• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "session_manager/include/screen_session_manager.h"
17 
18 #include <csignal>
19 #include <cstdint>
20 #include <ctime>
21 #include <iomanip>
22 #include <string_ex.h>
23 #include <unique_fd.h>
24 
25 #include <hitrace_meter.h>
26 #include <parameter.h>
27 #include <parameters.h>
28 #include <system_ability_definition.h>
29 #include <transaction/rs_interfaces.h>
30 #include <xcollie/watchdog.h>
31 #include <hisysevent.h>
32 
33 #include "dm_common.h"
34 #include "scene_board_judgement.h"
35 #include "session_permission.h"
36 #include "screen_scene_config.h"
37 #include "surface_capture_future.h"
38 #include "sys_cap_util.h"
39 #include "permission.h"
40 #include "window_manager_hilog.h"
41 #include "screen_rotation_property.h"
42 #include "screen_sensor_connector.h"
43 #include "screen_setting_helper.h"
44 #include "mock_session_manager_service.h"
45 
46 namespace OHOS::Rosen {
47 namespace {
48 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ScreenSessionManager" };
49 const std::string SCREEN_SESSION_MANAGER_THREAD = "OS_ScreenSessionManager";
50 const std::string SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD = "OS_ScreenSessionManager_ScreenPower";
51 const std::string SCREEN_CAPTURE_PERMISSION = "ohos.permission.CAPTURE_SCREEN";
52 const std::string BOOTEVENT_BOOT_COMPLETED = "bootevent.boot.completed";
53 const int SLEEP_US = 48 * 1000; // 48ms
54 const std::u16string DEFAULT_USTRING = u"error";
55 const std::string DEFAULT_STRING = "error";
56 const std::string ARG_DUMP_HELP = "-h";
57 const std::string ARG_DUMP_ALL = "-a";
58 const std::string ARG_DUMP_SCREEN = "-s";
59 const std::string ARG_FOLD_DISPLAY_FULL = "-f";
60 const std::string ARG_FOLD_DISPLAY_MAIN = "-m";
61 const std::string ARG_LOCK_FOLD_DISPLAY_STATUS = "-l";
62 const std::string ARG_UNLOCK_FOLD_DISPLAY_STATUS = "-u";
63 const ScreenId SCREEN_ID_FULL = 0;
64 const ScreenId SCREEN_ID_MAIN = 5;
65 } // namespace
66 
67 WM_IMPLEMENT_SINGLE_INSTANCE(ScreenSessionManager)
68 
69 const bool REGISTER_RESULT = !SceneBoardJudgement::IsSceneBoardEnabled() ? false :
70     SystemAbility::MakeAndRegisterAbility(&ScreenSessionManager::GetInstance());
71 
ScreenSessionManager()72 ScreenSessionManager::ScreenSessionManager()
73     : SystemAbility(DISPLAY_MANAGER_SERVICE_SA_ID, true), rsInterface_(RSInterfaces::GetInstance())
74 {
75     LoadScreenSceneXml();
76     taskScheduler_ = std::make_shared<TaskScheduler>(SCREEN_SESSION_MANAGER_THREAD);
77     screenPowerTaskScheduler_ = std::make_shared<TaskScheduler>(SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD);
78     screenCutoutController_ = new (std::nothrow) ScreenCutoutController();
79     sessionDisplayPowerController_ = new SessionDisplayPowerController(mutex_,
80         std::bind(&ScreenSessionManager::NotifyDisplayStateChange, this,
81             std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
82     bool foldScreenFlag = system::GetParameter("const.window.foldscreen.type", "") != "";
83     if (foldScreenFlag) {
84         foldScreenController_ = new (std::nothrow) FoldScreenController(displayInfoMutex_, screenPowerTaskScheduler_);
85         foldScreenController_->SetOnBootAnimation(true);
86         rsInterface_.SetScreenCorrection(SCREEN_ID_FULL, ScreenRotation::ROTATION_270);
87         SetFoldScreenPowerInit([&]() {
88             int64_t timeStamp = 50;
89             #ifdef TP_FEATURE_ENABLE
90             int32_t tpType = 12;
91             std::string fullTpChange = "0";
92             std::string mainTpChange = "1";
93             #endif
94             if (rsInterface_.GetActiveScreenId() == SCREEN_ID_FULL) {
95                 WLOGFI("ScreenSessionManager Fold Screen Power Full animation Init 1.");
96                 #ifdef TP_FEATURE_ENABLE
97                 rsInterface_.SetTpFeatureConfig(tpType, mainTpChange.c_str());
98                 #endif
99                 rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
100                 rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
101                 std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
102                 WLOGFI("ScreenSessionManager Fold Screen Power Full animation Init 2.");
103                 #ifdef TP_FEATURE_ENABLE
104                 rsInterface_.SetTpFeatureConfig(tpType, fullTpChange.c_str());
105                 #endif
106                 rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
107                 rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
108             } else if (rsInterface_.GetActiveScreenId() == SCREEN_ID_MAIN) {
109                 WLOGFI("ScreenSessionManager Fold Screen Power Main animation Init 3.");
110                 #ifdef TP_FEATURE_ENABLE
111                 rsInterface_.SetTpFeatureConfig(tpType, fullTpChange.c_str());
112                 #endif
113                 rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
114                 rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
115                 std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
116 
117                 WLOGFI("ScreenSessionManager Fold Screen Power Main animation Init 4.");
118                 #ifdef TP_FEATURE_ENABLE
119                 rsInterface_.SetTpFeatureConfig(tpType, mainTpChange.c_str());
120                 #endif
121                 rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
122                 rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
123             } else {
124                 WLOGFI("ScreenSessionManager Fold Screen Power Init, invalid active screen id");
125             }
126             foldScreenController_->SetOnBootAnimation(false);
127         });
128     }
129     WatchParameter(BOOTEVENT_BOOT_COMPLETED.c_str(), BootFinishedCallback, this);
130 }
131 
Init()132 void ScreenSessionManager::Init()
133 {
134     constexpr uint64_t interval = 5 * 1000; // 5 second
135     if (HiviewDFX::Watchdog::GetInstance().AddThread(
136         SCREEN_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
137         WLOGFW("Add thread %{public}s to watchdog failed.", SCREEN_SESSION_MANAGER_THREAD.c_str());
138     }
139 
140     if (HiviewDFX::Watchdog::GetInstance().AddThread(
141         SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD, screenPowerTaskScheduler_->GetEventHandler(), interval)) {
142         WLOGFW("Add thread %{public}s to watchdog failed.", SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD.c_str());
143     }
144 
145     RegisterScreenChangeListener();
146     RegisterRefreshRateModeChangeListener();
147 
148     bool isPcDevice = system::GetParameter("const.product.devicetype", "unknown") == "2in1";
149     if (isPcDevice) {
150         WLOGFI("Current device type not support SetSensorSubscriptionEnabled.");
151     } else {
152         SetSensorSubscriptionEnabled();
153     }
154 }
155 
OnStart()156 void ScreenSessionManager::OnStart()
157 {
158     WLOGFI("begin");
159     Init();
160     sptr<ScreenSessionManager> dms(this);
161     dms->IncStrongRef(nullptr);
162     if (!Publish(dms)) {
163         WLOGFE("Publish failed");
164         return;
165     }
166     WLOGFI("end");
167 }
168 
RegisterDisplayManagerAgent(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)169 DMError ScreenSessionManager::RegisterDisplayManagerAgent(
170     const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
171 {
172     if (type == DisplayManagerAgentType::SCREEN_EVENT_LISTENER && !SessionPermission::IsSystemCalling()
173         && !SessionPermission::IsStartByHdcd()) {
174         WLOGFE("register display manager agent permission denied!");
175         return DMError::DM_ERROR_NOT_SYSTEM_APP;
176     }
177     if (type < DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER
178         || type > DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER) {
179         WLOGFE("SCB:DisplayManagerAgentType: %{public}u", static_cast<uint32_t>(type));
180         return DMError::DM_ERROR_INVALID_PARAM;
181     }
182     if ((displayManagerAgent == nullptr) || (displayManagerAgent->AsObject() == nullptr)) {
183         WLOGFE("displayManagerAgent invalid");
184         return DMError::DM_ERROR_NULLPTR;
185     }
186 
187     return dmAgentContainer_.RegisterAgent(displayManagerAgent, type) ? DMError::DM_OK :DMError::DM_ERROR_NULLPTR;
188 }
189 
UnregisterDisplayManagerAgent(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)190 DMError ScreenSessionManager::UnregisterDisplayManagerAgent(
191     const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
192 {
193     if (type == DisplayManagerAgentType::SCREEN_EVENT_LISTENER && !SessionPermission::IsSystemCalling()
194         && !SessionPermission::IsStartByHdcd()) {
195         WLOGFE("unregister display manager agent permission denied!");
196         return DMError::DM_ERROR_NOT_SYSTEM_APP;
197     }
198     if ((displayManagerAgent == nullptr) || (displayManagerAgent->AsObject() == nullptr)) {
199         WLOGFE("displayManagerAgent invalid");
200         return DMError::DM_ERROR_NULLPTR;
201     }
202 
203     return dmAgentContainer_.UnregisterAgent(displayManagerAgent, type) ? DMError::DM_OK :DMError::DM_ERROR_NULLPTR;
204 }
205 
LoadScreenSceneXml()206 void ScreenSessionManager::LoadScreenSceneXml()
207 {
208     if (ScreenSceneConfig::LoadConfigXml()) {
209         ScreenSceneConfig::DumpConfig();
210         ConfigureScreenScene();
211     }
212 }
213 
ConfigureScreenScene()214 void ScreenSessionManager::ConfigureScreenScene()
215 {
216     auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
217     auto enableConfig = ScreenSceneConfig::GetEnableConfig();
218     auto stringConfig = ScreenSceneConfig::GetStringConfig();
219     if (numbersConfig.count("dpi") != 0) {
220         uint32_t densityDpi = static_cast<uint32_t>(numbersConfig["dpi"][0]);
221         WLOGFD("densityDpi = %u", densityDpi);
222         if (densityDpi >= DOT_PER_INCH_MINIMUM_VALUE && densityDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
223             isDensityDpiLoad_ = true;
224             defaultDpi = densityDpi;
225             cachedSettingDpi_ = defaultDpi;
226             densityDpi_ = static_cast<float>(densityDpi) / BASELINE_DENSITY;
227         }
228     }
229     if (numbersConfig.count("defaultDeviceRotationOffset") != 0) {
230         uint32_t defaultDeviceRotationOffset = static_cast<uint32_t>(numbersConfig["defaultDeviceRotationOffset"][0]);
231         WLOGFD("defaultDeviceRotationOffset = %u", defaultDeviceRotationOffset);
232     }
233     if (enableConfig.count("isWaterfallDisplay") != 0) {
234         bool isWaterfallDisplay = static_cast<bool>(enableConfig["isWaterfallDisplay"]);
235         WLOGFD("isWaterfallDisplay = %d", isWaterfallDisplay);
236     }
237     if (numbersConfig.count("curvedScreenBoundary") != 0) {
238         std::vector<int> vtBoundary = static_cast<std::vector<int>>(numbersConfig["curvedScreenBoundary"]);
239         WLOGFD("vtBoundary.size=%{public}u", static_cast<uint32_t>(vtBoundary.size()));
240     }
241     if (stringConfig.count("defaultDisplayCutoutPath") != 0) {
242         std::string defaultDisplayCutoutPath = static_cast<std::string>(stringConfig["defaultDisplayCutoutPath"]);
243         WLOGFD("defaultDisplayCutoutPath = %{public}s.", defaultDisplayCutoutPath.c_str());
244         ScreenSceneConfig::SetCutoutSvgPath(defaultDisplayCutoutPath);
245     }
246     ConfigureWaterfallDisplayCompressionParams();
247 
248     if (numbersConfig.count("buildInDefaultOrientation") != 0) {
249         Orientation orientation = static_cast<Orientation>(numbersConfig["buildInDefaultOrientation"][0]);
250         WLOGFD("orientation = %d", orientation);
251     }
252 }
253 
ConfigureWaterfallDisplayCompressionParams()254 void ScreenSessionManager::ConfigureWaterfallDisplayCompressionParams()
255 {
256     auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
257     auto enableConfig = ScreenSceneConfig::GetEnableConfig();
258     if (enableConfig.count("isWaterfallAreaCompressionEnableWhenHorizontal") != 0) {
259         bool enable = static_cast<bool>(enableConfig["isWaterfallAreaCompressionEnableWhenHorizontal"]);
260         WLOGD("isWaterfallAreaCompressionEnableWhenHorizontal=%d.", enable);
261     }
262     ScreenSceneConfig::SetCurvedCompressionAreaInLandscape();
263 }
264 
RegisterScreenChangeListener()265 void ScreenSessionManager::RegisterScreenChangeListener()
266 {
267     WLOGFD("Register screen change listener.");
268     auto res = rsInterface_.SetScreenChangeCallback(
269         [this](ScreenId screenId, ScreenEvent screenEvent) { OnScreenChange(screenId, screenEvent); });
270     if (res != StatusCode::SUCCESS) {
271         auto task = [this]() { RegisterScreenChangeListener(); };
272         taskScheduler_->PostAsyncTask(task, "RegisterScreenChangeListener", 50); // Retry after 50 ms.
273     }
274 }
275 
RegisterRefreshRateModeChangeListener()276 void ScreenSessionManager::RegisterRefreshRateModeChangeListener()
277 {
278     WLOGFI("Register refreshrate mode change listener.");
279     auto res = rsInterface_.RegisterHgmRefreshRateModeChangeCallback(
280         [this](int32_t refreshRateMode) { OnHgmRefreshRateModeChange(refreshRateMode); });
281     if (res != StatusCode::SUCCESS) {
282         WLOGFE("Register refreshrate mode change listener failed, retry after 50 ms.");
283         auto task = [this]() { RegisterRefreshRateModeChangeListener(); };
284         taskScheduler_->PostAsyncTask(task, "RegisterRefreshRateModeChangeListener", 50); // Retry after 50 ms.
285     }
286 }
287 
OnVirtualScreenChange(ScreenId screenId,ScreenEvent screenEvent)288 void ScreenSessionManager::OnVirtualScreenChange(ScreenId screenId, ScreenEvent screenEvent)
289 {
290     WLOGFI("Notify scb virtual screen change, ScreenId: %{public}" PRIu64 ", ScreenEvent: %{public}d", screenId,
291         static_cast<int>(screenEvent));
292     auto screenSession = GetScreenSession(screenId);
293     if (!screenSession) {
294         WLOGFE("screenSession is nullptr");
295         return;
296     }
297     if (screenEvent == ScreenEvent::CONNECTED) {
298         if (clientProxy_) {
299             clientProxy_->OnScreenConnectionChanged(screenId, ScreenEvent::CONNECTED,
300                 screenSession->GetRSScreenId(), screenSession->GetName());
301         }
302         return;
303     }
304     if (screenEvent == ScreenEvent::DISCONNECTED) {
305         if (clientProxy_) {
306             clientProxy_->OnScreenConnectionChanged(screenId, ScreenEvent::DISCONNECTED,
307                 screenSession->GetRSScreenId(), screenSession->GetName());
308         }
309     }
310 }
311 
FreeDisplayMirrorNodeInner(const sptr<ScreenSession> mirrorSession)312 void ScreenSessionManager::FreeDisplayMirrorNodeInner(const sptr<ScreenSession> mirrorSession)
313 {
314     bool phyMirrorEnable = system::GetParameter("const.product.devicetype", "unknown") == "phone";
315     if (mirrorSession == nullptr || !phyMirrorEnable) {
316         return;
317     }
318     std::shared_ptr<RSDisplayNode> displayNode = mirrorSession->GetDisplayNode();
319     if (displayNode == nullptr) {
320         return;
321     }
322     displayNode->RemoveFromTree();
323     auto transactionProxy = RSTransactionProxy::GetInstance();
324     if (transactionProxy != nullptr) {
325         WLOGFI("FreeDisplayMirrorNodeInner free displayNode");
326         transactionProxy->FlushImplicitTransaction();
327     }
328 }
329 
OnScreenChange(ScreenId screenId,ScreenEvent screenEvent)330 void ScreenSessionManager::OnScreenChange(ScreenId screenId, ScreenEvent screenEvent)
331 {
332     WLOGFI("screenId: %{public}" PRIu64 " screenEvent: %{public}d", screenId, static_cast<int>(screenEvent));
333     bool phyMirrorEnable = system::GetParameter("const.product.devicetype", "unknown") == "phone";
334     auto screenSession = GetOrCreateScreenSession(screenId);
335     if (!screenSession) {
336         WLOGFE("screenSession is nullptr");
337         return;
338     }
339 
340     if (foldScreenController_ != nullptr) {
341         screenSession->SetFoldScreen(true);
342     }
343 
344     if (screenEvent == ScreenEvent::CONNECTED) {
345         if (foldScreenController_ != nullptr) {
346             if (screenId == 0 && clientProxy_) {
347                 clientProxy_->OnScreenConnectionChanged(screenId, ScreenEvent::CONNECTED,
348                     screenSession->GetRSScreenId(), screenSession->GetName());
349             }
350             return;
351         }
352 
353         if (clientProxy_ && !phyMirrorEnable) {
354             clientProxy_->OnScreenConnectionChanged(screenId, ScreenEvent::CONNECTED,
355                 screenSession->GetRSScreenId(), screenSession->GetName());
356         }
357         return;
358     }
359     if (screenEvent == ScreenEvent::DISCONNECTED) {
360         if (phyMirrorEnable) {
361             FreeDisplayMirrorNodeInner(screenSession);
362         }
363         if (clientProxy_) {
364             clientProxy_->OnScreenConnectionChanged(screenId, ScreenEvent::DISCONNECTED,
365                 screenSession->GetRSScreenId(), screenSession->GetName());
366         }
367         {
368             std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
369             screenSessionMap_.erase(screenId);
370         }
371         {
372             std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
373             phyScreenPropMap_.erase(screenId);
374         }
375     }
376 }
377 
OnHgmRefreshRateModeChange(int32_t refreshRateMode)378 void ScreenSessionManager::OnHgmRefreshRateModeChange(int32_t refreshRateMode)
379 {
380     GetDefaultScreenId();
381     WLOGFI("Set refreshRateMode: %{public}d, defaultscreenid: %{public}" PRIu64"", refreshRateMode, defaultScreenId_);
382     uint32_t refreshRate;
383     RefreshRateMode mode = static_cast<RefreshRateMode>(refreshRateMode);
384     switch (mode) {
385         case RefreshRateMode::NORMAL :
386             refreshRate = static_cast<uint32_t>(RefreshRate::NORMAL);
387             break;
388         case RefreshRateMode::MIDDLE :
389             refreshRate = static_cast<uint32_t>(RefreshRate::MIDDLE);
390             break;
391         case RefreshRateMode::HIGH :
392             refreshRate = static_cast<uint32_t>(RefreshRate::HIGH);
393             break;
394         default:
395             refreshRate = static_cast<uint32_t>(RefreshRate::HIGH);
396     }
397     sptr<ScreenSession> screenSession = GetScreenSession(defaultScreenId_);
398     if (screenSession) {
399         screenSession->UpdateRefreshRate(refreshRate);
400     } else {
401         WLOGFE("Get default screen session failed.");
402     }
403     return ;
404 }
405 
GetScreenSession(ScreenId screenId) const406 sptr<ScreenSession> ScreenSessionManager::GetScreenSession(ScreenId screenId) const
407 {
408     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
409     auto iter = screenSessionMap_.find(screenId);
410     if (iter == screenSessionMap_.end()) {
411         WLOGFD("Error found screen session with id: %{public}" PRIu64"", screenId);
412         return nullptr;
413     }
414     return iter->second;
415 }
416 
GetDefaultScreenSession()417 sptr<ScreenSession> ScreenSessionManager::GetDefaultScreenSession()
418 {
419     GetDefaultScreenId();
420     return GetScreenSession(defaultScreenId_);
421 }
422 
GetDefaultDisplayInfo()423 sptr<DisplayInfo> ScreenSessionManager::GetDefaultDisplayInfo()
424 {
425     std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
426     GetDefaultScreenId();
427     sptr<ScreenSession> screenSession = GetScreenSession(defaultScreenId_);
428     if (screenSession) {
429         return screenSession->ConvertToDisplayInfo();
430     } else {
431         WLOGFE("Get default screen session failed.");
432         return nullptr;
433     }
434 }
435 
GetDisplayInfoById(DisplayId displayId)436 sptr<DisplayInfo> ScreenSessionManager::GetDisplayInfoById(DisplayId displayId)
437 {
438     WLOGFD("GetDisplayInfoById enter, displayId: %{public}" PRIu64" ", displayId);
439     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
440     for (auto sessionIt : screenSessionMap_) {
441         auto screenSession = sessionIt.second;
442         if (screenSession == nullptr) {
443             WLOGFE("GetDisplayInfoById screenSession is nullptr, ScreenId: %{public}" PRIu64 "", sessionIt.first);
444             continue;
445         }
446         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
447         if (displayInfo == nullptr) {
448             WLOGFE("ConvertToDisplayInfo error, displayInfo is nullptr.");
449             continue;
450         }
451         if (displayId == displayInfo->GetDisplayId()) {
452             WLOGFD("GetDisplayInfoById success");
453             return displayInfo;
454         }
455     }
456     WLOGFE("SCB: ScreenSessionManager::GetDisplayInfoById failed.");
457     return nullptr;
458 }
459 
GetDisplayInfoByScreen(ScreenId screenId)460 sptr<DisplayInfo> ScreenSessionManager::GetDisplayInfoByScreen(ScreenId screenId)
461 {
462     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
463     for (auto sessionIt : screenSessionMap_) {
464         auto screenSession = sessionIt.second;
465         if (screenSession == nullptr) {
466             WLOGFE("GetDisplayInfoByScreen screenSession is nullptr, ScreenId:%{public}" PRIu64"", sessionIt.first);
467             continue;
468         }
469         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
470         if (displayInfo == nullptr) {
471             WLOGFE("GetDisplayInfoByScreen error, displayInfo is nullptr.");
472             continue;
473         }
474         if (screenId == displayInfo->GetScreenId()) {
475             return displayInfo;
476         }
477     }
478     WLOGFE("SCB: ScreenSessionManager::GetDisplayInfoByScreen failed.");
479     return nullptr;
480 }
481 
GetAllDisplayIds()482 std::vector<DisplayId> ScreenSessionManager::GetAllDisplayIds()
483 {
484     WLOGFI("GetAllDisplayIds enter");
485     std::vector<DisplayId> res;
486     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
487     for (auto sessionIt : screenSessionMap_) {
488         auto screenSession = sessionIt.second;
489         if (screenSession == nullptr) {
490             WLOGFE("GetAllDisplayIds screenSession is nullptr, ScreenId:%{public}" PRIu64"", sessionIt.first);
491             continue;
492         }
493         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
494         if (displayInfo == nullptr) {
495             WLOGFE("GetAllDisplayIds error, displayInfo is nullptr.");
496             continue;
497         }
498         DisplayId displayId = displayInfo->GetDisplayId();
499         res.push_back(displayId);
500     }
501     return res;
502 }
503 
GetScreenInfoById(ScreenId screenId)504 sptr<ScreenInfo> ScreenSessionManager::GetScreenInfoById(ScreenId screenId)
505 {
506     if (!SessionPermission::IsSystemCalling()) {
507         WLOGFE("SCB: ScreenSessionManager::GetScreenInfoById permission denied!");
508         return nullptr;
509     }
510     auto screenSession = GetScreenSession(screenId);
511     if (screenSession == nullptr) {
512         WLOGE("SCB: ScreenSessionManager::GetScreenInfoById cannot find screenInfo: %{public}" PRIu64"", screenId);
513         return nullptr;
514     }
515     return screenSession->ConvertToScreenInfo();
516 }
517 
SetScreenActiveMode(ScreenId screenId,uint32_t modeId)518 DMError ScreenSessionManager::SetScreenActiveMode(ScreenId screenId, uint32_t modeId)
519 {
520     WLOGI("SetScreenActiveMode: ScreenId: %{public}" PRIu64", modeId: %{public}u", screenId, modeId);
521     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
522         WLOGFE("set screen active permission denied!");
523         return DMError::DM_ERROR_NOT_SYSTEM_APP;
524     }
525     if (screenId == SCREEN_ID_INVALID) {
526         WLOGFE("SetScreenActiveMode: invalid screenId");
527         return DMError::DM_ERROR_NULLPTR;
528     }
529     {
530         sptr<ScreenSession> screenSession = GetScreenSession(screenId);
531         if (screenSession == nullptr) {
532             WLOGFE("SetScreenActiveMode: Get ScreenSession failed");
533             return DMError::DM_ERROR_NULLPTR;
534         }
535         ScreenId rsScreenId = SCREEN_ID_INVALID;
536         if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
537             WLOGFE("SetScreenActiveMode: No corresponding rsId");
538             return DMError::DM_ERROR_NULLPTR;
539         }
540         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetScreenActiveMode(%" PRIu64", %u)", screenId, modeId);
541         rsInterface_.SetScreenActiveMode(rsScreenId, modeId);
542         screenSession->activeIdx_ = static_cast<int32_t>(modeId);
543         screenSession->UpdatePropertyByActiveMode();
544         screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::CHANGE_MODE);
545         NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
546         NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
547     }
548     return DMError::DM_OK;
549 }
550 
ConvertScreenIdToRsScreenId(ScreenId screenId,ScreenId & rsScreenId)551 bool ScreenSessionManager::ConvertScreenIdToRsScreenId(ScreenId screenId, ScreenId& rsScreenId)
552 {
553     return screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
554 }
555 
NotifyScreenChanged(sptr<ScreenInfo> screenInfo,ScreenChangeEvent event)556 void ScreenSessionManager::NotifyScreenChanged(sptr<ScreenInfo> screenInfo, ScreenChangeEvent event)
557 {
558     if (screenInfo == nullptr) {
559         WLOGFE("NotifyScreenChanged error, screenInfo is nullptr.");
560         return;
561     }
562     auto task = [=] {
563         WLOGFI("NotifyScreenChanged,  screenId:%{public}" PRIu64"", screenInfo->GetScreenId());
564         auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
565         if (agents.empty()) {
566             return;
567         }
568         for (auto& agent : agents) {
569             agent->OnScreenChange(screenInfo, event);
570         }
571     };
572     taskScheduler_->PostAsyncTask(task, "NotifyScreenChanged:SID:" + std::to_string(screenInfo->GetScreenId()));
573 }
574 
SetVirtualPixelRatio(ScreenId screenId,float virtualPixelRatio)575 DMError ScreenSessionManager::SetVirtualPixelRatio(ScreenId screenId, float virtualPixelRatio)
576 {
577     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
578         WLOGFE("set virtual pixel permission denied!");
579         return DMError::DM_ERROR_NOT_SYSTEM_APP;
580     }
581 
582     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
583     if (!screenSession) {
584         WLOGFE("screen session is nullptr");
585         return DMError::DM_ERROR_UNKNOWN;
586     }
587     if (screenSession->isScreenGroup_) {
588         WLOGE("cannot set virtual pixel ratio to the combination. screen: %{public}" PRIu64"", screenId);
589         return DMError::DM_ERROR_NULLPTR;
590     }
591     if (fabs(screenSession->GetScreenProperty().GetVirtualPixelRatio() - virtualPixelRatio) < 1e-6) {
592         WLOGE("The density is equivalent to the original value, no update operation is required, aborted.");
593         return DMError::DM_OK;
594     }
595     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetVirtualPixelRatio(%" PRIu64", %f)", screenId,
596         virtualPixelRatio);
597     screenSession->SetVirtualPixelRatio(virtualPixelRatio);
598     std::map<DisplayId, sptr<DisplayInfo>> emptyMap;
599     NotifyDisplayStateChange(GetDefaultScreenId(), screenSession->ConvertToDisplayInfo(),
600         emptyMap, DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE);
601     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::VIRTUAL_PIXEL_RATIO_CHANGED);
602     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
603         DisplayChangeEvent::DISPLAY_VIRTUAL_PIXEL_RATIO_CHANGED);
604     return DMError::DM_OK;
605 }
606 
SetResolution(ScreenId screenId,uint32_t width,uint32_t height,float virtualPixelRatio)607 DMError ScreenSessionManager::SetResolution(ScreenId screenId, uint32_t width, uint32_t height, float virtualPixelRatio)
608 {
609     WLOGI("SetResolution ScreenId: %{public}" PRIu64 ", w: %{public}u, h: %{public}u, virtualPixelRatio: %{public}f",
610         screenId, width, height, virtualPixelRatio);
611     if (screenId == SCREEN_ID_INVALID) {
612         WLOGFE("SetResolution: invalid screenId");
613         return DMError::DM_ERROR_NULLPTR;
614     }
615     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
616     if (screenSession == nullptr) {
617         WLOGFE("SetResolution: Get ScreenSession failed");
618         return DMError::DM_ERROR_NULLPTR;
619     }
620     sptr<SupportedScreenModes> screenSessionModes = screenSession->GetActiveScreenMode();
621     if (screenSessionModes == nullptr) {
622         return DMError::DM_ERROR_NULLPTR;
623     }
624     if (width <= 0 || width > screenSessionModes->width_ ||
625         height <= 0 || height > screenSessionModes->height_ ||
626         virtualPixelRatio < (static_cast<float>(DOT_PER_INCH_MINIMUM_VALUE) / DOT_PER_INCH) ||
627         virtualPixelRatio > (static_cast<float>(DOT_PER_INCH_MAXIMUM_VALUE) / DOT_PER_INCH)) {
628         WLOGFE("SetResolution invalid param! w:%{public}u h:%{public}u min:%{public}f max:%{public}f",
629             screenSessionModes->width_,
630             screenSessionModes->height_,
631             static_cast<float>(DOT_PER_INCH_MINIMUM_VALUE) / DOT_PER_INCH,
632             static_cast<float>(DOT_PER_INCH_MAXIMUM_VALUE) / DOT_PER_INCH);
633         return DMError::DM_ERROR_INVALID_PARAM;
634     }
635 
636     screenSession->SetDensityInCurResolution(virtualPixelRatio);
637     DMError ret = SetVirtualPixelRatio(screenId, virtualPixelRatio);
638     if (ret != DMError::DM_OK) {
639         WLOGFE("Failed to setVirtualPixelRatio when settingResolution");
640         screenSession->SetDensityInCurResolution(screenSession->GetScreenProperty().GetVirtualPixelRatio());
641         return ret;
642     }
643     {
644         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetResolution(%" PRIu64", %u, %u, %f)",
645             screenId, width, height, virtualPixelRatio);
646         screenSession->UpdatePropertyByResolution(width, height);
647         screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::CHANGE_MODE);
648         NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
649         NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
650     }
651     return DMError::DM_OK;
652 }
653 
GetDensityInCurResolution(ScreenId screenId,float & virtualPixelRatio)654 DMError ScreenSessionManager::GetDensityInCurResolution(ScreenId screenId, float& virtualPixelRatio)
655 {
656     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
657     if (screenSession == nullptr) {
658         WLOGFE("GetDensityInCurResolution: Get ScreenSession failed");
659         return DMError::DM_ERROR_NULLPTR;
660     }
661 
662     virtualPixelRatio = screenSession->GetScreenProperty().GetDensityInCurResolution();
663     return DMError::DM_OK;
664 }
665 
GetScreenColorGamut(ScreenId screenId,ScreenColorGamut & colorGamut)666 DMError ScreenSessionManager::GetScreenColorGamut(ScreenId screenId, ScreenColorGamut& colorGamut)
667 {
668     WLOGFI("GetScreenColorGamut::ScreenId: %{public}" PRIu64 "", screenId);
669     if (screenId == SCREEN_ID_INVALID) {
670         WLOGFE("screenId invalid");
671         return DMError::DM_ERROR_INVALID_PARAM;
672     }
673     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
674     if (screenSession == nullptr) {
675         return DMError::DM_ERROR_INVALID_PARAM;
676     }
677     return screenSession->GetScreenColorGamut(colorGamut);
678 }
679 
SetScreenColorGamut(ScreenId screenId,int32_t colorGamutIdx)680 DMError ScreenSessionManager::SetScreenColorGamut(ScreenId screenId, int32_t colorGamutIdx)
681 {
682     WLOGFI("SetScreenColorGamut::ScreenId: %{public}" PRIu64 ", colorGamutIdx %{public}d", screenId, colorGamutIdx);
683     if (screenId == SCREEN_ID_INVALID) {
684         WLOGFE("screenId invalid");
685         return DMError::DM_ERROR_INVALID_PARAM;
686     }
687     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
688     if (screenSession == nullptr) {
689         return DMError::DM_ERROR_INVALID_PARAM;
690     }
691     return screenSession->SetScreenColorGamut(colorGamutIdx);
692 }
693 
GetScreenGamutMap(ScreenId screenId,ScreenGamutMap & gamutMap)694 DMError ScreenSessionManager::GetScreenGamutMap(ScreenId screenId, ScreenGamutMap& gamutMap)
695 {
696     WLOGFI("GetScreenGamutMap::ScreenId: %{public}" PRIu64 "", screenId);
697     if (screenId == SCREEN_ID_INVALID) {
698         WLOGFE("screenId invalid");
699         return DMError::DM_ERROR_INVALID_PARAM;
700     }
701     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
702     if (screenSession == nullptr) {
703         return DMError::DM_ERROR_INVALID_PARAM;
704     }
705     return screenSession->GetScreenGamutMap(gamutMap);
706 }
707 
SetScreenGamutMap(ScreenId screenId,ScreenGamutMap gamutMap)708 DMError ScreenSessionManager::SetScreenGamutMap(ScreenId screenId, ScreenGamutMap gamutMap)
709 {
710     WLOGFI("SetScreenGamutMap::ScreenId: %{public}" PRIu64 ", ScreenGamutMap %{public}u",
711         screenId, static_cast<uint32_t>(gamutMap));
712     if (screenId == SCREEN_ID_INVALID) {
713         WLOGFE("screenId invalid");
714         return DMError::DM_ERROR_INVALID_PARAM;
715     }
716     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
717     if (screenSession == nullptr) {
718         return DMError::DM_ERROR_INVALID_PARAM;
719     }
720     return screenSession->SetScreenGamutMap(gamutMap);
721 }
722 
SetScreenColorTransform(ScreenId screenId)723 DMError ScreenSessionManager::SetScreenColorTransform(ScreenId screenId)
724 {
725     WLOGFI("SetScreenColorTransform::ScreenId: %{public}" PRIu64 "", screenId);
726     if (screenId == SCREEN_ID_INVALID) {
727         WLOGFE("screenId invalid");
728         return DMError::DM_ERROR_INVALID_PARAM;
729     }
730     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
731     if (screenSession == nullptr) {
732         return DMError::DM_ERROR_INVALID_PARAM;
733     }
734     return screenSession->SetScreenColorTransform();
735 }
736 
GetScreenSessionInner(ScreenId screenId,ScreenProperty property)737 sptr<ScreenSession> ScreenSessionManager::GetScreenSessionInner(ScreenId screenId, ScreenProperty property)
738 {
739     bool phyMirrorEnable = system::GetParameter("const.product.devicetype", "unknown") == "phone";
740     sptr<ScreenSession> session = nullptr;
741     ScreenId defScreenId = GetDefaultScreenId();
742     if (phyMirrorEnable && screenId != defScreenId) {
743         NodeId nodeId = 0;
744         auto sIt = screenSessionMap_.find(defScreenId);
745         if (sIt != screenSessionMap_.end() && sIt->second != nullptr && sIt->second->GetDisplayNode() != nullptr) {
746             nodeId = sIt->second->GetDisplayNode()->GetId();
747         }
748         WLOGFI("GetScreenSessionInner: nodeId:%{public}" PRIu64 "", nodeId);
749         session = new ScreenSession(screenId, property, nodeId, defScreenId);
750     } else {
751         session = new ScreenSession(screenId, property, defScreenId);
752     }
753     return session;
754 }
755 
GetOrCreateScreenSession(ScreenId screenId)756 sptr<ScreenSession> ScreenSessionManager::GetOrCreateScreenSession(ScreenId screenId)
757 {
758     WLOGFI("SCB: ScreenSessionManager::GetOrCreateScreenSession ENTER");
759     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
760     auto sessionIt = screenSessionMap_.find(screenId);
761     if (sessionIt != screenSessionMap_.end()) {
762         return sessionIt->second;
763     }
764 
765     ScreenId rsId = screenId;
766     screenIdManager_.UpdateScreenId(rsId, screenId);
767 
768     auto screenMode = rsInterface_.GetScreenActiveMode(screenId);
769     auto screenBounds = RRect({ 0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight() }, 0.0f, 0.0f);
770     auto screenRefreshRate = screenMode.GetScreenRefreshRate();
771     auto screenCapability = rsInterface_.GetScreenCapability(screenId);
772     ScreenProperty property;
773     property.SetRotation(0.0f);
774     property.SetPhyWidth(screenCapability.GetPhyWidth());
775     property.SetPhyHeight(screenCapability.GetPhyHeight());
776     property.SetPhyBounds(screenBounds);
777     property.SetBounds(screenBounds);
778     property.SetAvailableArea({0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight()});
779     if (isDensityDpiLoad_) {
780         property.SetVirtualPixelRatio(densityDpi_);
781         property.SetDefaultDensity(densityDpi_);
782         property.SetDensityInCurResolution(densityDpi_);
783     } else {
784         property.UpdateVirtualPixelRatio(screenBounds);
785     }
786     property.SetRefreshRate(screenRefreshRate);
787 
788     if (foldScreenController_ != nullptr && screenId == 0) {
789         screenBounds = RRect({ 0, 0, screenMode.GetScreenHeight(), screenMode.GetScreenWidth() }, 0.0f, 0.0f);
790         property.SetBounds(screenBounds);
791     }
792     property.CalcDefaultDisplayOrientation();
793 
794     {
795         std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
796         phyScreenPropMap_[screenId] = property;
797     }
798 
799     if (foldScreenController_ != nullptr) {
800         // sensor may earlier than screen connect, when physical screen property changed, update
801         foldScreenController_->UpdateForPhyScreenPropertyChange();
802         /* folder screen outer screenId is 5 */
803         if (screenId == 5) {
804             return nullptr;
805         }
806     }
807 
808     sptr<ScreenSession> session = GetScreenSessionInner(screenId, property);
809     session->RegisterScreenChangeListener(this);
810     InitAbstractScreenModesInfo(session);
811     session->groupSmsId_ = 1;
812     screenSessionMap_[screenId] = session;
813     SetHdrFormats(screenId, session);
814     SetColorSpaces(screenId, session);
815     return session;
816 }
817 
SetHdrFormats(ScreenId screenId,sptr<ScreenSession> & session)818 void ScreenSessionManager::SetHdrFormats(ScreenId screenId, sptr<ScreenSession>& session)
819 {
820     WLOGFI("SCB: ScreenSessionManager::SetHdrFormats %{public}" PRIu64, screenId);
821     std::vector<ScreenHDRFormat> rsHdrFormat;
822     auto status = rsInterface_.GetScreenSupportedHDRFormats(screenId, rsHdrFormat);
823     if (static_cast<StatusCode>(status) != StatusCode::SUCCESS) {
824         WLOGFE("get hdr format failed! status code: %{public}d", status);
825     } else {
826         std::vector<uint32_t> hdrFormat(rsHdrFormat.size());
827         std::transform(rsHdrFormat.begin(), rsHdrFormat.end(), hdrFormat.begin(), [](int val) {
828             return static_cast<uint32_t>(val);
829         });
830         session->SetHdrFormats(std::move(hdrFormat));
831     }
832 }
833 
SetColorSpaces(ScreenId screenId,sptr<ScreenSession> & session)834 void ScreenSessionManager::SetColorSpaces(ScreenId screenId, sptr<ScreenSession>& session)
835 {
836     WLOGFI("SCB: ScreenSessionManager::SetColorSpaces %{public}" PRIu64, screenId);
837     std::vector<GraphicCM_ColorSpaceType> rsColorSpace;
838     auto status = rsInterface_.GetScreenSupportedColorSpaces(screenId, rsColorSpace);
839     if (static_cast<StatusCode>(status) != StatusCode::SUCCESS) {
840         WLOGFE("get color space failed! status code: %{public}d", status);
841     } else {
842         std::vector<uint32_t> colorSpace(rsColorSpace.size());
843         std::transform(rsColorSpace.begin(), rsColorSpace.end(), colorSpace.begin(), [](int val) {
844             return static_cast<uint32_t>(val);
845         });
846         session->SetColorSpaces(std::move(colorSpace));
847     }
848 }
849 
GetDefaultScreenId()850 ScreenId ScreenSessionManager::GetDefaultScreenId()
851 {
852     if (defaultScreenId_ == INVALID_SCREEN_ID) {
853         defaultScreenId_ = rsInterface_.GetDefaultScreenId();
854     }
855     return defaultScreenId_;
856 }
857 
WakeUpBegin(PowerStateChangeReason reason)858 bool ScreenSessionManager::WakeUpBegin(PowerStateChangeReason reason)
859 {
860     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:WakeUpBegin(%u)", reason);
861     WLOGFI("ScreenSessionManager::WakeUpBegin remove suspend begin task");
862     blockScreenPowerChange_ = false;
863     taskScheduler_->RemoveTask("suspendBeginTask");
864     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
865         isMultiScreenCollaboration_ = true;
866         return true;
867     }
868     return NotifyDisplayPowerEvent(DisplayPowerEvent::WAKE_UP, EventStatus::BEGIN, reason);
869 }
870 
WakeUpEnd()871 bool ScreenSessionManager::WakeUpEnd()
872 {
873     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:WakeUpEnd");
874     if (isMultiScreenCollaboration_) {
875         isMultiScreenCollaboration_ = false;
876         return true;
877     }
878     return NotifyDisplayPowerEvent(DisplayPowerEvent::WAKE_UP, EventStatus::END,
879         PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
880 }
881 
SuspendBegin(PowerStateChangeReason reason)882 bool ScreenSessionManager::SuspendBegin(PowerStateChangeReason reason)
883 {
884     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SuspendBegin(%u)", reason);
885     WLOGFI("ScreenSessionManager::SuspendBegin block screen power change is true");
886     blockScreenPowerChange_ = true;
887     auto suspendBeginTask = [this]() {
888         WLOGFI("ScreenSessionManager::SuspendBegin delay task start");
889         blockScreenPowerChange_ = false;
890         SetScreenPower(ScreenPowerStatus::POWER_STATUS_OFF, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
891     };
892     taskScheduler_->PostTask(suspendBeginTask, "suspendBeginTask", 1500);
893     sessionDisplayPowerController_->SuspendBegin(reason);
894     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
895         isMultiScreenCollaboration_ = true;
896         return true;
897     }
898     return NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::BEGIN, reason);
899 }
900 
SuspendEnd()901 bool ScreenSessionManager::SuspendEnd()
902 {
903     WLOGFI("ScreenSessionManager::SuspendEnd enter");
904     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SuspendEnd");
905     blockScreenPowerChange_ = false;
906     if (isMultiScreenCollaboration_) {
907         isMultiScreenCollaboration_ = false;
908         return true;
909     }
910     return NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::END,
911         PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
912 }
913 
SetDisplayState(DisplayState state)914 bool ScreenSessionManager::SetDisplayState(DisplayState state)
915 {
916     WLOGFI("ScreenSessionManager::SetDisplayState enter");
917     return sessionDisplayPowerController_->SetDisplayState(state);
918 }
919 
NotifyDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)920 void ScreenSessionManager::NotifyDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
921     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
922 {
923     if (clientProxy_) {
924         clientProxy_->OnDisplayStateChanged(defaultDisplayId, displayInfo, displayInfoMap, type);
925     }
926 }
927 
NotifyScreenshot(DisplayId displayId)928 void ScreenSessionManager::NotifyScreenshot(DisplayId displayId)
929 {
930     if (clientProxy_) {
931         clientProxy_->OnScreenshot(displayId);
932     }
933 }
934 
SetSpecifiedScreenPower(ScreenId screenId,ScreenPowerState state,PowerStateChangeReason reason)935 bool ScreenSessionManager::SetSpecifiedScreenPower(ScreenId screenId, ScreenPowerState state, PowerStateChangeReason reason)
936 {
937     WLOGFI("SetSpecifiedScreenPower: screen id:%{public}" PRIu64 ", state:%{public}u", screenId, state);
938 
939     ScreenPowerStatus status;
940     switch (state) {
941         case ScreenPowerState::POWER_ON: {
942             status = ScreenPowerStatus::POWER_STATUS_ON;
943             break;
944         }
945         case ScreenPowerState::POWER_OFF: {
946             status = ScreenPowerStatus::POWER_STATUS_OFF;
947             break;
948         }
949         default: {
950             WLOGFW("SetScreenPowerStatus state not support");
951             return false;
952         }
953     }
954 
955     rsInterface_.SetScreenPowerStatus(screenId, status);
956     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
957         return true;
958     }
959     return NotifyDisplayPowerEvent(state == ScreenPowerState::POWER_ON ? DisplayPowerEvent::DISPLAY_ON :
960         DisplayPowerEvent::DISPLAY_OFF, EventStatus::END, reason);
961 }
962 
SetScreenPowerForAll(ScreenPowerState state,PowerStateChangeReason reason)963 bool ScreenSessionManager::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)
964 {
965     ScreenPowerStatus status;
966     if (blockScreenPowerChange_) {
967         WLOGFI("ScreenSessionManager::SetScreenPowerForAll block screen power change");
968         return true;
969     }
970     switch (state) {
971         case ScreenPowerState::POWER_ON: {
972             if (keyguardDrawnDone_) {
973                 WLOGFI("ScreenSessionManager::SetScreenPowerForAll keyguardDrawnDone_ is true step 1");
974                 status = ScreenPowerStatus::POWER_STATUS_ON;
975                 break;
976             } else {
977                 needScreenOnWhenKeyguardNotify_ = true;
978                 auto task = [this]() {
979                     SetScreenPower(ScreenPowerStatus::POWER_STATUS_ON,
980                         PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
981                     needScreenOnWhenKeyguardNotify_ = false;
982                     keyguardDrawnDone_ = true;
983                     WLOGFI("ScreenSessionManager::SetScreenPowerForAll keyguardDrawnDone_ is true step 2");
984                 };
985                 taskScheduler_->PostTask(task, "screenOnTask", 300); // Retry after 300 ms.
986                 return true;
987             }
988         }
989         case ScreenPowerState::POWER_OFF: {
990             keyguardDrawnDone_ = false;
991             WLOGFI("ScreenSessionManager::SetScreenPowerForAll keyguardDrawnDone_ is false");
992             status = ScreenPowerStatus::POWER_STATUS_OFF;
993             break;
994         }
995         default: {
996             WLOGFW("SetScreenPowerStatus state not support");
997             return false;
998         }
999     }
1000     return SetScreenPower(status, reason);
1001 }
1002 
SetScreenPower(ScreenPowerStatus status,PowerStateChangeReason reason)1003 bool ScreenSessionManager::SetScreenPower(ScreenPowerStatus status, PowerStateChangeReason reason)
1004 {
1005     WLOGFI("ScreenSessionManager::SetScreenPower enter status:%{public}u", status);
1006     auto screenIds = GetAllScreenIds();
1007     if (screenIds.empty()) {
1008         WLOGFE("no screen info");
1009         return false;
1010     }
1011 
1012     if (status == ScreenPowerStatus::POWER_STATUS_OFF) {
1013         taskScheduler_->RemoveTask("screenOnTask");
1014     }
1015 
1016     if (foldScreenController_ != nullptr) {
1017         rsInterface_.SetScreenPowerStatus(foldScreenController_->GetCurrentScreenId(), status);
1018     } else {
1019         for (auto screenId : screenIds) {
1020             rsInterface_.SetScreenPowerStatus(screenId, status);
1021             HandlerSensor(status);
1022         }
1023     }
1024     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
1025         return true;
1026     }
1027     return NotifyDisplayPowerEvent(status == ScreenPowerStatus::POWER_STATUS_ON ? DisplayPowerEvent::DISPLAY_ON :
1028         DisplayPowerEvent::DISPLAY_OFF, EventStatus::END, reason);
1029 }
1030 
SetKeyguardDrawnDoneFlag(bool flag)1031 void ScreenSessionManager::SetKeyguardDrawnDoneFlag(bool flag)
1032 {
1033     keyguardDrawnDone_ = flag;
1034 }
1035 
HandlerSensor(ScreenPowerStatus status)1036 void ScreenSessionManager::HandlerSensor(ScreenPowerStatus status)
1037 {
1038     auto isPhone = system::GetParameter("const.product.devicetype", "unknown") == "phone";
1039     if (isPhone) {
1040         if (status == ScreenPowerStatus::POWER_STATUS_ON) {
1041             WLOGFI("subscribe rotation sensor when phone turn on");
1042             ScreenSensorConnector::SubscribeRotationSensor();
1043         } else if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND) {
1044             WLOGFI("unsubscribe rotation sensor when phone turn off");
1045             ScreenSensorConnector::UnsubscribeRotationSensor();
1046         } else {
1047             WLOGFI("SetScreenPower state not support");
1048         }
1049     }
1050 }
1051 
BootFinishedCallback(const char * key,const char * value,void * context)1052 void ScreenSessionManager::BootFinishedCallback(const char *key, const char *value, void *context)
1053 {
1054     if (strcmp(key, BOOTEVENT_BOOT_COMPLETED.c_str()) == 0 && strcmp(value, "true") == 0) {
1055         WLOGFI("ScreenSessionManager BootFinishedCallback boot animation finished");
1056         auto &that = *reinterpret_cast<ScreenSessionManager *>(context);
1057         that.SetDpiFromSettingData();
1058         that.RegisterSettingDpiObserver();
1059         if (that.foldScreenPowerInit_ != nullptr) {
1060             that.foldScreenPowerInit_();
1061         }
1062     }
1063 }
1064 
SetFoldScreenPowerInit(std::function<void ()> foldScreenPowerInit)1065 void ScreenSessionManager::SetFoldScreenPowerInit(std::function<void()> foldScreenPowerInit)
1066 {
1067     foldScreenPowerInit_ = foldScreenPowerInit;
1068 }
1069 
RegisterSettingDpiObserver()1070 void ScreenSessionManager::RegisterSettingDpiObserver()
1071 {
1072     WLOGFI("Register Setting Dpi Observer");
1073     SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetDpiFromSettingData(); };
1074     ScreenSettingHelper::RegisterSettingDpiObserver(updateFunc);
1075 }
1076 
SetDpiFromSettingData()1077 void ScreenSessionManager::SetDpiFromSettingData()
1078 {
1079     uint32_t settingDpi;
1080     bool ret = ScreenSettingHelper::GetSettingDpi(settingDpi);
1081     if (!ret) {
1082         WLOGFW("get setting dpi failed,use default dpi");
1083         settingDpi = defaultDpi;
1084     } else {
1085         WLOGFI("get setting dpi success,settingDpi: %{public}u", settingDpi);
1086     }
1087     if (settingDpi >= DOT_PER_INCH_MINIMUM_VALUE && settingDpi <= DOT_PER_INCH_MAXIMUM_VALUE
1088         && cachedSettingDpi_ != settingDpi) {
1089         cachedSettingDpi_ = settingDpi;
1090         float dpi = static_cast<float>(settingDpi) / BASELINE_DENSITY;
1091         ScreenId defaultScreenId = GetDefaultScreenId();
1092         SetVirtualPixelRatio(defaultScreenId, dpi);
1093     }
1094 }
1095 
GetAllScreenIds()1096 std::vector<ScreenId> ScreenSessionManager::GetAllScreenIds()
1097 {
1098     std::vector<ScreenId> res;
1099     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1100     for (const auto& iter : screenSessionMap_) {
1101         res.emplace_back(iter.first);
1102     }
1103     return res;
1104 }
1105 
GetDisplayState(DisplayId displayId)1106 DisplayState ScreenSessionManager::GetDisplayState(DisplayId displayId)
1107 {
1108     return sessionDisplayPowerController_->GetDisplayState(displayId);
1109 }
1110 
NotifyDisplayEvent(DisplayEvent event)1111 void ScreenSessionManager::NotifyDisplayEvent(DisplayEvent event)
1112 {
1113     WLOGFI("ScreenSessionManager::NotifyDisplayEvent receive keyguardDrawnDone");
1114     sessionDisplayPowerController_->NotifyDisplayEvent(event);
1115     if (event == DisplayEvent::KEYGUARD_DRAWN) {
1116         keyguardDrawnDone_ = true;
1117         WLOGFI("ScreenSessionManager::NotifyDisplayEvent keyguardDrawnDone_ is true");
1118         if (needScreenOnWhenKeyguardNotify_) {
1119             taskScheduler_->RemoveTask("screenOnTask");
1120             usleep(SLEEP_US);
1121             SetScreenPower(ScreenPowerStatus::POWER_STATUS_ON, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
1122             needScreenOnWhenKeyguardNotify_ = false;
1123         }
1124     }
1125 
1126     if (event == DisplayEvent::SCREEN_LOCK_SUSPEND) {
1127         WLOGFI("ScreenSessionManager::NotifyDisplayEvent screen lock suspend");
1128         taskScheduler_->RemoveTask("suspendBeginTask");
1129         blockScreenPowerChange_ = false;
1130         SetScreenPower(ScreenPowerStatus::POWER_STATUS_SUSPEND, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
1131     }
1132 
1133     if (event == DisplayEvent::SCREEN_LOCK_OFF) {
1134         WLOGFI("ScreenSessionManager::NotifyDisplayEvent screen lock off");
1135         taskScheduler_->RemoveTask("suspendBeginTask");
1136         blockScreenPowerChange_ = false;
1137         SetScreenPower(ScreenPowerStatus::POWER_STATUS_OFF, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
1138     }
1139 }
1140 
GetScreenPower(ScreenId screenId)1141 ScreenPowerState ScreenSessionManager::GetScreenPower(ScreenId screenId)
1142 {
1143     auto state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance().GetScreenPowerStatus(screenId));
1144     WLOGFI("GetScreenPower:%{public}u, rsscreen:%{public}" PRIu64".", state, screenId);
1145     return state;
1146 }
1147 
IsScreenRotationLocked(bool & isLocked)1148 DMError ScreenSessionManager::IsScreenRotationLocked(bool& isLocked)
1149 {
1150     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1151         WLOGFE("SCB: ScreenSessionManager is screen rotation locked permission denied!");
1152         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1153     }
1154     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
1155     if (screenSession == nullptr) {
1156         WLOGFE("fail to get default screenSession");
1157         return DMError::DM_ERROR_INVALID_PARAM;
1158     }
1159     isLocked = screenSession->IsScreenRotationLocked();
1160     WLOGFI("SCB: IsScreenRotationLocked:isLocked: %{public}u", isLocked);
1161     return DMError::DM_OK;
1162 }
1163 
SetScreenRotationLocked(bool isLocked)1164 DMError ScreenSessionManager::SetScreenRotationLocked(bool isLocked)
1165 {
1166     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1167         WLOGFE("SCB: ScreenSessionManager set screen rotation locked permission denied!");
1168         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1169     }
1170     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
1171     if (screenSession == nullptr) {
1172         WLOGFE("fail to get default screenSession");
1173         return DMError::DM_ERROR_INVALID_PARAM;
1174     }
1175     screenSession->SetScreenRotationLocked(isLocked);
1176     WLOGFI("SCB: SetScreenRotationLocked: isLocked: %{public}u", isLocked);
1177     return DMError::DM_OK;
1178 }
1179 
UpdateScreenRotationProperty(ScreenId screenId,const RRect & bounds,float rotation)1180 void ScreenSessionManager::UpdateScreenRotationProperty(ScreenId screenId, const RRect& bounds, float rotation)
1181 {
1182     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1183     if (screenSession == nullptr) {
1184         WLOGFE("fail to update screen rotation property, cannot find screen %{public}" PRIu64"", screenId);
1185         return;
1186     }
1187     bool needNotifyAvoidArea = false;
1188     if (screenSession->GetScreenProperty().GetBounds() == bounds &&
1189         screenSession->GetScreenProperty().GetRotation() != static_cast<float>(rotation)) {
1190         needNotifyAvoidArea = true;
1191     }
1192     screenSession->UpdatePropertyAfterRotation(bounds, rotation, GetFoldDisplayMode());
1193     sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1194     if (displayInfo == nullptr) {
1195         WLOGFE("fail to update screen rotation property, displayInfo is nullptr");
1196         return;
1197     }
1198     NotifyDisplayChanged(displayInfo, DisplayChangeEvent::UPDATE_ROTATION);
1199     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
1200     if (needNotifyAvoidArea) {
1201         std::map<DisplayId, sptr<DisplayInfo>> emptyMap;
1202         NotifyDisplayStateChange(GetDefaultScreenId(), screenSession->ConvertToDisplayInfo(),
1203             emptyMap, DisplayStateChangeType::UPDATE_ROTATION);
1204     }
1205 }
1206 
NotifyDisplayChanged(sptr<DisplayInfo> displayInfo,DisplayChangeEvent event)1207 void ScreenSessionManager::NotifyDisplayChanged(sptr<DisplayInfo> displayInfo, DisplayChangeEvent event)
1208 {
1209     if (displayInfo == nullptr) {
1210         WLOGFE("NotifyDisplayChanged error, displayInfo is nullptr.");
1211         return;
1212     }
1213     auto task = [=] {
1214         WLOGFI("NotifyDisplayChanged, displayId:%{public}" PRIu64"", displayInfo->GetDisplayId());
1215         auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
1216         if (agents.empty()) {
1217             return;
1218         }
1219         for (auto& agent : agents) {
1220             agent->OnDisplayChange(displayInfo, event);
1221         }
1222     };
1223     taskScheduler_->PostAsyncTask(task, "NotifyDisplayChanged");
1224 }
1225 
SetOrientation(ScreenId screenId,Orientation orientation)1226 DMError ScreenSessionManager::SetOrientation(ScreenId screenId, Orientation orientation)
1227 {
1228     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1229         WLOGFE("SCB: ScreenSessionManager set orientation permission denied!");
1230         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1231     }
1232     if (orientation < Orientation::UNSPECIFIED || orientation > Orientation::REVERSE_HORIZONTAL) {
1233         WLOGFE("SCB: ScreenSessionManager set orientation: %{public}u", static_cast<uint32_t>(orientation));
1234         return DMError::DM_ERROR_INVALID_PARAM;
1235     }
1236     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetOrientation");
1237     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1238     if (screenSession == nullptr) {
1239         WLOGFE("fail to set orientation, cannot find screen %{public}" PRIu64"", screenId);
1240         return DMError::DM_ERROR_NULLPTR;
1241     }
1242     // just for get orientation test
1243     screenSession->SetOrientation(orientation);
1244     screenSession->ScreenOrientationChange(orientation, GetFoldDisplayMode());
1245     return DMError::DM_OK;
1246 }
1247 
SetOrientationFromWindow(DisplayId displayId,Orientation orientation)1248 DMError ScreenSessionManager::SetOrientationFromWindow(DisplayId displayId, Orientation orientation)
1249 {
1250     sptr<DisplayInfo> displayInfo = GetDisplayInfoById(displayId);
1251     if (displayInfo == nullptr) {
1252         return DMError::DM_ERROR_NULLPTR;
1253     }
1254     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetOrientationFromWindow");
1255     return SetOrientationController(displayInfo->GetScreenId(), orientation, true);
1256 }
1257 
SetOrientationController(ScreenId screenId,Orientation newOrientation,bool isFromWindow)1258 DMError ScreenSessionManager::SetOrientationController(ScreenId screenId, Orientation newOrientation,
1259     bool isFromWindow)
1260 {
1261     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1262     if (screenSession == nullptr) {
1263         WLOGFE("fail to set orientation, cannot find screen %{public}" PRIu64"", screenId);
1264         return DMError::DM_ERROR_NULLPTR;
1265     }
1266 
1267     if (isFromWindow) {
1268         if (newOrientation == Orientation::UNSPECIFIED) {
1269             newOrientation = screenSession->GetScreenRequestedOrientation();
1270         }
1271     } else {
1272         screenSession->SetScreenRequestedOrientation(newOrientation);
1273     }
1274 
1275     if (screenSession->GetOrientation() == newOrientation) {
1276         return DMError::DM_OK;
1277     }
1278     if (isFromWindow) {
1279         ScreenRotationProperty::ProcessOrientationSwitch(newOrientation);
1280     } else {
1281         Rotation rotationAfter = screenSession->CalcRotation(newOrientation, GetFoldDisplayMode());
1282         SetRotation(screenId, rotationAfter, false);
1283     }
1284     screenSession->SetOrientation(newOrientation);
1285     screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::ROTATION);
1286     // Notify rotation event to ScreenManager
1287     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ORIENTATION);
1288     return DMError::DM_OK;
1289 }
1290 
SetRotation(ScreenId screenId,Rotation rotationAfter,bool isFromWindow)1291 bool ScreenSessionManager::SetRotation(ScreenId screenId, Rotation rotationAfter, bool isFromWindow)
1292 {
1293     WLOGFI("Enter SetRotation, screenId: %{public}" PRIu64 ", rotation: %{public}u, isFromWindow: %{public}u,",
1294         screenId, rotationAfter, isFromWindow);
1295     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1296     if (screenSession == nullptr) {
1297         WLOGFE("SetRotation error, cannot get screen with screenId: %{public}" PRIu64, screenId);
1298         return false;
1299     }
1300     if (rotationAfter == screenSession->GetRotation()) {
1301         WLOGFE("rotation not changed. screen %{public}" PRIu64" rotation %{public}u", screenId, rotationAfter);
1302         return false;
1303     }
1304     WLOGFD("set orientation. rotation %{public}u", rotationAfter);
1305     SetDisplayBoundary(screenSession);
1306     screenSession->SetRotation(rotationAfter);
1307     screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::ROTATION);
1308     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
1309     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::UPDATE_ROTATION);
1310     return true;
1311 }
1312 
SetSensorSubscriptionEnabled()1313 void ScreenSessionManager::SetSensorSubscriptionEnabled()
1314 {
1315     isAutoRotationOpen_ = system::GetParameter("persist.display.ar.enabled", "1") == "1";
1316     if (!isAutoRotationOpen_) {
1317         WLOGFE("autoRotation is not open");
1318         ScreenRotationProperty::Init();
1319         return;
1320     }
1321     ScreenRotationProperty::Init();
1322     ScreenSensorConnector::SubscribeRotationSensor();
1323     WLOGFI("subscribe rotation sensor successful");
1324 }
1325 
SetRotationFromWindow(Rotation targetRotation)1326 bool ScreenSessionManager::SetRotationFromWindow(Rotation targetRotation)
1327 {
1328     sptr<DisplayInfo> displayInfo = GetDefaultDisplayInfo();
1329     if (displayInfo == nullptr) {
1330         return false;
1331     }
1332     return SetRotation(displayInfo->GetScreenId(), targetRotation, true);
1333 }
1334 
GetScreenModesByDisplayId(DisplayId displayId)1335 sptr<SupportedScreenModes> ScreenSessionManager::GetScreenModesByDisplayId(DisplayId displayId)
1336 {
1337     auto displayInfo = GetDisplayInfoById(displayId);
1338     if (displayInfo == nullptr) {
1339         WLOGFW("can not get display.");
1340         return nullptr;
1341     }
1342     auto screenInfo = GetScreenInfoById(displayInfo->GetScreenId());
1343     if (screenInfo == nullptr) {
1344         WLOGFE("can not get screen.");
1345         return nullptr;
1346     }
1347     auto modes = screenInfo->GetModes();
1348     auto id = screenInfo->GetModeId();
1349     if (id >= modes.size()) {
1350         WLOGFE("can not get screenMode.");
1351         return nullptr;
1352     }
1353     return modes[id];
1354 }
1355 
GetScreenInfoByDisplayId(DisplayId displayId)1356 sptr<ScreenInfo> ScreenSessionManager::GetScreenInfoByDisplayId(DisplayId displayId)
1357 {
1358     auto displayInfo = GetDisplayInfoById(displayId);
1359     if (displayInfo == nullptr) {
1360         WLOGFE("can not get displayInfo.");
1361         return nullptr;
1362     }
1363     return GetScreenInfoById(displayInfo->GetScreenId());
1364 }
1365 
NotifyDisplayPowerEvent(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)1366 bool ScreenSessionManager::NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status,
1367     PowerStateChangeReason reason)
1368 {
1369     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER);
1370     if (agents.empty()) {
1371         return false;
1372     }
1373     WLOGFD("NotifyDisplayPowerEvent");
1374     for (auto& agent : agents) {
1375         agent->NotifyDisplayPowerEvent(event, status);
1376     }
1377 
1378     auto screenIds = GetAllScreenIds();
1379     if (screenIds.empty()) {
1380         WLOGFE("NotifyDisplayPowerEvent no screen info");
1381         return false;
1382     }
1383 
1384     for (auto screenId : screenIds) {
1385         sptr<ScreenSession> screen = GetScreenSession(screenId);
1386         screen->PowerStatusChange(event, status, reason);
1387     }
1388     return true;
1389 }
1390 
NotifyDisplayStateChanged(DisplayId id,DisplayState state)1391 bool ScreenSessionManager::NotifyDisplayStateChanged(DisplayId id, DisplayState state)
1392 {
1393     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_STATE_LISTENER);
1394     if (agents.empty()) {
1395         return false;
1396     }
1397     WLOGFI("NotifyDisplayStateChanged");
1398     for (auto& agent : agents) {
1399         agent->NotifyDisplayStateChanged(id, state);
1400     }
1401     return true;
1402 }
GetAllScreenInfos(std::vector<sptr<ScreenInfo>> & screenInfos)1403 DMError ScreenSessionManager::GetAllScreenInfos(std::vector<sptr<ScreenInfo>>& screenInfos)
1404 {
1405     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1406         WLOGFE("SCB: ScreenSessionManager::GetAllScreenInfos get all screen infos permission denied!");
1407         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1408     }
1409     std::vector<ScreenId> screenIds = GetAllScreenIds();
1410     for (auto screenId: screenIds) {
1411         auto screenInfo = GetScreenInfoById(screenId);
1412         if (screenInfo == nullptr) {
1413             WLOGE("SCB: ScreenSessionManager::GetAllScreenInfos cannot find screenInfo: %{public}" PRIu64"", screenId);
1414             continue;
1415         }
1416         screenInfos.emplace_back(screenInfo);
1417     }
1418     return DMError::DM_OK;
1419 }
1420 
GetAllScreenIds() const1421 std::vector<ScreenId> ScreenSessionManager::GetAllScreenIds() const
1422 {
1423     std::vector<ScreenId> res;
1424     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1425     for (const auto& iter : screenSessionMap_) {
1426         res.emplace_back(iter.first);
1427     }
1428     return res;
1429 }
1430 
GetScreenSupportedColorGamuts(ScreenId screenId,std::vector<ScreenColorGamut> & colorGamuts)1431 DMError ScreenSessionManager::GetScreenSupportedColorGamuts(ScreenId screenId,
1432     std::vector<ScreenColorGamut>& colorGamuts)
1433 {
1434     WLOGFI("SCB: ScreenSessionManager::GetScreenSupportedColorGamuts ENTER");
1435     if (!SessionPermission::IsSystemCalling()) {
1436         WLOGFE("SCB: ScreenSessionManager::GetScreenSupportedColorGamuts permission denied!");
1437         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1438     }
1439     sptr<ScreenSession> screen = GetScreenSession(screenId);
1440     if (screen == nullptr) {
1441         WLOGFE("SCB: ScreenSessionManager::GetScreenSupportedColorGamuts nullptr");
1442         return DMError::DM_ERROR_INVALID_PARAM;
1443     }
1444     return screen->GetScreenSupportedColorGamuts(colorGamuts);
1445 }
1446 
GetPixelFormat(ScreenId screenId,GraphicPixelFormat & pixelFormat)1447 DMError ScreenSessionManager::GetPixelFormat(ScreenId screenId, GraphicPixelFormat& pixelFormat)
1448 {
1449     WLOGFI("GetPixelFormat::ScreenId: %{public}" PRIu64, screenId);
1450     if (screenId == SCREEN_ID_INVALID) {
1451         WLOGFE("screenId invalid");
1452         return DMError::DM_ERROR_INVALID_PARAM;
1453     }
1454     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1455     if (screenSession == nullptr) {
1456         return DMError::DM_ERROR_INVALID_PARAM;
1457     }
1458     return screenSession->GetPixelFormat(pixelFormat);
1459 }
1460 
SetPixelFormat(ScreenId screenId,GraphicPixelFormat pixelFormat)1461 DMError ScreenSessionManager::SetPixelFormat(ScreenId screenId, GraphicPixelFormat pixelFormat)
1462 {
1463     WLOGFI("SetPixelFormat::ScreenId: %{public}" PRIu64 ", pixelFormat %{public}d", screenId, pixelFormat);
1464     if (screenId == SCREEN_ID_INVALID) {
1465         WLOGFE("screenId invalid");
1466         return DMError::DM_ERROR_INVALID_PARAM;
1467     }
1468     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1469     if (screenSession == nullptr) {
1470         return DMError::DM_ERROR_INVALID_PARAM;
1471     }
1472     return screenSession->SetPixelFormat(pixelFormat);
1473 }
1474 
GetSupportedHDRFormats(ScreenId screenId,std::vector<ScreenHDRFormat> & hdrFormats)1475 DMError ScreenSessionManager::GetSupportedHDRFormats(ScreenId screenId,
1476     std::vector<ScreenHDRFormat>& hdrFormats)
1477 {
1478     WLOGFI("SCB: ScreenSessionManager::GetSupportedHDRFormats %{public}" PRIu64, screenId);
1479     sptr<ScreenSession> screen = GetScreenSession(screenId);
1480     if (screen == nullptr) {
1481         WLOGFE("SCB: ScreenSessionManager::GetSupportedHDRFormats nullptr");
1482         return DMError::DM_ERROR_INVALID_PARAM;
1483     }
1484     return screen->GetSupportedHDRFormats(hdrFormats);
1485 }
1486 
GetScreenHDRFormat(ScreenId screenId,ScreenHDRFormat & hdrFormat)1487 DMError ScreenSessionManager::GetScreenHDRFormat(ScreenId screenId, ScreenHDRFormat& hdrFormat)
1488 {
1489     WLOGFI("GetScreenHDRFormat::ScreenId: %{public}" PRIu64, screenId);
1490     if (screenId == SCREEN_ID_INVALID) {
1491         WLOGFE("screenId invalid");
1492         return DMError::DM_ERROR_INVALID_PARAM;
1493     }
1494     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1495     if (screenSession == nullptr) {
1496         return DMError::DM_ERROR_INVALID_PARAM;
1497     }
1498     return screenSession->GetScreenHDRFormat(hdrFormat);
1499 }
1500 
SetScreenHDRFormat(ScreenId screenId,int32_t modeIdx)1501 DMError ScreenSessionManager::SetScreenHDRFormat(ScreenId screenId, int32_t modeIdx)
1502 {
1503     WLOGFI("SetScreenHDRFormat::ScreenId: %{public}" PRIu64 ", modeIdx %{public}d", screenId, modeIdx);
1504     if (screenId == SCREEN_ID_INVALID) {
1505         WLOGFE("screenId invalid");
1506         return DMError::DM_ERROR_INVALID_PARAM;
1507     }
1508     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1509     if (screenSession == nullptr) {
1510         return DMError::DM_ERROR_INVALID_PARAM;
1511     }
1512     return screenSession->SetScreenHDRFormat(modeIdx);
1513 }
1514 
GetSupportedColorSpaces(ScreenId screenId,std::vector<GraphicCM_ColorSpaceType> & colorSpaces)1515 DMError ScreenSessionManager::GetSupportedColorSpaces(ScreenId screenId,
1516     std::vector<GraphicCM_ColorSpaceType>& colorSpaces)
1517 {
1518     WLOGFI("SCB: ScreenSessionManager::GetSupportedColorSpaces %{public}" PRIu64, screenId);
1519     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1520     if (screenSession == nullptr) {
1521         WLOGFE("SCB: ScreenSessionManager::GetSupportedColorSpaces nullptr");
1522         return DMError::DM_ERROR_INVALID_PARAM;
1523     }
1524     return screenSession->GetSupportedColorSpaces(colorSpaces);
1525 }
1526 
GetScreenColorSpace(ScreenId screenId,GraphicCM_ColorSpaceType & colorSpace)1527 DMError ScreenSessionManager::GetScreenColorSpace(ScreenId screenId, GraphicCM_ColorSpaceType& colorSpace)
1528 {
1529     WLOGFI("GetScreenColorSpace::ScreenId: %{public}" PRIu64, screenId);
1530     if (screenId == SCREEN_ID_INVALID) {
1531         WLOGFE("screenId invalid");
1532         return DMError::DM_ERROR_INVALID_PARAM;
1533     }
1534     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1535     if (screenSession == nullptr) {
1536         return DMError::DM_ERROR_INVALID_PARAM;
1537     }
1538     return screenSession->GetScreenColorSpace(colorSpace);
1539 }
1540 
SetScreenColorSpace(ScreenId screenId,GraphicCM_ColorSpaceType colorSpace)1541 DMError ScreenSessionManager::SetScreenColorSpace(ScreenId screenId, GraphicCM_ColorSpaceType colorSpace)
1542 {
1543     WLOGFI("SetScreenColorSpace::ScreenId: %{public}" PRIu64 ", colorSpace %{public}d", screenId, colorSpace);
1544     if (screenId == SCREEN_ID_INVALID) {
1545         WLOGFE("screenId invalid");
1546         return DMError::DM_ERROR_INVALID_PARAM;
1547     }
1548     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1549     if (screenSession == nullptr) {
1550         return DMError::DM_ERROR_INVALID_PARAM;
1551     }
1552     return screenSession->SetScreenColorSpace(colorSpace);
1553 }
1554 
CreateVirtualScreen(VirtualScreenOption option,const sptr<IRemoteObject> & displayManagerAgent)1555 ScreenId ScreenSessionManager::CreateVirtualScreen(VirtualScreenOption option,
1556                                                    const sptr<IRemoteObject>& displayManagerAgent)
1557 {
1558     if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
1559         !SessionPermission::IsShellCall()) {
1560         WLOGFE("create virtual screen permission denied!");
1561         return SCREEN_ID_INVALID;
1562     }
1563     WLOGFI("SCB: ScreenSessionManager::CreateVirtualScreen ENTER");
1564 
1565     CheckAndSendHiSysEvent("CREATE_VIRTUAL_SCREEN", "ohos.screenrecorder");
1566 
1567     if (clientProxy_ && option.missionIds_.size() > 0) {
1568         std::vector<uint64_t> surfaceNodeIds;
1569         clientProxy_->OnGetSurfaceNodeIdsFromMissionIdsChanged(option.missionIds_, surfaceNodeIds);
1570         option.missionIds_ = surfaceNodeIds;
1571     }
1572     ScreenId rsId = rsInterface_.CreateVirtualScreen(option.name_, option.width_,
1573         option.height_, option.surface_, SCREEN_ID_INVALID, option.flags_);
1574     WLOGFI("SCB: ScreenSessionManager::CreateVirtualScreen rsid: %{public}" PRIu64"", rsId);
1575     if (rsId == SCREEN_ID_INVALID) {
1576         WLOGFI("SCB: ScreenSessionManager::CreateVirtualScreen rsid is invalid");
1577         return SCREEN_ID_INVALID;
1578     }
1579     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CreateVirtualScreen(%s)", option.name_.c_str());
1580     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1581     ScreenId smsScreenId = SCREEN_ID_INVALID;
1582     if (!screenIdManager_.ConvertToSmsScreenId(rsId, smsScreenId)) {
1583         WLOGFI("SCB: ScreenSessionManager::CreateVirtualScreen !ConvertToSmsScreenId(rsId, smsScreenId)");
1584         smsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsId);
1585         auto screenSession = InitVirtualScreen(smsScreenId, rsId, option);
1586         if (screenSession == nullptr) {
1587             WLOGFI("SCB: ScreenSessionManager::CreateVirtualScreen screensession is nullptr");
1588             screenIdManager_.DeleteScreenId(smsScreenId);
1589             return SCREEN_ID_INVALID;
1590         }
1591         screenSession->SetName(option.name_);
1592         screenSessionMap_.insert(std::make_pair(smsScreenId, screenSession));
1593         NotifyScreenConnected(screenSession->ConvertToScreenInfo());
1594         if (deathRecipient_ == nullptr) {
1595             WLOGFI("SCB: ScreenSessionManager::CreateVirtualScreen Create deathRecipient");
1596             deathRecipient_ =
1597                 new AgentDeathRecipient([this](const sptr<IRemoteObject>& agent) { OnRemoteDied(agent); });
1598         }
1599         if (displayManagerAgent == nullptr) {
1600             return smsScreenId;
1601         }
1602         auto agIter = screenAgentMap_.find(displayManagerAgent);
1603         if (agIter == screenAgentMap_.end()) {
1604             displayManagerAgent->AddDeathRecipient(deathRecipient_);
1605         }
1606         screenAgentMap_[displayManagerAgent].emplace_back(smsScreenId);
1607     } else {
1608         WLOGFI("SCB: ScreenSessionManager::CreateVirtualScreen id: %{public}" PRIu64" in screenIdManager_", rsId);
1609     }
1610     return smsScreenId;
1611 }
1612 
SetVirtualScreenSurface(ScreenId screenId,sptr<IBufferProducer> surface)1613 DMError ScreenSessionManager::SetVirtualScreenSurface(ScreenId screenId, sptr<IBufferProducer> surface)
1614 {
1615     if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
1616         !SessionPermission::IsShellCall()) {
1617         WLOGFE("set virtual screenSurface permission denied!");
1618         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1619     }
1620     WLOGFI("SCB: ScreenSessionManager::SetVirtualScreenSurface ENTER");
1621     ScreenId rsScreenId;
1622     int32_t res = -1;
1623     if (screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
1624         sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(surface);
1625         res = rsInterface_.SetVirtualScreenSurface(rsScreenId, pSurface);
1626     }
1627     if (res != 0) {
1628         WLOGE("SCB: ScreenSessionManager::SetVirtualScreenSurface failed in RenderService");
1629         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1630     }
1631     return DMError::DM_OK;
1632 }
1633 
SetVirtualMirrorScreenCanvasRotation(ScreenId screenId,bool autoRotate)1634 DMError ScreenSessionManager::SetVirtualMirrorScreenCanvasRotation(ScreenId screenId, bool autoRotate)
1635 {
1636     if (!SessionPermission::IsSystemCalling()) {
1637         WLOGFE("SetVirtualMirrorScreenCanvasRotation denied!");
1638         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1639     }
1640     WLOGFI("SCB: ScreenSessionManager::SetVirtualMirrorScreenCanvasRotation ENTER");
1641 
1642     bool res = false;
1643     ScreenId rsScreenId;
1644     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
1645         WLOGFE("SetVirtualMirrorScreenCanvasRotation: No corresponding rsId");
1646         return DMError::DM_ERROR_INVALID_PARAM;
1647     }
1648     res = rsInterface_.SetVirtualMirrorScreenCanvasRotation(rsScreenId, autoRotate);
1649     if (!res) {
1650         WLOGE("SetVirtualMirrorScreenCanvasRotation failed in RenderService");
1651         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1652     }
1653     WLOGI("SetVirtualMirrorScreenCanvasRotation success");
1654     return DMError::DM_OK;
1655 }
1656 
ResizeVirtualScreen(ScreenId screenId,uint32_t width,uint32_t height)1657 DMError ScreenSessionManager::ResizeVirtualScreen(ScreenId screenId, uint32_t width, uint32_t height)
1658 {
1659     if (!SessionPermission::IsSystemCalling()) {
1660         WLOGFE("ResizeVirtualScreen permission denied!");
1661         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1662     }
1663     WLOGFI("ResizeVirtualScreen, screenId: %{public}" PRIu64", width: %{public}u, height: %{public}u.",
1664         screenId, width, height);
1665     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1666     if (screenSession == nullptr) {
1667         WLOGFE("ResizeVirtualScreen: no such screen.");
1668         return DMError::DM_ERROR_INVALID_PARAM;
1669     }
1670     ScreenId rsScreenId;
1671     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
1672         WLOGFE("ResizeVirtualScreen: No corresponding rsId");
1673         return DMError::DM_ERROR_INVALID_PARAM;
1674     }
1675     rsInterface_.ResizeVirtualScreen(rsScreenId, width, height);
1676     screenSession->Resize(width, height);
1677     screenSession->PropertyChange(screenSession->GetScreenProperty(),
1678         ScreenPropertyChangeReason::VIRTUAL_SCREEN_RESIZE);
1679     return DMError::DM_OK;
1680 }
1681 
DestroyVirtualScreen(ScreenId screenId)1682 DMError ScreenSessionManager::DestroyVirtualScreen(ScreenId screenId)
1683 {
1684     if (!SessionPermission::IsSystemCalling()) {
1685         WLOGFE("destroy virtual screen permission denied!");
1686         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1687     }
1688 
1689     // virtual screen destroy callback to notify scb
1690     WLOGFI("destroy callback virtual screen");
1691     OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED);
1692 
1693     WLOGI("SCB: ScreenSessionManager::DestroyVirtualScreen Enter");
1694     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1695     ScreenId rsScreenId = SCREEN_ID_INVALID;
1696     screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
1697 
1698     bool agentFound = false;
1699     for (auto &agentIter : screenAgentMap_) {
1700         for (auto iter = agentIter.second.begin(); iter != agentIter.second.end(); iter++) {
1701             if (*iter == screenId) {
1702                 iter = agentIter.second.erase(iter);
1703                 agentFound = true;
1704                 break;
1705             }
1706         }
1707         if (agentFound) {
1708             if (agentIter.first != nullptr && agentIter.second.empty()) {
1709                 screenAgentMap_.erase(agentIter.first);
1710             }
1711             break;
1712         }
1713     }
1714     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyVirtualScreen(%" PRIu64")", screenId);
1715     if (rsScreenId != SCREEN_ID_INVALID && GetScreenSession(screenId) != nullptr) {
1716         auto screen = GetScreenSession(screenId);
1717         if (CheckScreenInScreenGroup(screen)) {
1718             NotifyDisplayDestroy(screenId);
1719         }
1720         auto smsScreenMapIter = screenSessionMap_.find(screenId);
1721         if (smsScreenMapIter != screenSessionMap_.end()) {
1722             auto screenGroup = RemoveFromGroupLocked(smsScreenMapIter->second);
1723             if (screenGroup != nullptr) {
1724                 NotifyScreenGroupChanged(
1725                     smsScreenMapIter->second->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
1726             }
1727             screenSessionMap_.erase(smsScreenMapIter);
1728             NotifyScreenDisconnected(screenId);
1729             WLOGFI("SCB: ScreenSessionManager::DestroyVirtualScreen id: %{public}" PRIu64"", screenId);
1730         }
1731     }
1732     screenIdManager_.DeleteScreenId(screenId);
1733 
1734     if (rsScreenId == SCREEN_ID_INVALID) {
1735         WLOGFE("SCB: ScreenSessionManager::DestroyVirtualScreen: No corresponding rsScreenId");
1736         return DMError::DM_ERROR_INVALID_PARAM;
1737     }
1738     rsInterface_.RemoveVirtualScreen(rsScreenId);
1739     return DMError::DM_OK;
1740 }
1741 
DisableMirror(bool disableOrNot)1742 DMError ScreenSessionManager::DisableMirror(bool disableOrNot)
1743 {
1744     WLOGFI("SCB:ScreenSessionManager::DisableMirror %{public}d", disableOrNot);
1745     if (!SessionPermission::IsSystemCalling()) {
1746         WLOGFI("DisableMirror permission denied!");
1747         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1748     }
1749     WLOGFI("SCB:ScreenSessionManager::DisableMirror enter %{public}d", disableOrNot);
1750     if (disableOrNot) {
1751         std::vector<ScreenId> screenIds;
1752         auto allScreenIds = GetAllScreenIds();
1753         for (auto screenId : allScreenIds) {
1754             auto screen = GetScreenSession(screenId);
1755             if (screen && screen->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
1756                 screenIds.push_back(screenId);
1757             }
1758         }
1759         StopMirror(screenIds);
1760     }
1761     return DMError::DM_OK;
1762 }
1763 
MakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,ScreenId & screenGroupId)1764 DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
1765                                          ScreenId& screenGroupId)
1766 {
1767     WLOGFI("SCB:ScreenSessionManager::MakeMirror enter!");
1768     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1769         WLOGFE("SCB:ScreenSessionManager::MakeMirror permission denied!");
1770         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1771     }
1772     if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
1773         WLOGFW("SCB:ScreenSessionManager::MakeMirror was disabled by edm!");
1774         return DMError::DM_ERROR_INVALID_PERMISSION;
1775     }
1776     WLOGFI("SCB:ScreenSessionManager::MakeMirror mainScreenId :%{public}" PRIu64"", mainScreenId);
1777     auto allMirrorScreenIds = GetAllValidScreenIds(mirrorScreenIds);
1778     auto iter = std::find(allMirrorScreenIds.begin(), allMirrorScreenIds.end(), mainScreenId);
1779     if (iter != allMirrorScreenIds.end()) {
1780         allMirrorScreenIds.erase(iter);
1781     }
1782     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:MakeMirror");
1783     auto mainScreen = GetScreenSession(mainScreenId);
1784     if (mainScreen == nullptr || allMirrorScreenIds.empty()) {
1785         WLOGFE("SCB:ScreenSessionManager::MakeMirror fail. mainScreen :%{public}" PRIu64", screens size:%{public}u",
1786             mainScreenId, static_cast<uint32_t>(allMirrorScreenIds.size()));
1787         return DMError::DM_ERROR_INVALID_PARAM;
1788     }
1789     DMError ret = SetMirror(mainScreenId, allMirrorScreenIds);
1790     if (ret != DMError::DM_OK) {
1791         WLOGFE("SCB:ScreenSessionManager::MakeMirror set mirror failed.");
1792         return ret;
1793     }
1794     if (GetAbstractScreenGroup(mainScreen->groupSmsId_) == nullptr) {
1795         WLOGFE("SCB:ScreenSessionManager::MakeMirror get screen group failed.");
1796         return DMError::DM_ERROR_NULLPTR;
1797     }
1798     screenGroupId = mainScreen->groupSmsId_;
1799     return DMError::DM_OK;
1800 }
1801 
StopMirror(const std::vector<ScreenId> & mirrorScreenIds)1802 DMError ScreenSessionManager::StopMirror(const std::vector<ScreenId>& mirrorScreenIds)
1803 {
1804     if (!SessionPermission::IsSystemCalling()) {
1805         WLOGFE("StopMirror permission denied!");
1806         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1807     }
1808     auto allMirrorScreenIds = GetAllValidScreenIds(mirrorScreenIds);
1809     if (allMirrorScreenIds.empty()) {
1810         WLOGFI("SCB: StopMirror done. screens' size:%{public}u", static_cast<uint32_t>(allMirrorScreenIds.size()));
1811         return DMError::DM_OK;
1812     }
1813 
1814     DMError ret = StopScreens(allMirrorScreenIds, ScreenCombination::SCREEN_MIRROR);
1815     if (ret != DMError::DM_OK) {
1816         WLOGFE("SCB: StopMirror failed.");
1817         return ret;
1818     }
1819 
1820     return DMError::DM_OK;
1821 }
1822 
StopScreens(const std::vector<ScreenId> & screenIds,ScreenCombination stopCombination)1823 DMError ScreenSessionManager::StopScreens(const std::vector<ScreenId>& screenIds, ScreenCombination stopCombination)
1824 {
1825     for (ScreenId screenId : screenIds) {
1826         WLOGFI("SCB: StopMirror ScreenId: %{public}" PRIu64"", screenId);
1827         auto screen = GetScreenSession(screenId);
1828         if (screen == nullptr) {
1829             WLOGFW("SCB: StopMirror screen:%{public}" PRIu64" is nullptr", screenId);
1830             continue;
1831         }
1832         sptr<ScreenSessionGroup> screenGroup = GetAbstractScreenGroup(screen->groupSmsId_);
1833         if (!screenGroup) {
1834             WLOGFW("SCB: StopMirror groupDmsId:%{public}" PRIu64"is not in smsScreenGroupMap_", screen->groupSmsId_);
1835             continue;
1836         }
1837         if (screenGroup->combination_ != stopCombination) {
1838             WLOGFW("SCB: StopMirror try to stop screen in another combination");
1839             continue;
1840         }
1841         if (screenGroup->combination_ == ScreenCombination::SCREEN_MIRROR &&
1842             screen->screenId_ == screenGroup->mirrorScreenId_) {
1843             WLOGFW("SCB: StopMirror try to stop main mirror screen");
1844             continue;
1845         }
1846         bool res = RemoveChildFromGroup(screen, screenGroup);
1847         if (res) {
1848             NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
1849         }
1850     }
1851     return DMError::DM_OK;
1852 }
1853 
MakeUniqueScreen(const std::vector<ScreenId> & screenIds)1854 DMError ScreenSessionManager::MakeUniqueScreen(const std::vector<ScreenId>& screenIds)
1855 {
1856     WLOGFI("SCB:ScreenSessionManager::MakeUniqueScreen enter!");
1857     if (screenIds.empty()) {
1858         WLOGFE("screen is empty");
1859         return DMError::DM_ERROR_INVALID_PARAM;
1860     }
1861     ScreenId mainScreenId = GetDefaultScreenId();
1862     ScreenId uniqueScreenId = screenIds[0];
1863     WLOGFI("MainScreenId %{public}" PRIu64" unique screenId %{public}" PRIu64".", mainScreenId, uniqueScreenId);
1864 
1865     auto defaultScreen = GetDefaultScreenSession();
1866     if (!defaultScreen) {
1867         WLOGFE("Default screen is nullptr");
1868         return DMError::DM_ERROR_NULLPTR;
1869     }
1870     auto group = GetAbstractScreenGroup(defaultScreen->groupSmsId_);
1871     if (group == nullptr) {
1872         group = AddToGroupLocked(defaultScreen);
1873         if (group == nullptr) {
1874             WLOGFE("group is nullptr");
1875             return DMError::DM_ERROR_NULLPTR;
1876         }
1877         NotifyScreenGroupChanged(defaultScreen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
1878     }
1879     Point point;
1880     std::vector<Point> startPoints;
1881     startPoints.insert(startPoints.begin(), screenIds.size(), point);
1882     ChangeScreenGroup(group, screenIds, startPoints, true, ScreenCombination::SCREEN_UNIQUE);
1883 
1884     // virtual screen create callback to notify scb
1885     OnVirtualScreenChange(uniqueScreenId, ScreenEvent::CONNECTED);
1886     return DMError::DM_OK;
1887 }
1888 
1889 
MakeExpand(std::vector<ScreenId> screenId,std::vector<Point> startPoint,ScreenId & screenGroupId)1890 DMError ScreenSessionManager::MakeExpand(std::vector<ScreenId> screenId,
1891                                          std::vector<Point> startPoint,
1892                                          ScreenId& screenGroupId)
1893 {
1894     WLOGFI("SCB:ScreenSessionManager::MakeExpand enter!");
1895     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1896         WLOGFE("SCB:ScreenSessionManager::MakeExpand permission denied!");
1897         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1898     }
1899     if (screenId.empty() || startPoint.empty() || screenId.size() != startPoint.size()) {
1900         WLOGFE("create expand fail, screenId size:%{public}ud,startPoint size:%{public}ud",
1901             static_cast<uint32_t>(screenId.size()), static_cast<uint32_t>(startPoint.size()));
1902         return DMError::DM_ERROR_INVALID_PARAM;
1903     }
1904     std::map<ScreenId, Point> pointsMap;
1905     uint32_t size = screenId.size();
1906     for (uint32_t i = 0; i < size; i++) {
1907         if (pointsMap.find(screenId[i]) != pointsMap.end()) {
1908             continue;
1909         }
1910         pointsMap[screenId[i]] = startPoint[i];
1911     }
1912     ScreenId defaultScreenId = GetDefaultScreenId();
1913     auto allExpandScreenIds = GetAllValidScreenIds(screenId);
1914     auto iter = std::find(allExpandScreenIds.begin(), allExpandScreenIds.end(), defaultScreenId);
1915     if (iter != allExpandScreenIds.end()) {
1916         allExpandScreenIds.erase(iter);
1917     }
1918     if (allExpandScreenIds.empty()) {
1919         WLOGFE("allExpandScreenIds is empty. make expand failed.");
1920         return DMError::DM_ERROR_NULLPTR;
1921     }
1922     std::shared_ptr<RSDisplayNode> rsDisplayNode;
1923     std::vector<Point> points;
1924     for (uint32_t i = 0; i < allExpandScreenIds.size(); i++) {
1925         rsDisplayNode = GetRSDisplayNodeByScreenId(allExpandScreenIds[i]);
1926         points.emplace_back(pointsMap[allExpandScreenIds[i]]);
1927         if (rsDisplayNode != nullptr) {
1928             rsDisplayNode->SetDisplayOffset(pointsMap[allExpandScreenIds[i]].posX_,
1929                 pointsMap[allExpandScreenIds[i]].posY_);
1930         }
1931     }
1932     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeExpand");
1933     if (!OnMakeExpand(allExpandScreenIds, points)) {
1934         return DMError::DM_ERROR_NULLPTR;
1935     }
1936     auto screen = GetScreenSession(allExpandScreenIds[0]);
1937     if (screen == nullptr || GetAbstractScreenGroup(screen->groupSmsId_) == nullptr) {
1938         return DMError::DM_ERROR_NULLPTR;
1939     }
1940     screenGroupId = screen->groupSmsId_;
1941     return DMError::DM_OK;
1942 }
1943 
OnMakeExpand(std::vector<ScreenId> screenId,std::vector<Point> startPoint)1944 bool ScreenSessionManager::OnMakeExpand(std::vector<ScreenId> screenId, std::vector<Point> startPoint)
1945 {
1946     ScreenId defaultScreenId = GetDefaultScreenId();
1947     WLOGI("OnMakeExpand, defaultScreenId:%{public}" PRIu64"", defaultScreenId);
1948     auto defaultScreen = GetScreenSession(defaultScreenId);
1949     if (defaultScreen == nullptr) {
1950         WLOGFI("OnMakeExpand failed.");
1951         return false;
1952     }
1953     auto group = GetAbstractScreenGroup(defaultScreen->groupSmsId_);
1954     if (group == nullptr) {
1955         group = AddToGroupLocked(defaultScreen);
1956         if (group == nullptr) {
1957             WLOGFE("group is nullptr");
1958             return false;
1959         }
1960         NotifyScreenGroupChanged(defaultScreen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
1961     }
1962     bool filterExpandScreen = group->combination_ == ScreenCombination::SCREEN_EXPAND;
1963     ChangeScreenGroup(group, screenId, startPoint, filterExpandScreen, ScreenCombination::SCREEN_EXPAND);
1964     WLOGFI("OnMakeExpand success");
1965     return true;
1966 }
1967 
StopExpand(const std::vector<ScreenId> & expandScreenIds)1968 DMError ScreenSessionManager::StopExpand(const std::vector<ScreenId>& expandScreenIds)
1969 {
1970     if (!SessionPermission::IsSystemCalling()) {
1971         WLOGFE("StopExpand permission denied!");
1972         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1973     }
1974     auto allExpandScreenIds = GetAllValidScreenIds(expandScreenIds);
1975     if (allExpandScreenIds.empty()) {
1976         WLOGFI("SCB: StopExpand done. screens' size:%{public}u", static_cast<uint32_t>(allExpandScreenIds.size()));
1977         return DMError::DM_OK;
1978     }
1979 
1980     DMError ret = StopScreens(allExpandScreenIds, ScreenCombination::SCREEN_EXPAND);
1981     if (ret != DMError::DM_OK) {
1982         WLOGFE("SCB: StopExpand stop expand failed.");
1983         return ret;
1984     }
1985 
1986     return DMError::DM_OK;
1987 }
1988 
ConvertToRsScreenId(ScreenId smsScreenId,ScreenId & rsScreenId) const1989 bool ScreenSessionManager::ScreenIdManager::ConvertToRsScreenId(ScreenId smsScreenId, ScreenId& rsScreenId) const
1990 {
1991     std::shared_lock lock(screenIdMapMutex_);
1992     auto iter = sms2RsScreenIdMap_.find(smsScreenId);
1993     if (iter == sms2RsScreenIdMap_.end()) {
1994         return false;
1995     }
1996     rsScreenId = iter->second;
1997     return true;
1998 }
1999 
ConvertToRsScreenId(ScreenId screenId) const2000 ScreenId ScreenSessionManager::ScreenIdManager::ConvertToRsScreenId(ScreenId screenId) const
2001 {
2002     ScreenId rsScreenId = SCREEN_ID_INVALID;
2003     ConvertToRsScreenId(screenId, rsScreenId);
2004     return rsScreenId;
2005 }
2006 
ConvertToSmsScreenId(ScreenId rsScreenId) const2007 ScreenId ScreenSessionManager::ScreenIdManager::ConvertToSmsScreenId(ScreenId rsScreenId) const
2008 {
2009     ScreenId smsScreenId = SCREEN_ID_INVALID;
2010     ConvertToSmsScreenId(rsScreenId, smsScreenId);
2011     return smsScreenId;
2012 }
2013 
ConvertToSmsScreenId(ScreenId rsScreenId,ScreenId & smsScreenId) const2014 bool ScreenSessionManager::ScreenIdManager::ConvertToSmsScreenId(ScreenId rsScreenId, ScreenId& smsScreenId) const
2015 {
2016     std::shared_lock lock(screenIdMapMutex_);
2017     auto iter = rs2SmsScreenIdMap_.find(rsScreenId);
2018     if (iter == rs2SmsScreenIdMap_.end()) {
2019         return false;
2020     }
2021     smsScreenId = iter->second;
2022     return true;
2023 }
2024 
CreateAndGetNewScreenId(ScreenId rsScreenId)2025 ScreenId ScreenSessionManager::ScreenIdManager::CreateAndGetNewScreenId(ScreenId rsScreenId)
2026 {
2027     std::unique_lock lock(screenIdMapMutex_);
2028     ScreenId smsScreenId = smsScreenCount_++;
2029     WLOGFI("SCB: ScreenSessionManager::CreateAndGetNewScreenId screenId: %{public}" PRIu64"", smsScreenId);
2030     if (sms2RsScreenIdMap_.find(smsScreenId) != sms2RsScreenIdMap_.end()) {
2031         WLOGFW("SCB: ScreenSessionManager::CreateAndGetNewScreenId screenId: %{public}" PRIu64" exit", smsScreenId);
2032     }
2033     sms2RsScreenIdMap_[smsScreenId] = rsScreenId;
2034     if (rsScreenId == SCREEN_ID_INVALID) {
2035         return smsScreenId;
2036     }
2037     if (rs2SmsScreenIdMap_.find(rsScreenId) != rs2SmsScreenIdMap_.end()) {
2038         WLOGFW("SCB: ScreenSessionManager::CreateAndGetNewScreenId rsScreenId: %{public}" PRIu64" exit", rsScreenId);
2039     }
2040     rs2SmsScreenIdMap_[rsScreenId] = smsScreenId;
2041     return smsScreenId;
2042 }
2043 
UpdateScreenId(ScreenId rsScreenId,ScreenId smsScreenId)2044 void ScreenSessionManager::ScreenIdManager::UpdateScreenId(ScreenId rsScreenId, ScreenId smsScreenId)
2045 {
2046     std::unique_lock lock(screenIdMapMutex_);
2047     rs2SmsScreenIdMap_[rsScreenId] = smsScreenId;
2048     sms2RsScreenIdMap_[smsScreenId] = rsScreenId;
2049 }
2050 
DeleteScreenId(ScreenId smsScreenId)2051 bool ScreenSessionManager::ScreenIdManager::DeleteScreenId(ScreenId smsScreenId)
2052 {
2053     std::unique_lock lock(screenIdMapMutex_);
2054     auto iter = sms2RsScreenIdMap_.find(smsScreenId);
2055     if (iter == sms2RsScreenIdMap_.end()) {
2056         return false;
2057     }
2058     ScreenId rsScreenId = iter->second;
2059     sms2RsScreenIdMap_.erase(smsScreenId);
2060     rs2SmsScreenIdMap_.erase(rsScreenId);
2061     return true;
2062 }
2063 
HasRsScreenId(ScreenId smsScreenId) const2064 bool ScreenSessionManager::ScreenIdManager::HasRsScreenId(ScreenId smsScreenId) const
2065 {
2066     std::shared_lock lock(screenIdMapMutex_);
2067     return rs2SmsScreenIdMap_.find(smsScreenId) != rs2SmsScreenIdMap_.end();
2068 }
2069 
InitVirtualScreen(ScreenId smsScreenId,ScreenId rsId,VirtualScreenOption option)2070 sptr<ScreenSession> ScreenSessionManager::InitVirtualScreen(ScreenId smsScreenId, ScreenId rsId,
2071     VirtualScreenOption option)
2072 {
2073     WLOGFI("SCB: ScreenSessionManager::InitVirtualScreen: Enter");
2074     sptr<ScreenSession> screenSession =
2075         new(std::nothrow) ScreenSession(option.name_, smsScreenId, rsId, GetDefaultScreenId());
2076     sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
2077     if (screenSession == nullptr || info == nullptr) {
2078         WLOGFI("SCB: ScreenSessionManager::InitVirtualScreen: new screenSession or info failed");
2079         screenIdManager_.DeleteScreenId(smsScreenId);
2080         rsInterface_.RemoveVirtualScreen(rsId);
2081         return nullptr;
2082     }
2083     info->width_ = option.width_;
2084     info->height_ = option.height_;
2085     auto defaultScreen = GetScreenSession(GetDefaultScreenId());
2086     if (defaultScreen != nullptr && defaultScreen->GetActiveScreenMode() != nullptr) {
2087         info->refreshRate_ = defaultScreen->GetActiveScreenMode()->refreshRate_;
2088     }
2089     screenSession->modes_.emplace_back(info);
2090     screenSession->activeIdx_ = 0;
2091     screenSession->SetScreenType(ScreenType::VIRTUAL);
2092     screenSession->SetVirtualPixelRatio(option.density_);
2093     screenSession->SetDisplayBoundary(RectF(0, 0, option.width_, option.height_), 0);
2094     screenSession->RegisterScreenChangeListener(this);
2095     return screenSession;
2096 }
2097 
InitAbstractScreenModesInfo(sptr<ScreenSession> & screenSession)2098 bool ScreenSessionManager::InitAbstractScreenModesInfo(sptr<ScreenSession>& screenSession)
2099 {
2100     std::vector<RSScreenModeInfo> allModes = rsInterface_.GetScreenSupportedModes(
2101         screenIdManager_.ConvertToRsScreenId(screenSession->screenId_));
2102     if (allModes.size() == 0) {
2103         WLOGE("SCB: allModes.size() == 0, screenId=%{public}" PRIu64"", screenSession->rsId_);
2104         return false;
2105     }
2106     for (const RSScreenModeInfo& rsScreenModeInfo : allModes) {
2107         sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
2108         if (info == nullptr) {
2109             WLOGFE("SCB: ScreenSessionManager::InitAbstractScreenModesInfo:create SupportedScreenModes failed");
2110             return false;
2111         }
2112         info->id_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenModeId());
2113         info->width_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenWidth());
2114         info->height_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenHeight());
2115         info->refreshRate_ = rsScreenModeInfo.GetScreenRefreshRate();
2116         screenSession->modes_.push_back(info);
2117         WLOGI("SCB: fill screen idx:%{public}d w/h:%{public}d/%{public}d",
2118             rsScreenModeInfo.GetScreenModeId(), info->width_, info->height_);
2119     }
2120     int32_t activeModeId = rsInterface_.GetScreenActiveMode(screenSession->rsId_).GetScreenModeId();
2121     WLOGI("SCB: ScreenSessionManager::InitAbstractScreenModesInfo: fill screen activeModeId:%{public}d", activeModeId);
2122     if (static_cast<std::size_t>(activeModeId) >= allModes.size()) {
2123         WLOGE("SCB: activeModeId exceed, screenId=%{public}" PRIu64", activeModeId:%{public}d/%{public}ud",
2124             screenSession->rsId_, activeModeId, static_cast<uint32_t>(allModes.size()));
2125         return false;
2126     }
2127     screenSession->activeIdx_ = activeModeId;
2128     return true;
2129 }
2130 
InitAndGetScreen(ScreenId rsScreenId)2131 sptr<ScreenSession> ScreenSessionManager::InitAndGetScreen(ScreenId rsScreenId)
2132 {
2133     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2134     ScreenId smsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsScreenId);
2135     RSScreenCapability screenCapability = rsInterface_.GetScreenCapability(rsScreenId);
2136     WLOGFD("SCB: Screen name is %{public}s, phyWidth is %{public}u, phyHeight is %{public}u",
2137         screenCapability.GetName().c_str(), screenCapability.GetPhyWidth(), screenCapability.GetPhyHeight());
2138     sptr<ScreenSession> screenSession =
2139         new(std::nothrow) ScreenSession(screenCapability.GetName(), smsScreenId, rsScreenId, GetDefaultScreenId());
2140     if (screenSession == nullptr) {
2141         WLOGFE("SCB: ScreenSessionManager::InitAndGetScreen: screenSession == nullptr.");
2142         screenIdManager_.DeleteScreenId(smsScreenId);
2143         return nullptr;
2144     }
2145     if (!InitAbstractScreenModesInfo(screenSession)) {
2146         screenIdManager_.DeleteScreenId(smsScreenId);
2147         WLOGFE("SCB: ScreenSessionManager::InitAndGetScreen: InitAndGetScreen failed.");
2148         return nullptr;
2149     }
2150     WLOGI("SCB: InitAndGetScreen: screenSessionMap_ add screenId=%{public}" PRIu64"", smsScreenId);
2151     screenSessionMap_.insert(std::make_pair(smsScreenId, screenSession));
2152     return screenSession;
2153 }
2154 
AddToGroupLocked(sptr<ScreenSession> newScreen)2155 sptr<ScreenSessionGroup> ScreenSessionManager::AddToGroupLocked(sptr<ScreenSession> newScreen)
2156 {
2157     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2158     sptr<ScreenSessionGroup> res;
2159     if (smsScreenGroupMap_.empty()) {
2160         WLOGI("connect the first screen");
2161         res = AddAsFirstScreenLocked(newScreen);
2162     } else {
2163         res = AddAsSuccedentScreenLocked(newScreen);
2164     }
2165     return res;
2166 }
2167 
AddAsFirstScreenLocked(sptr<ScreenSession> newScreen)2168 sptr<ScreenSessionGroup> ScreenSessionManager::AddAsFirstScreenLocked(sptr<ScreenSession> newScreen)
2169 {
2170     ScreenId smsGroupScreenId(1);
2171     std::ostringstream buffer;
2172     buffer<<"ScreenGroup_"<<smsGroupScreenId;
2173     std::string name = buffer.str();
2174     // default ScreenCombination is mirror
2175     isExpandCombination_ = system::GetParameter("persist.display.expand.enabled", "0") == "1";
2176     sptr<ScreenSessionGroup> screenGroup;
2177     if (isExpandCombination_) {
2178         screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
2179             SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_EXPAND);
2180         newScreen->SetScreenCombination(ScreenCombination::SCREEN_EXPAND);
2181     } else {
2182         screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
2183             SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_MIRROR);
2184         newScreen->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
2185     }
2186     if (screenGroup == nullptr) {
2187         WLOGE("new ScreenSessionGroup failed");
2188         screenIdManager_.DeleteScreenId(smsGroupScreenId);
2189         return nullptr;
2190     }
2191     screenGroup->groupSmsId_ = 1;
2192     Point point;
2193     if (!screenGroup->AddChild(newScreen, point, GetScreenSession(GetDefaultScreenId()))) {
2194         WLOGE("fail to add screen to group. screen=%{public}" PRIu64"", newScreen->screenId_);
2195         screenIdManager_.DeleteScreenId(smsGroupScreenId);
2196         return nullptr;
2197     }
2198     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2199     auto iter = smsScreenGroupMap_.find(smsGroupScreenId);
2200     if (iter != smsScreenGroupMap_.end()) {
2201         WLOGE("group screen existed. id=%{public}" PRIu64"", smsGroupScreenId);
2202         smsScreenGroupMap_.erase(iter);
2203     }
2204     smsScreenGroupMap_.insert(std::make_pair(smsGroupScreenId, screenGroup));
2205     screenSessionMap_.insert(std::make_pair(smsGroupScreenId, screenGroup));
2206     screenGroup->mirrorScreenId_ = newScreen->screenId_;
2207     WLOGI("connect new group screen, screenId: %{public}" PRIu64", screenGroupId: %{public}" PRIu64", "
2208         "combination:%{public}u", newScreen->screenId_, smsGroupScreenId,
2209         newScreen->GetScreenProperty().GetScreenType());
2210     return screenGroup;
2211 }
2212 
AddAsSuccedentScreenLocked(sptr<ScreenSession> newScreen)2213 sptr<ScreenSessionGroup> ScreenSessionManager::AddAsSuccedentScreenLocked(sptr<ScreenSession> newScreen)
2214 {
2215     ScreenId defaultScreenId = GetDefaultScreenId();
2216     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2217     auto iter = screenSessionMap_.find(defaultScreenId);
2218     if (iter == screenSessionMap_.end()) {
2219         WLOGE("AddAsSuccedentScreenLocked. defaultScreenId:%{public}" PRIu64" is not in screenSessionMap_.",
2220             defaultScreenId);
2221         return nullptr;
2222     }
2223     auto screen = iter->second;
2224     auto screenGroupIter = smsScreenGroupMap_.find(screen->groupSmsId_);
2225     if (screenGroupIter == smsScreenGroupMap_.end()) {
2226         WLOGE("AddAsSuccedentScreenLocked. groupSmsId:%{public}" PRIu64" is not in smsScreenGroupMap_.",
2227             screen->groupSmsId_);
2228         return nullptr;
2229     }
2230     auto screenGroup = screenGroupIter->second;
2231     Point point;
2232     if (screenGroup->combination_ == ScreenCombination::SCREEN_EXPAND) {
2233         point = {screen->GetActiveScreenMode()->width_, 0};
2234     }
2235     screenGroup->AddChild(newScreen, point, screen);
2236     return screenGroup;
2237 }
2238 
RemoveFromGroupLocked(sptr<ScreenSession> screen)2239 sptr<ScreenSessionGroup> ScreenSessionManager::RemoveFromGroupLocked(sptr<ScreenSession> screen)
2240 {
2241     WLOGI("RemoveFromGroupLocked.");
2242     auto groupSmsId = screen->groupSmsId_;
2243     sptr<ScreenSessionGroup> screenGroup = GetAbstractScreenGroup(groupSmsId);
2244     if (!screenGroup) {
2245         WLOGE("RemoveFromGroupLocked. groupSmsId:%{public}" PRIu64"is not in smsScreenGroupMap_.", groupSmsId);
2246         return nullptr;
2247     }
2248     if (!RemoveChildFromGroup(screen, screenGroup)) {
2249         return nullptr;
2250     }
2251     return screenGroup;
2252 }
2253 
RemoveChildFromGroup(sptr<ScreenSession> screen,sptr<ScreenSessionGroup> screenGroup)2254 bool ScreenSessionManager::RemoveChildFromGroup(sptr<ScreenSession> screen, sptr<ScreenSessionGroup> screenGroup)
2255 {
2256     bool res = screenGroup->RemoveChild(screen);
2257     if (!res) {
2258         WLOGE("RemoveFromGroupLocked. remove screen:%{public}" PRIu64" failed from screenGroup:%{public}" PRIu64".",
2259               screen->screenId_, screen->groupSmsId_);
2260         return false;
2261     }
2262     if (screenGroup->GetChildCount() == 0) {
2263         // Group removed, need to do something.
2264         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2265         smsScreenGroupMap_.erase(screenGroup->screenId_);
2266         screenSessionMap_.erase(screenGroup->screenId_);
2267         WLOGE("SCB: RemoveFromGroupLocked. screenSessionMap_ remove screen:%{public}" PRIu64"", screenGroup->screenId_);
2268     }
2269     return true;
2270 }
2271 
SetMirror(ScreenId screenId,std::vector<ScreenId> screens)2272 DMError ScreenSessionManager::SetMirror(ScreenId screenId, std::vector<ScreenId> screens)
2273 {
2274     WLOGI("SetMirror, screenId:%{public}" PRIu64"", screenId);
2275     sptr<ScreenSession> screen = GetScreenSession(screenId);
2276     if (screen == nullptr || screen->GetScreenProperty().GetScreenType() != ScreenType::REAL) {
2277         WLOGFE("screen is nullptr, or screenType is not real.");
2278         return DMError::DM_ERROR_NULLPTR;
2279     }
2280     screen->groupSmsId_ = 1;
2281     auto group = GetAbstractScreenGroup(screen->groupSmsId_);
2282     if (group == nullptr) {
2283         group = AddToGroupLocked(screen);
2284         if (group == nullptr) {
2285             WLOGFE("group is nullptr");
2286             return DMError::DM_ERROR_NULLPTR;
2287         }
2288         NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
2289     }
2290     Point point;
2291     std::vector<Point> startPoints;
2292     startPoints.insert(startPoints.begin(), screens.size(), point);
2293     bool filterMirroredScreen =
2294         group->combination_ == ScreenCombination::SCREEN_MIRROR && group->mirrorScreenId_ == screen->screenId_;
2295     group->mirrorScreenId_ = screen->screenId_;
2296     ChangeScreenGroup(group, screens, startPoints, filterMirroredScreen, ScreenCombination::SCREEN_MIRROR);
2297     WLOGFI("SetMirror success");
2298     return DMError::DM_OK;
2299 }
2300 
GetAbstractScreenGroup(ScreenId smsScreenId)2301 sptr<ScreenSessionGroup> ScreenSessionManager::GetAbstractScreenGroup(ScreenId smsScreenId)
2302 {
2303     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2304     auto iter = smsScreenGroupMap_.find(smsScreenId);
2305     if (iter == smsScreenGroupMap_.end()) {
2306         WLOGE("did not find screen:%{public}" PRIu64"", smsScreenId);
2307         return nullptr;
2308     }
2309     return iter->second;
2310 }
2311 
CheckScreenInScreenGroup(sptr<ScreenSession> screen) const2312 bool ScreenSessionManager::CheckScreenInScreenGroup(sptr<ScreenSession> screen) const
2313 {
2314     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2315     auto groupSmsId = screen->groupSmsId_;
2316     auto iter = smsScreenGroupMap_.find(groupSmsId);
2317     if (iter == smsScreenGroupMap_.end()) {
2318         WLOGFE("groupSmsId:%{public}" PRIu64"is not in smsScreenGroupMap_.", groupSmsId);
2319         return false;
2320     }
2321     sptr<ScreenSessionGroup> screenGroup = iter->second;
2322     return screenGroup->HasChild(screen->screenId_);
2323 }
2324 
ChangeScreenGroup(sptr<ScreenSessionGroup> group,const std::vector<ScreenId> & screens,const std::vector<Point> & startPoints,bool filterScreen,ScreenCombination combination)2325 void ScreenSessionManager::ChangeScreenGroup(sptr<ScreenSessionGroup> group, const std::vector<ScreenId>& screens,
2326     const std::vector<Point>& startPoints, bool filterScreen, ScreenCombination combination)
2327 {
2328     std::map<ScreenId, bool> removeChildResMap;
2329     std::vector<ScreenId> addScreens;
2330     std::vector<Point> addChildPos;
2331     for (uint64_t i = 0; i != screens.size(); i++) {
2332         ScreenId screenId = screens[i];
2333         WLOGFI("ScreenId: %{public}" PRIu64"", screenId);
2334         auto screen = GetScreenSession(screenId);
2335         if (screen == nullptr) {
2336             WLOGFE("screen:%{public}" PRIu64" is nullptr", screenId);
2337             continue;
2338         }
2339         WLOGFI("Screen->groupSmsId_: %{public}" PRIu64"", screen->groupSmsId_);
2340         screen->groupSmsId_ = 1;
2341         if (filterScreen && screen->groupSmsId_ == group->screenId_ && group->HasChild(screen->screenId_)) {
2342             continue;
2343         }
2344         if (CheckScreenInScreenGroup(screen)) {
2345             NotifyDisplayDestroy(screenId);
2346         }
2347         auto originGroup = RemoveFromGroupLocked(screen);
2348         addChildPos.emplace_back(startPoints[i]);
2349         removeChildResMap[screenId] = originGroup != nullptr;
2350         addScreens.emplace_back(screenId);
2351     }
2352     group->combination_ = combination;
2353     AddScreenToGroup(group, addScreens, addChildPos, removeChildResMap);
2354 }
2355 
AddScreenToGroup(sptr<ScreenSessionGroup> group,const std::vector<ScreenId> & addScreens,const std::vector<Point> & addChildPos,std::map<ScreenId,bool> & removeChildResMap)2356 void ScreenSessionManager::AddScreenToGroup(sptr<ScreenSessionGroup> group,
2357     const std::vector<ScreenId>& addScreens, const std::vector<Point>& addChildPos,
2358     std::map<ScreenId, bool>& removeChildResMap)
2359 {
2360     std::vector<sptr<ScreenInfo>> addToGroup;
2361     std::vector<sptr<ScreenInfo>> removeFromGroup;
2362     std::vector<sptr<ScreenInfo>> changeGroup;
2363     for (uint64_t i = 0; i != addScreens.size(); i++) {
2364         ScreenId screenId = addScreens[i];
2365         sptr<ScreenSession> screen = GetScreenSession(screenId);
2366         if (screen == nullptr) {
2367             continue;
2368         }
2369         Point expandPoint = addChildPos[i];
2370         WLOGFI("screenId: %{public}" PRIu64", Point: %{public}d, %{public}d",
2371             screen->screenId_, expandPoint.posX_, expandPoint.posY_);
2372         bool addChildRes = group->AddChild(screen, expandPoint, GetScreenSession(GetDefaultScreenId()));
2373         if (removeChildResMap[screenId] && addChildRes) {
2374             changeGroup.emplace_back(screen->ConvertToScreenInfo());
2375             WLOGFD("changeGroup");
2376         } else if (removeChildResMap[screenId]) {
2377             WLOGFD("removeChild");
2378             removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
2379         } else if (addChildRes) {
2380             WLOGFD("AddChild");
2381             addToGroup.emplace_back(screen->ConvertToScreenInfo());
2382         } else {
2383             WLOGFD("default, AddChild failed");
2384         }
2385         NotifyDisplayCreate(screen->ConvertToDisplayInfo());
2386     }
2387 
2388     NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
2389     NotifyScreenGroupChanged(changeGroup, ScreenGroupChangeEvent::CHANGE_GROUP);
2390     NotifyScreenGroupChanged(addToGroup, ScreenGroupChangeEvent::ADD_TO_GROUP);
2391 }
2392 
RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)2393 void ScreenSessionManager::RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)
2394 {
2395     WLOGFI("SCB: ScreenSessionManager::RemoveVirtualScreenFromGroup enter!");
2396     if (!SessionPermission::IsSystemCalling()) {
2397         WLOGFE("SCB: ScreenSessionManager::RemoveVirtualScreenFromGroup permission denied!");
2398         return;
2399     }
2400     if (screens.empty()) {
2401         return;
2402     }
2403     std::vector<sptr<ScreenInfo>> removeFromGroup;
2404     for (ScreenId screenId : screens) {
2405         auto screen = GetScreenSession(screenId);
2406         if (screen == nullptr || screen->GetScreenProperty().GetScreenType() != ScreenType::VIRTUAL) {
2407             continue;
2408         }
2409         auto originGroup = GetAbstractScreenGroup(screen->groupSmsId_);
2410         if (originGroup == nullptr) {
2411             continue;
2412         }
2413         if (!originGroup->HasChild(screenId)) {
2414             continue;
2415         }
2416         RemoveFromGroupLocked(screen);
2417         removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
2418     }
2419     NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
2420 }
2421 
GetRSDisplayNodeByScreenId(ScreenId smsScreenId) const2422 const std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetRSDisplayNodeByScreenId(ScreenId smsScreenId) const
2423 {
2424     static std::shared_ptr<RSDisplayNode> notFound = nullptr;
2425     sptr<ScreenSession> screen = GetScreenSession(smsScreenId);
2426     if (screen == nullptr) {
2427         WLOGFE("SCB: ScreenSessionManager::GetRSDisplayNodeByScreenId screen == nullptr!");
2428         return notFound;
2429     }
2430     if (screen->GetDisplayNode() == nullptr) {
2431         WLOGFE("SCB: ScreenSessionManager::GetRSDisplayNodeByScreenId displayNode_ == nullptr!");
2432         return notFound;
2433     }
2434     WLOGI("GetRSDisplayNodeByScreenId: screen: %{public}" PRIu64", nodeId: %{public}" PRIu64" ",
2435         screen->screenId_, screen->GetDisplayNode()->GetId());
2436     return screen->GetDisplayNode();
2437 }
2438 
GetScreenSnapshot(DisplayId displayId)2439 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetScreenSnapshot(DisplayId displayId)
2440 {
2441     ScreenId screenId = SCREEN_ID_INVALID;
2442     std::shared_ptr<RSDisplayNode> displayNode = nullptr;
2443     {
2444         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2445         for (auto sessionIt : screenSessionMap_) {
2446             auto screenSession = sessionIt.second;
2447             if (screenSession == nullptr) {
2448                 WLOGFE("SCB: ScreenSessionManager::GetScreenSnapshot screenSession is nullptr!");
2449                 continue;
2450             }
2451             sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
2452             if (displayInfo == nullptr) {
2453                 WLOGFE("SCB: ScreenSessionManager::GetScreenSnapshot displayInfo is nullptr!");
2454                 continue;
2455             }
2456             WLOGI("SCB: GetScreenSnapshot: displayId %{public}" PRIu64"", displayInfo->GetDisplayId());
2457             if (displayId == displayInfo->GetDisplayId()) {
2458                 displayNode = screenSession->GetDisplayNode();
2459                 screenId = sessionIt.first;
2460                 break;
2461             }
2462         }
2463     }
2464     if (screenId == SCREEN_ID_INVALID) {
2465         WLOGFE("SCB: ScreenSessionManager::GetScreenSnapshot screenId == SCREEN_ID_INVALID!");
2466         return nullptr;
2467     }
2468     if (displayNode == nullptr) {
2469         WLOGFE("SCB: ScreenSessionManager::GetScreenSnapshot displayNode == nullptr!");
2470         return nullptr;
2471     }
2472 
2473     std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
2474     bool ret = rsInterface_.TakeSurfaceCapture(displayNode, callback);
2475     if (!ret) {
2476         WLOGFE("SCB: ScreenSessionManager::GetScreenSnapshot TakeSurfaceCapture failed");
2477         return nullptr;
2478     }
2479     std::shared_ptr<Media::PixelMap> screenshot = callback->GetResult(2000); // wait for <= 2000ms
2480     if (screenshot == nullptr) {
2481         WLOGFE("SCB: Failed to get pixelmap from RS, return nullptr!");
2482     }
2483 
2484     // notify dm listener
2485     sptr<ScreenshotInfo> snapshotInfo = new ScreenshotInfo();
2486     snapshotInfo->SetTrigger(SysCapUtil::GetClientName());
2487     snapshotInfo->SetDisplayId(displayId);
2488     OnScreenshot(snapshotInfo);
2489 
2490     return screenshot;
2491 }
2492 
GetDisplaySnapshot(DisplayId displayId,DmErrorCode * errorCode)2493 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetDisplaySnapshot(DisplayId displayId, DmErrorCode* errorCode)
2494 {
2495     WLOGFI("SCB: ScreenSessionManager::GetDisplaySnapshot ENTER!");
2496 
2497     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
2498         WLOGFW("SCB: ScreenSessionManager::GetDisplaySnapshot was disabled by edm!");
2499         return nullptr;
2500     }
2501     if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
2502         SessionPermission::IsShellCall()) {
2503         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplaySnapshot(%" PRIu64")", displayId);
2504         auto res = GetScreenSnapshot(displayId);
2505         if (res != nullptr) {
2506             NotifyScreenshot(displayId);
2507             CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "ohos.screenshot");
2508         }
2509         return res;
2510     } else if (errorCode) {
2511         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
2512     }
2513     return nullptr;
2514 }
2515 
OnRemoteDied(const sptr<IRemoteObject> & agent)2516 bool ScreenSessionManager::OnRemoteDied(const sptr<IRemoteObject>& agent)
2517 {
2518     if (agent == nullptr) {
2519         return false;
2520     }
2521     auto agentIter = screenAgentMap_.find(agent);
2522     if (agentIter != screenAgentMap_.end()) {
2523         while (screenAgentMap_[agent].size() > 0) {
2524             auto diedId = screenAgentMap_[agent][0];
2525             WLOGI("destroy screenId in OnRemoteDied: %{public}" PRIu64"", diedId);
2526             DMError res = DestroyVirtualScreen(diedId);
2527             if (res != DMError::DM_OK) {
2528                 WLOGE("destroy failed in OnRemoteDied: %{public}" PRIu64"", diedId);
2529             }
2530         }
2531         screenAgentMap_.erase(agent);
2532     }
2533     return true;
2534 }
2535 
GetAllValidScreenIds(const std::vector<ScreenId> & screenIds) const2536 std::vector<ScreenId> ScreenSessionManager::GetAllValidScreenIds(const std::vector<ScreenId>& screenIds) const
2537 {
2538     std::vector<ScreenId> validScreenIds;
2539     for (ScreenId screenId : screenIds) {
2540         auto screenIdIter = std::find(validScreenIds.begin(), validScreenIds.end(), screenId);
2541         if (screenIdIter != validScreenIds.end()) {
2542             continue;
2543         }
2544         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2545         auto iter = screenSessionMap_.find(screenId);
2546         if (iter != screenSessionMap_.end() && iter->second != nullptr &&
2547                 iter->second->GetScreenProperty().GetScreenType() != ScreenType::UNDEFINED) {
2548             validScreenIds.emplace_back(screenId);
2549         }
2550     }
2551     return validScreenIds;
2552 }
2553 
GetScreenGroupInfoById(ScreenId screenId)2554 sptr<ScreenGroupInfo> ScreenSessionManager::GetScreenGroupInfoById(ScreenId screenId)
2555 {
2556     if (!SessionPermission::IsSystemCalling()) {
2557         WLOGFE("SCB: ScreenSessionManager::GetScreenGroupInfoById permission denied!");
2558         return nullptr;
2559     }
2560     auto screenSessionGroup = GetAbstractScreenGroup(screenId);
2561     if (screenSessionGroup == nullptr) {
2562         WLOGE("SCB: GetScreenGroupInfoById cannot find screenGroupInfo: %{public}" PRIu64"", screenId);
2563         return nullptr;
2564     }
2565     return screenSessionGroup->ConvertToScreenGroupInfo();
2566 }
2567 
NotifyScreenConnected(sptr<ScreenInfo> screenInfo)2568 void ScreenSessionManager::NotifyScreenConnected(sptr<ScreenInfo> screenInfo)
2569 {
2570     if (screenInfo == nullptr) {
2571         WLOGFE("SCB: NotifyScreenConnected error, screenInfo is nullptr.");
2572         return;
2573     }
2574     auto task = [=] {
2575         WLOGFI("SCB: NotifyScreenConnected,  screenId:%{public}" PRIu64"", screenInfo->GetScreenId());
2576         OnScreenConnect(screenInfo);
2577     };
2578     taskScheduler_->PostAsyncTask(task, "NotifyScreenConnected");
2579 }
2580 
NotifyScreenDisconnected(ScreenId screenId)2581 void ScreenSessionManager::NotifyScreenDisconnected(ScreenId screenId)
2582 {
2583     auto task = [=] {
2584         WLOGFI("NotifyScreenDisconnected,  screenId:%{public}" PRIu64"", screenId);
2585         OnScreenDisconnect(screenId);
2586     };
2587     taskScheduler_->PostAsyncTask(task, "NotifyScreenDisconnected");
2588 }
2589 
NotifyDisplayCreate(sptr<DisplayInfo> displayInfo)2590 void ScreenSessionManager::NotifyDisplayCreate(sptr<DisplayInfo> displayInfo)
2591 {
2592     if (displayInfo == nullptr) {
2593         return;
2594     }
2595     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
2596     if (agents.empty()) {
2597         return;
2598     }
2599     WLOGFI("NotifyDisplayCreate");
2600     for (auto& agent : agents) {
2601         agent->OnDisplayCreate(displayInfo);
2602     }
2603 }
2604 
NotifyDisplayDestroy(DisplayId displayId)2605 void ScreenSessionManager::NotifyDisplayDestroy(DisplayId displayId)
2606 {
2607     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
2608     if (agents.empty()) {
2609         return;
2610     }
2611     WLOGFI("NotifyDisplayDestroy");
2612     for (auto& agent : agents) {
2613         agent->OnDisplayDestroy(displayId);
2614     }
2615 }
2616 
NotifyScreenGroupChanged(const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent event)2617 void ScreenSessionManager::NotifyScreenGroupChanged(
2618     const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent event)
2619 {
2620     if (screenInfo == nullptr) {
2621         WLOGFE("screenInfo is nullptr.");
2622         return;
2623     }
2624     std::string trigger = SysCapUtil::GetClientName();
2625     auto task = [=] {
2626         WLOGFI("SCB: screenId:%{public}" PRIu64", trigger:[%{public}s]", screenInfo->GetScreenId(), trigger.c_str());
2627         OnScreenGroupChange(trigger, screenInfo, event);
2628     };
2629     taskScheduler_->PostAsyncTask(task, "NotifyScreenGroupChanged:PID");
2630 }
2631 
NotifyScreenGroupChanged(const std::vector<sptr<ScreenInfo>> & screenInfo,ScreenGroupChangeEvent event)2632 void ScreenSessionManager::NotifyScreenGroupChanged(
2633     const std::vector<sptr<ScreenInfo>>& screenInfo, ScreenGroupChangeEvent event)
2634 {
2635     if (screenInfo.empty()) {
2636         return;
2637     }
2638     std::string trigger = SysCapUtil::GetClientName();
2639     auto task = [=] {
2640         WLOGFI("SCB: trigger:[%{public}s]", trigger.c_str());
2641         OnScreenGroupChange(trigger, screenInfo, event);
2642     };
2643     taskScheduler_->PostAsyncTask(task, "NotifyScreenGroupChanged");
2644 }
2645 
NotifyPrivateSessionStateChanged(bool hasPrivate)2646 void ScreenSessionManager::NotifyPrivateSessionStateChanged(bool hasPrivate)
2647 {
2648     if (hasPrivate == screenPrivacyStates) {
2649         WLOGFD("screen session state is not changed, return");
2650         return;
2651     }
2652     WLOGI("PrivateSession status : %{public}u", hasPrivate);
2653     screenPrivacyStates = hasPrivate;
2654     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::PRIVATE_WINDOW_LISTENER);
2655     if (agents.empty()) {
2656         return;
2657     }
2658     for (auto& agent : agents) {
2659         agent->NotifyPrivateWindowStateChanged(hasPrivate);
2660     }
2661 }
2662 
SetScreenPrivacyState(bool hasPrivate)2663 void ScreenSessionManager::SetScreenPrivacyState(bool hasPrivate)
2664 {
2665     WLOGFI("SetScreenPrivacyState enter, hasPrivate: %{public}d", hasPrivate);
2666     ScreenId id = GetDefaultScreenId();
2667     auto screenSession = GetScreenSession(id);
2668     if (screenSession == nullptr) {
2669         WLOGFE("can not get default screen now");
2670         return;
2671     }
2672     screenSession->SetPrivateSessionForeground(hasPrivate);
2673     NotifyPrivateSessionStateChanged(hasPrivate);
2674 }
2675 
HasPrivateWindow(DisplayId id,bool & hasPrivateWindow)2676 DMError ScreenSessionManager::HasPrivateWindow(DisplayId id, bool& hasPrivateWindow)
2677 {
2678     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2679         WLOGFE("SCB: ScreenSessionManager HasPrivateWindow permission denied!");
2680         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2681     }
2682     std::vector<ScreenId> screenIds = GetAllScreenIds();
2683     auto iter = std::find(screenIds.begin(), screenIds.end(), id);
2684     if (iter == screenIds.end()) {
2685         WLOGFE("invalid displayId");
2686         return DMError::DM_ERROR_INVALID_PARAM;
2687     }
2688     auto screenSession = GetScreenSession(id);
2689     if (screenSession == nullptr) {
2690         return DMError::DM_ERROR_NULLPTR;
2691     }
2692     hasPrivateWindow = screenSession->HasPrivateSessionForeground();
2693     WLOGFD("id: %{public}" PRIu64" has private window: %{public}u", id, static_cast<uint32_t>(hasPrivateWindow));
2694     return DMError::DM_OK;
2695 }
2696 
OnScreenGroupChange(const std::string & trigger,const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent groupEvent)2697 void ScreenSessionManager::OnScreenGroupChange(const std::string& trigger,
2698     const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent groupEvent)
2699 {
2700     if (screenInfo == nullptr) {
2701         return;
2702     }
2703     std::vector<sptr<ScreenInfo>> screenInfos;
2704     screenInfos.push_back(screenInfo);
2705     OnScreenGroupChange(trigger, screenInfos, groupEvent);
2706 }
2707 
OnScreenGroupChange(const std::string & trigger,const std::vector<sptr<ScreenInfo>> & screenInfos,ScreenGroupChangeEvent groupEvent)2708 void ScreenSessionManager::OnScreenGroupChange(const std::string& trigger,
2709     const std::vector<sptr<ScreenInfo>>& screenInfos, ScreenGroupChangeEvent groupEvent)
2710 {
2711     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
2712     std::vector<sptr<ScreenInfo>> infos;
2713     for (auto& screenInfo : screenInfos) {
2714         if (screenInfo != nullptr) {
2715             infos.emplace_back(screenInfo);
2716         }
2717     }
2718     if (agents.empty() || infos.empty()) {
2719         return;
2720     }
2721     for (auto& agent : agents) {
2722         agent->OnScreenGroupChange(trigger, infos, groupEvent);
2723     }
2724 }
2725 
OnScreenConnect(const sptr<ScreenInfo> screenInfo)2726 void ScreenSessionManager::OnScreenConnect(const sptr<ScreenInfo> screenInfo)
2727 {
2728     if (screenInfo == nullptr) {
2729         return;
2730     }
2731     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
2732     if (agents.empty()) {
2733         return;
2734     }
2735     WLOGFI("SCB: OnScreenConnect");
2736     for (auto& agent : agents) {
2737         agent->OnScreenConnect(screenInfo);
2738     }
2739 }
2740 
OnScreenDisconnect(ScreenId screenId)2741 void ScreenSessionManager::OnScreenDisconnect(ScreenId screenId)
2742 {
2743     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
2744     if (agents.empty()) {
2745         return;
2746     }
2747     WLOGFI("SCB: OnScreenDisconnect");
2748     for (auto& agent : agents) {
2749         agent->OnScreenDisconnect(screenId);
2750     }
2751 }
2752 
OnScreenshot(sptr<ScreenshotInfo> info)2753 void ScreenSessionManager::OnScreenshot(sptr<ScreenshotInfo> info)
2754 {
2755     if (info == nullptr) {
2756         return;
2757     }
2758     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREENSHOT_EVENT_LISTENER);
2759     if (agents.empty()) {
2760         return;
2761     }
2762     WLOGFI("SCB: onScreenshot");
2763     for (auto& agent : agents) {
2764         agent->OnScreenshot(info);
2765     }
2766 }
2767 
GetCutoutInfo(DisplayId displayId)2768 sptr<CutoutInfo> ScreenSessionManager::GetCutoutInfo(DisplayId displayId)
2769 {
2770     return screenCutoutController_ ? screenCutoutController_->GetScreenCutoutInfo(displayId) : nullptr;
2771 }
2772 
HasImmersiveWindow(bool & immersive)2773 DMError ScreenSessionManager::HasImmersiveWindow(bool& immersive)
2774 {
2775     if (!clientProxy_) {
2776         WLOGFE("clientProxy_ is null");
2777         return DMError::DM_ERROR_NULLPTR;
2778     }
2779     clientProxy_->OnImmersiveStateChanged(immersive);
2780     return DMError::DM_OK;
2781 }
2782 
SetDisplayBoundary(const sptr<ScreenSession> screenSession)2783 void ScreenSessionManager::SetDisplayBoundary(const sptr<ScreenSession> screenSession)
2784 {
2785     if (screenSession && screenCutoutController_) {
2786         RectF rect =
2787             screenCutoutController_->CalculateCurvedCompression(screenSession->GetScreenProperty());
2788         if (!rect.IsEmpty()) {
2789             screenSession->SetDisplayBoundary(rect, screenCutoutController_->GetOffsetY());
2790         }
2791     } else {
2792         WLOGFW("screenSession or screenCutoutController_ is null");
2793     }
2794 }
2795 
TransferTypeToString(ScreenType type) const2796 std::string ScreenSessionManager::TransferTypeToString(ScreenType type) const
2797 {
2798     std::string screenType;
2799     switch (type) {
2800         case ScreenType::REAL:
2801             screenType = "REAL";
2802             break;
2803         case ScreenType::VIRTUAL:
2804             screenType = "VIRTUAL";
2805             break;
2806         default:
2807             screenType = "UNDEFINED";
2808             break;
2809     }
2810     return screenType;
2811 }
2812 
DumpAllScreensInfo(std::string & dumpInfo)2813 void ScreenSessionManager::DumpAllScreensInfo(std::string& dumpInfo)
2814 {
2815     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
2816         WLOGFE("DumpAllScreensInfo permission denied!");
2817         return;
2818     }
2819     std::ostringstream oss;
2820     oss << "--------------------------------------Free Screen"
2821         << "--------------------------------------"
2822         << std::endl;
2823     oss << "ScreenName           Type     IsGroup DmsId RsId                 ActiveIdx VPR Rotation Orientation "
2824         << "RequestOrientation NodeId               "
2825         << std::endl;
2826     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2827     for (auto sessionIt : screenSessionMap_) {
2828         auto screenSession = sessionIt.second;
2829         if (screenSession == nullptr) {
2830             continue;
2831         }
2832         sptr<ScreenInfo> screenInfo = screenSession->ConvertToScreenInfo();
2833         if (screenInfo == nullptr) {
2834             continue;
2835         }
2836         std::string screenType = TransferTypeToString(screenInfo->GetType());
2837         NodeId nodeId = (screenSession->GetDisplayNode() == nullptr) ?
2838             SCREEN_ID_INVALID : screenSession->GetDisplayNode()->GetId();
2839         oss << std::left << std::setw(21) << screenInfo->GetName()
2840             << std::left << std::setw(9) << screenType
2841             << std::left << std::setw(8) << (screenSession->isScreenGroup_ ? "true" : "false")
2842             << std::left << std::setw(6) << screenSession->screenId_
2843             << std::left << std::setw(21) << screenSession->rsId_
2844             << std::left << std::setw(10) << screenSession->activeIdx_
2845             << std::left << std::setw(4) << screenInfo->GetVirtualPixelRatio()
2846             << std::left << std::setw(9) << static_cast<uint32_t>(screenInfo->GetRotation())
2847             << std::left << std::setw(12) << static_cast<uint32_t>(screenInfo->GetOrientation())
2848             << std::left << std::setw(19) << static_cast<uint32_t>(screenSession->GetScreenRequestedOrientation())
2849             << std::left << std::setw(21) << nodeId
2850             << std::endl;
2851     }
2852     oss << "total screen num: " << screenSessionMap_.size() << std::endl;
2853     dumpInfo.append(oss.str());
2854 }
2855 
DumpSpecialScreenInfo(ScreenId id,std::string & dumpInfo)2856 void ScreenSessionManager::DumpSpecialScreenInfo(ScreenId id, std::string& dumpInfo)
2857 {
2858     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
2859         WLOGFE("DumpSpecialScreenInfo permission denied!");
2860         return;
2861     }
2862     std::ostringstream oss;
2863     sptr<ScreenSession> session = GetScreenSession(id);
2864     if (!session) {
2865         WLOGFE("Get screen session failed.");
2866         oss << "This screen id is invalid.";
2867         dumpInfo.append(oss.str());
2868         return;
2869     }
2870     sptr<ScreenInfo> screenInfo = GetScreenInfoById(id);
2871     if (screenInfo == nullptr) {
2872         return;
2873     }
2874     std::string screenType = TransferTypeToString(screenInfo->GetType());
2875     NodeId nodeId = (session->GetDisplayNode() == nullptr) ?
2876         SCREEN_ID_INVALID : session->GetDisplayNode()->GetId();
2877     oss << "ScreenName: " << screenInfo->GetName() << std::endl;
2878     oss << "Type: " << screenType << std::endl;
2879     oss << "IsGroup: " << (session->isScreenGroup_ ? "true" : "false") << std::endl;
2880     oss << "DmsId: " << id << std::endl;
2881     oss << "RsId: " << session->rsId_ << std::endl;
2882     oss << "ActiveIdx: " << session->activeIdx_ << std::endl;
2883     oss << "VPR: " << screenInfo->GetVirtualPixelRatio() << std::endl;
2884     oss << "Rotation: " << static_cast<uint32_t>(screenInfo->GetRotation()) << std::endl;
2885     oss << "Orientation: " << static_cast<uint32_t>(screenInfo->GetOrientation()) << std::endl;
2886     oss << "RequestOrientation: " << static_cast<uint32_t>(session->GetScreenRequestedOrientation()) << std::endl;
2887     oss << "NodeId: " << nodeId << std::endl;
2888     dumpInfo.append(oss.str());
2889 }
2890 
2891 // --- Fold Screen ---
GetPhyScreenProperty(ScreenId screenId)2892 ScreenProperty ScreenSessionManager::GetPhyScreenProperty(ScreenId screenId)
2893 {
2894     std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
2895     ScreenProperty property;
2896     auto iter = phyScreenPropMap_.find(screenId);
2897     if (iter == phyScreenPropMap_.end()) {
2898         WLOGFD("Error found physic screen config with id: %{public}" PRIu64, screenId);
2899         return property;
2900     }
2901     return iter->second;
2902 }
2903 
SetFoldDisplayMode(const FoldDisplayMode displayMode)2904 void ScreenSessionManager::SetFoldDisplayMode(const FoldDisplayMode displayMode)
2905 {
2906     if (foldScreenController_ == nullptr) {
2907         WLOGFW("SetFoldDisplayMode foldScreenController_ is null");
2908         return;
2909     }
2910     if (!SessionPermission::IsSystemCalling()) {
2911         WLOGFE("SetFoldDisplayMode permission denied!");
2912         return;
2913     }
2914     foldScreenController_->SetDisplayMode(displayMode);
2915 }
2916 
SetFoldStatusLocked(bool locked)2917 void ScreenSessionManager::SetFoldStatusLocked(bool locked)
2918 {
2919     if (foldScreenController_ == nullptr) {
2920         WLOGFW("SetFoldStatusLocked foldScreenController_ is null");
2921         return;
2922     }
2923     if (!SessionPermission::IsSystemCalling()) {
2924         WLOGFE("SetFoldStatusLocked permission denied!");
2925         return;
2926     }
2927     foldScreenController_->LockDisplayStatus(locked);
2928 }
2929 
GetFoldDisplayMode()2930 FoldDisplayMode ScreenSessionManager::GetFoldDisplayMode()
2931 {
2932     if (foldScreenController_ == nullptr) {
2933         WLOGFD("GetFoldDisplayMode foldScreenController_ is null");
2934         return FoldDisplayMode::UNKNOWN;
2935     }
2936     return foldScreenController_->GetDisplayMode();
2937 }
2938 
IsFoldable()2939 bool ScreenSessionManager::IsFoldable()
2940 {
2941     if (foldScreenController_ == nullptr) {
2942         WLOGFD("foldScreenController_ is null");
2943         return false;
2944     }
2945     return foldScreenController_->IsFoldable();
2946 }
2947 
IsMultiScreenCollaboration()2948 bool ScreenSessionManager::IsMultiScreenCollaboration()
2949 {
2950     return isMultiScreenCollaboration_;
2951 }
2952 
GetFoldStatus()2953 FoldStatus ScreenSessionManager::GetFoldStatus()
2954 {
2955     if (foldScreenController_ == nullptr) {
2956         WLOGFD("foldScreenController_ is null");
2957         return FoldStatus::UNKNOWN;
2958     }
2959     return foldScreenController_->GetFoldStatus();
2960 }
2961 
GetCurrentFoldCreaseRegion()2962 sptr<FoldCreaseRegion> ScreenSessionManager::GetCurrentFoldCreaseRegion()
2963 {
2964     if (foldScreenController_ == nullptr) {
2965         WLOGFW("foldScreenController_ is null");
2966         return nullptr;
2967     }
2968     return foldScreenController_->GetCurrentFoldCreaseRegion();
2969 }
2970 
GetCurvedCompressionArea()2971 uint32_t ScreenSessionManager::GetCurvedCompressionArea()
2972 {
2973     return ScreenSceneConfig::GetCurvedCompressionAreaInLandscape();
2974 }
2975 
NotifyFoldStatusChanged(FoldStatus foldStatus)2976 void ScreenSessionManager::NotifyFoldStatusChanged(FoldStatus foldStatus)
2977 {
2978     WLOGI("NotifyFoldStatusChanged foldStatus:%{public}d", foldStatus);
2979     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER);
2980     if (agents.empty()) {
2981         return;
2982     }
2983     for (auto& agent: agents) {
2984         agent->NotifyFoldStatusChanged(foldStatus);
2985     }
2986 }
2987 
NotifyDisplayChangeInfoChanged(const sptr<DisplayChangeInfo> & info)2988 void ScreenSessionManager::NotifyDisplayChangeInfoChanged(const sptr<DisplayChangeInfo>& info)
2989 {
2990     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER);
2991     if (agents.empty()) {
2992         return;
2993     }
2994     for (auto& agent: agents) {
2995         agent->NotifyDisplayChangeInfoChanged(info);
2996     }
2997 }
2998 
NotifyDisplayModeChanged(FoldDisplayMode displayMode)2999 void ScreenSessionManager::NotifyDisplayModeChanged(FoldDisplayMode displayMode)
3000 {
3001     WLOGI("NotifyDisplayModeChanged displayMode:%{public}d", displayMode);
3002     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER);
3003     if (agents.empty()) {
3004         return;
3005     }
3006     for (auto& agent: agents) {
3007         agent->NotifyDisplayModeChanged(displayMode);
3008     }
3009 }
3010 
SetDisplayNodeScreenId(ScreenId screenId,ScreenId displayNodeScreenId)3011 void ScreenSessionManager::SetDisplayNodeScreenId(ScreenId screenId, ScreenId displayNodeScreenId)
3012 {
3013     WLOGFI("screenId: %{public}" PRIu64 " displayNodeScreenId: %{public}" PRIu64, screenId, displayNodeScreenId);
3014     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetDisplayNodeScreenId");
3015     if (!clientProxy_) {
3016         WLOGFD("clientProxy_ is null");
3017         return;
3018     }
3019     clientProxy_->SetDisplayNodeScreenId(screenId, displayNodeScreenId);
3020 }
3021 
OnPropertyChange(const ScreenProperty & newProperty,ScreenPropertyChangeReason reason,ScreenId screenId)3022 void ScreenSessionManager::OnPropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason,
3023     ScreenId screenId)
3024 {
3025     WLOGFI("screenId: %{public}" PRIu64 " reason: %{public}d", screenId, static_cast<int>(reason));
3026     if (!clientProxy_) {
3027         WLOGFD("clientProxy_ is null");
3028         return;
3029     }
3030     clientProxy_->OnPropertyChanged(screenId, newProperty, reason);
3031 }
3032 
OnPowerStatusChange(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)3033 void ScreenSessionManager::OnPowerStatusChange(DisplayPowerEvent event, EventStatus status,
3034     PowerStateChangeReason reason)
3035 {
3036     WLOGFI("event: %{public}d, status: %{public}d, reason: %{public}d", static_cast<int>(event),
3037         static_cast<int>(status), static_cast<int>(reason));
3038     if (!clientProxy_) {
3039         WLOGFD("clientProxy_ is null");
3040         return;
3041     }
3042     clientProxy_->OnPowerStatusChanged(event, status, reason);
3043 }
3044 
OnSensorRotationChange(float sensorRotation,ScreenId screenId)3045 void ScreenSessionManager::OnSensorRotationChange(float sensorRotation, ScreenId screenId)
3046 {
3047     WLOGFI("screenId: %{public}" PRIu64 " sensorRotation: %{public}f", screenId, sensorRotation);
3048     if (!clientProxy_) {
3049         WLOGFD("clientProxy_ is null");
3050         return;
3051     }
3052     clientProxy_->OnSensorRotationChanged(screenId, sensorRotation);
3053 }
3054 
OnScreenOrientationChange(float screenOrientation,ScreenId screenId)3055 void ScreenSessionManager::OnScreenOrientationChange(float screenOrientation, ScreenId screenId)
3056 {
3057     WLOGFI("screenId: %{public}" PRIu64 " screenOrientation: %{public}f", screenId, screenOrientation);
3058     if (!clientProxy_) {
3059         WLOGFD("clientProxy_ is null");
3060         return;
3061     }
3062     clientProxy_->OnScreenOrientationChanged(screenId, screenOrientation);
3063 }
3064 
OnScreenRotationLockedChange(bool isLocked,ScreenId screenId)3065 void ScreenSessionManager::OnScreenRotationLockedChange(bool isLocked, ScreenId screenId)
3066 {
3067     WLOGFI("screenId: %{public}" PRIu64 " isLocked: %{public}d", screenId, isLocked);
3068     if (!clientProxy_) {
3069         WLOGFD("clientProxy_ is null");
3070         return;
3071     }
3072     clientProxy_->OnScreenRotationLockedChanged(screenId, isLocked);
3073 }
3074 
SetClient(const sptr<IScreenSessionManagerClient> & client,int32_t userId)3075 void ScreenSessionManager::SetClient(const sptr<IScreenSessionManagerClient>& client, int32_t userId)
3076 {
3077     if (!client) {
3078         WLOGFE("client is null");
3079         return;
3080     }
3081     WLOGFI("SetClient userId= %{public}d", userId);
3082     MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, 0);
3083     clientProxy_ = client;
3084     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3085     for (const auto& iter : screenSessionMap_) {
3086         if (!iter.second) {
3087             continue;
3088         }
3089         // In the rotating state, after scb restarts, the screen information needs to be reset.
3090         float phyWidth = 0.0f;
3091         float phyHeight = 0.0f;
3092         bool isReset = true;
3093         if (foldScreenController_ != nullptr) {
3094             FoldDisplayMode displayMode = GetFoldDisplayMode();
3095             WLOGFI("fold screen with screenId = %{public}u", displayMode);
3096             if (displayMode == FoldDisplayMode::MAIN) {
3097                 auto phyBounds = GetPhyScreenProperty(SCREEN_ID_MAIN).GetPhyBounds();
3098                 phyWidth = phyBounds.rect_.width_;
3099                 phyHeight = phyBounds.rect_.height_;
3100             } else if (displayMode == FoldDisplayMode::FULL) {
3101                 auto phyBounds = GetPhyScreenProperty(SCREEN_ID_FULL).GetPhyBounds();
3102                 phyWidth = phyBounds.rect_.height_;
3103                 phyHeight = phyBounds.rect_.width_;
3104             } else {
3105                 isReset = false;
3106             }
3107         } else {
3108             auto remoteScreenMode = rsInterface_.GetScreenActiveMode(iter.first);
3109             phyWidth = remoteScreenMode.GetScreenWidth();
3110             phyHeight = remoteScreenMode.GetScreenHeight();
3111         }
3112         auto localRotation = iter.second->GetRotation();
3113         WLOGFI("phyWidth = :%{public}f, phyHeight = :%{public}f, localRotation = :%{public}u",
3114             phyWidth, phyHeight, localRotation);
3115         bool isModeChanged = localRotation != Rotation::ROTATION_0;
3116         if (isModeChanged && isReset) {
3117             WLOGFI("[WMSRecover]screen(id:%{public}" PRIu64 ") current mode is not default mode, reset it", iter.first);
3118             SetRotation(iter.first, Rotation::ROTATION_0, false);
3119             iter.second->SetDisplayBoundary(RectF(0, 0, phyWidth, phyHeight), 0);
3120         }
3121         clientProxy_->OnScreenConnectionChanged(iter.first, ScreenEvent::CONNECTED,
3122             iter.second->GetRSScreenId(), iter.second->GetName());
3123     }
3124 }
3125 
GetScreenProperty(ScreenId screenId)3126 ScreenProperty ScreenSessionManager::GetScreenProperty(ScreenId screenId)
3127 {
3128     auto screenSession = GetScreenSession(screenId);
3129     if (!screenSession) {
3130         WLOGFE("screenSession is null");
3131         return {};
3132     }
3133     return screenSession->GetScreenProperty();
3134 }
3135 
GetDisplayNode(ScreenId screenId)3136 std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetDisplayNode(ScreenId screenId)
3137 {
3138     auto screenSession = GetScreenSession(screenId);
3139     if (!screenSession) {
3140         WLOGFE("screenSession is null");
3141         return nullptr;
3142     }
3143     return screenSession->GetDisplayNode();
3144 }
3145 
ShowHelpInfo(std::string & dumpInfo)3146 void ScreenSessionManager::ShowHelpInfo(std::string& dumpInfo)
3147 {
3148     dumpInfo.append("Usage:\n")
3149         .append(" -h                             ")
3150         .append("|help text for the tool\n")
3151         .append(" -a                             ")
3152         .append("|dump all screen information in the system\n")
3153         .append(" -s {screen id}                 ")
3154         .append("|dump specified screen information\n")
3155         .append(" -f                             ")
3156         .append("|switch the screen to full display mode\n")
3157         .append(" -m                             ")
3158         .append("|switch the screen to main display mode\n")
3159         .append(" -l                             ")
3160         .append("|lock the screen display status\n")
3161         .append(" -u                             ")
3162         .append("|unlock the screen display status\n");
3163 }
3164 
ShowIllegalArgsInfo(std::string & dumpInfo)3165 void ScreenSessionManager::ShowIllegalArgsInfo(std::string& dumpInfo)
3166 {
3167     dumpInfo.append("The arguments are illegal and you can enter '-h' for help.");
3168 }
3169 
IsValidDigitString(const std::string & idStr) const3170 bool ScreenSessionManager::IsValidDigitString(const std::string& idStr) const
3171 {
3172     if (idStr.empty()) {
3173         return false;
3174     }
3175     for (char ch : idStr) {
3176         if ((ch >= '0' && ch <= '9')) {
3177             continue;
3178         }
3179         WLOGFE("invalid id");
3180         return false;
3181     }
3182     return true;
3183 }
3184 
DumpScreenInfo(const std::vector<std::string> & args,std::string & dumpInfo)3185 int ScreenSessionManager::DumpScreenInfo(const std::vector<std::string>& args, std::string& dumpInfo)
3186 {
3187     if (args.empty()) {
3188         return -1;
3189     }
3190     if (args.size() == 1 && args[0] == ARG_DUMP_ALL) { // 1: params num
3191         return DumpAllScreenInfo(dumpInfo);
3192     } else if (args[0] == ARG_DUMP_SCREEN && IsValidDigitString(args[1])) {
3193         ScreenId screenId = std::stoull(args[1]);
3194         return DumpSpecifiedScreenInfo(screenId, dumpInfo);
3195     } else {
3196         return -1;
3197     }
3198 }
3199 
DumpAllScreenInfo(std::string & dumpInfo)3200 int ScreenSessionManager::DumpAllScreenInfo(std::string& dumpInfo)
3201 {
3202     DumpAllScreensInfo(dumpInfo);
3203     return 0;
3204 }
3205 
DumpSpecifiedScreenInfo(ScreenId screenId,std::string & dumpInfo)3206 int ScreenSessionManager::DumpSpecifiedScreenInfo(ScreenId screenId, std::string& dumpInfo)
3207 {
3208     DumpSpecialScreenInfo(screenId, dumpInfo);
3209     return 0;
3210 }
3211 
Str16ToStr8(const std::u16string & str)3212 static std::string Str16ToStr8(const std::u16string& str)
3213 {
3214     if (str == DEFAULT_USTRING) {
3215         return DEFAULT_STRING;
3216     }
3217     std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert(DEFAULT_STRING);
3218     std::string result = convert.to_bytes(str);
3219     return result == DEFAULT_STRING ? "" : result;
3220 }
3221 
Dump(int fd,const std::vector<std::u16string> & args)3222 int ScreenSessionManager::Dump(int fd, const std::vector<std::u16string>& args)
3223 {
3224     WLOGFI("Dump begin");
3225     if (fd < 0) {
3226         return -1;
3227     }
3228     (void) signal(SIGPIPE, SIG_IGN); // ignore SIGPIPE crash
3229     UniqueFd ufd = UniqueFd(fd); // auto close
3230     fd = ufd.Get();
3231     std::vector<std::string> params;
3232     for (auto& arg : args) {
3233         params.emplace_back(Str16ToStr8(arg));
3234     }
3235     std::string dumpInfo;
3236     if (params.empty()) {
3237         ShowHelpInfo(dumpInfo);
3238     } else if (params.size() == 1 && params[0] == ARG_DUMP_HELP) { // 1: params num
3239         ShowHelpInfo(dumpInfo);
3240     } else if (params.size() == 1 && (params[0] == ARG_FOLD_DISPLAY_FULL || params[0] == ARG_FOLD_DISPLAY_MAIN)) {
3241         int errCode = SetFoldDisplayMode(params[0]);
3242         if (errCode != 0) {
3243             ShowIllegalArgsInfo(dumpInfo);
3244         }
3245     } else if (params.size() == 1 && (params[0] == ARG_LOCK_FOLD_DISPLAY_STATUS
3246                 || params[0] == ARG_UNLOCK_FOLD_DISPLAY_STATUS)) {
3247         int errCode = SetFoldStatusLocked(params[0]);
3248         if (errCode != 0) {
3249             ShowIllegalArgsInfo(dumpInfo);
3250         }
3251     } else {
3252         int errCode = DumpScreenInfo(params, dumpInfo);
3253         if (errCode != 0) {
3254             ShowIllegalArgsInfo(dumpInfo);
3255         }
3256     }
3257     int ret = dprintf(fd, "%s\n", dumpInfo.c_str());
3258     if (ret < 0) {
3259         WLOGFE("dprintf error");
3260         return -1; // WMError::WM_ERROR_INVALID_OPERATION;
3261     }
3262     WLOGI("dump end");
3263     return 0;
3264 }
3265 
SetFoldDisplayMode(const std::string & modeParam)3266 int ScreenSessionManager::SetFoldDisplayMode(const std::string& modeParam)
3267 {
3268     if (modeParam.empty()) {
3269         return -1;
3270     }
3271     FoldDisplayMode displayMode = FoldDisplayMode::UNKNOWN;
3272     if (modeParam == ARG_FOLD_DISPLAY_FULL) {
3273         displayMode = FoldDisplayMode::FULL;
3274     } else if (modeParam == ARG_FOLD_DISPLAY_MAIN) {
3275         displayMode = FoldDisplayMode::MAIN;
3276     } else {
3277         WLOGFW("SetFoldDisplayMode mode not support");
3278         return -1;
3279     }
3280     SetFoldDisplayMode(displayMode);
3281     return 0;
3282 }
3283 
SetFoldStatusLocked(const std::string & lockParam)3284 int ScreenSessionManager::SetFoldStatusLocked(const std::string& lockParam)
3285 {
3286     if (lockParam.empty()) {
3287         return -1;
3288     }
3289     bool lockDisplayStatus = false;
3290     if (lockParam == ARG_LOCK_FOLD_DISPLAY_STATUS) {
3291         lockDisplayStatus = true;
3292     } else if (lockParam == ARG_UNLOCK_FOLD_DISPLAY_STATUS) {
3293         lockDisplayStatus = false;
3294     } else {
3295         WLOGFW("SetFoldStatusLocked status not support");
3296         return -1;
3297     }
3298     SetFoldStatusLocked(lockDisplayStatus);
3299     return 0;
3300 }
3301 
NotifyAvailableAreaChanged(DMRect area)3302 void ScreenSessionManager::NotifyAvailableAreaChanged(DMRect area)
3303 {
3304     WLOGI("NotifyAvailableAreaChanged call");
3305     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER);
3306     if (agents.empty()) {
3307         return;
3308     }
3309     for (auto& agent: agents) {
3310         agent->NotifyAvailableAreaChanged(area);
3311     }
3312 }
3313 
GetAvailableArea(DisplayId displayId,DMRect & area)3314 DMError ScreenSessionManager::GetAvailableArea(DisplayId displayId, DMRect& area)
3315 {
3316     auto displayInfo = GetDisplayInfoById(displayId);
3317     if (displayInfo == nullptr) {
3318         WLOGFE("can not get displayInfo.");
3319         return DMError::DM_ERROR_NULLPTR;
3320     }
3321     auto screenSession = GetScreenSession(displayInfo->GetScreenId());
3322     if (screenSession == nullptr) {
3323         WLOGFE("can not get default screen now");
3324         return DMError::DM_ERROR_NULLPTR;
3325     }
3326     area = screenSession->GetAvailableArea();
3327     return DMError::DM_OK;
3328 }
3329 
UpdateAvailableArea(ScreenId screenId,DMRect area)3330 void ScreenSessionManager::UpdateAvailableArea(ScreenId screenId, DMRect area)
3331 {
3332     auto screenSession = GetScreenSession(screenId);
3333     if (screenSession == nullptr) {
3334         WLOGFE("can not get default screen now");
3335         return;
3336     }
3337     if (!screenSession->UpdateAvailableArea(area)) {
3338         return;
3339     }
3340     NotifyAvailableAreaChanged(area);
3341 }
3342 
NotifyFoldToExpandCompletion(bool foldToExpand)3343 void ScreenSessionManager::NotifyFoldToExpandCompletion(bool foldToExpand)
3344 {
3345     WLOGFI("ScreenSessionManager::NotifyFoldToExpandCompletion");
3346     SetDisplayNodeScreenId(SCREEN_ID_FULL, foldToExpand ? SCREEN_ID_FULL : SCREEN_ID_MAIN);
3347 }
3348 
CheckAndSendHiSysEvent(const std::string & eventName,const std::string & bundleName) const3349 void ScreenSessionManager::CheckAndSendHiSysEvent(const std::string& eventName, const std::string& bundleName) const
3350 {
3351     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CheckAndSendHiSysEvent");
3352     if (Permission::CheckIsCallingBundleName(bundleName) == false) {
3353         WLOGI("BundleName not in whitelist!");
3354         return;
3355     }
3356     int32_t eventRet = HiSysEventWrite(
3357         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
3358         eventName, // CREATE_VIRTUAL_SCREEN, GET_DISPLAY_SNAPSHOT
3359         OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,
3360         "PID", getpid(),
3361         "UID", getuid());
3362     WLOGI("%{public}s: Write HiSysEvent ret:%{public}d", eventName.c_str(), eventRet);
3363 }
3364 } // namespace OHOS::Rosen
3365