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