• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "screen_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 #include "input_manager.h"
25 
26 #include <hitrace_meter.h>
27 #ifdef DEVICE_STATUS_ENABLE
28 #include <interaction_manager.h>
29 #endif // DEVICE_STATUS_ENABLE
30 #include <ipc_skeleton.h>
31 #include <parameter.h>
32 #include <parameters.h>
33 #include <privacy_kit.h>
34 #include <system_ability_definition.h>
35 #include <transaction/rs_interfaces.h>
36 #include <xcollie/watchdog.h>
37 #include <hisysevent.h>
38 #include <power_mgr_client.h>
39 #include <screen_power_utils.h>
40 
41 #include "dm_common.h"
42 #include "fold_screen_state_internel.h"
43 #ifdef WM_MULTI_SCREEN_ENABLE
44 #include "multi_screen_manager.h"
45 #endif
46 #include "pipeline/rs_node_map.h"
47 #include "scene_board_judgement.h"
48 #include "session_permission.h"
49 #include "screen_scene_config.h"
50 #include "surface_capture_future.h"
51 #include "sys_cap_util.h"
52 #include "permission.h"
53 #include "window_manager_hilog.h"
54 #include "screen_rotation_property.h"
55 #include "screen_sensor_connector.h"
56 #include "screen_setting_helper.h"
57 #include "screen_session_dumper.h"
58 #include "mock_session_manager_service.h"
59 #include "connection/screen_snapshot_picker_connection.h"
60 #include "connection/screen_cast_connection.h"
61 #include "publish/screen_session_publish.h"
62 #include "dms_xcollie.h"
63 #include "screen_sensor_plugin.h"
64 #ifdef FOLD_ABILITY_ENABLE
65 #include "fold_screen_controller/super_fold_sensor_manager.h"
66 #include "fold_screen_controller/super_fold_state_manager.h"
67 #include "fold_screen_controller/secondary_fold_sensor_manager.h"
68 #include "fold_screen_controller/super_fold_policy.h"
69 #endif
70 
71 namespace OHOS::Rosen {
72 namespace {
73 const std::string SCREEN_SESSION_MANAGER_THREAD = "OS_ScreenSessionManager";
74 const std::string SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD = "OS_ScreenSessionManager_ScreenPower";
75 const std::string SCREEN_CAPTURE_PERMISSION = "ohos.permission.CAPTURE_SCREEN";
76 const std::string CUSTOM_SCREEN_CAPTURE_PERMISSION = "ohos.permission.CUSTOM_SCREEN_CAPTURE";
77 const std::string BOOTEVENT_BOOT_COMPLETED = "bootevent.boot.completed";
78 const std::string ACCESS_VIRTUAL_SCREEN_PERMISSION = "ohos.permission.ACCESS_VIRTUAL_SCREEN";
79 const int32_t CV_WAIT_SCREENON_MS = 300;
80 const int32_t CV_WAIT_SCREENOFF_MS = 1500;
81 const int32_t CV_WAIT_SCREENOFF_MS_MAX = 3000;
82 const int32_t CV_WAIT_SCBSWITCH_MS = 3000;
83 #ifdef WM_MULTI_USR_ABILITY_ENABLE
84 const int64_t SWITCH_USER_DISPLAYMODE_CHANGE_DELAY = 500;
85 #endif
86 const int32_t SCREEN_OFF_MIN_DELAY_TIME = 300;
87 const int32_t SCREEN_WAIT_PICTURE_FRAME_TIME = 1500;
88 const std::string STATUS_FOLD_HALF = "-z";
89 const std::string STATUS_EXPAND = "-y";
90 const std::string STATUS_FOLD = "-p";
91 const std::string SETTING_LOCKED_KEY = "settings.general.accelerometer_rotation_status";
92 const ScreenId SCREEN_ID_DEFAULT = 0;
93 const ScreenId SCREEN_ID_FULL = 0;
94 const ScreenId SCREEN_ID_MAIN = 5;
95 const ScreenId SCREEN_ID_PC_MAIN = 9;
96 const ScreenId MINIMUM_VIRTUAL_SCREEN_ID = 1000;
97 constexpr int32_t INVALID_UID = -1;
98 constexpr int32_t INVALID_USER_ID = -1;
99 constexpr int32_t INVALID_SCB_PID = -1;
100 constexpr int32_t BASE_USER_RANGE = 200000;
101 static bool g_foldScreenFlag = system::GetParameter("const.window.foldscreen.type", "") != "";
102 static const int32_t SCREEN_ROTATION_OFFSET = system::GetIntParameter<int32_t>("const.fold.screen_rotation.offset", 0);
103 static const int32_t g_outerOnly = system::GetIntParameter<int32_t>("persist.display.outeronly", 0);
104 static const int32_t ROTATION_90 = 1;
105 static const int32_t ONLY_OUTER_SCREEN_VALUE = 1;
106 #ifdef FOLD_ABILITY_ENABLE
107 static const int32_t ROTATION_270 = 3;
108 constexpr int32_t REMOVE_DISPLAY_MODE = 0;
109 #endif
110 static const int32_t AUTO_ROTATE_OFF = 0;
111 static const int NOTIFY_EVENT_FOR_DUAL_FAILED = 0;
112 static const int NOTIFY_EVENT_FOR_DUAL_SUCESS = 1;
113 static const int NO_NEED_NOTIFY_EVENT_FOR_DUAL = 2;
114 static bool g_isPcDevice = false;
115 static uint32_t g_internalWidth = 3120;
116 const unsigned int XCOLLIE_TIMEOUT_10S = 10;
117 constexpr int32_t CAST_WIRED_PROJECTION_START = 1005;
118 constexpr int32_t CAST_WIRED_PROJECTION_STOP = 1007;
119 constexpr int32_t RES_FAILURE_FOR_PRIVACY_WINDOW = -2;
120 constexpr int32_t IRREGULAR_REFRESH_RATE_SKIP_THRETHOLD = 10;
121 #ifdef WM_MULTI_SCREEN_CTL_ABILITY_ENABLE
122 constexpr uint32_t NUMBER_OF_PHYSICAL_SCREEN = 2;
123 constexpr bool ADD_VOTE = true;
124 constexpr bool REMOVE_VOTE = false;
125 constexpr uint32_t OLED_60_HZ = 60;
126 #endif
127 constexpr uint32_t FOUR_K_WIDTH = 3840;
128 constexpr uint32_t THREE_K_WIDTH = 3000;
129 constexpr uint32_t DISPLAY_B_HEIGHT = 1608;
130 
131 const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
132 constexpr int32_t FOLDABLE_DEVICE { 2 };
133 constexpr float DEFAULT_PIVOT = 0.5f;
134 constexpr float DEFAULT_SCALE = 1.0f;
135 constexpr float EXTEND_SCREEN_DPI_PARAMETER = 0.85f;
136 static const constexpr char* SET_SETTING_DPI_KEY {"default_display_dpi"};
137 const std::vector<std::string> ROTATION_DEFAULT = {"0", "1", "2", "3"};
138 const std::vector<std::string> ORIENTATION_DEFAULT = {"0", "1", "2", "3"};
139 
140 const std::string SCREEN_UNKNOWN = "unknown";
141 #ifdef WM_MULTI_SCREEN_ENABLE
142 const std::string SCREEN_EXTEND = "extend";
143 const std::string SCREEN_MIRROR = "mirror";
144 const std::string MULTI_SCREEN_EXIT_STR = "exit";
145 const std::string MULTI_SCREEN_ENTER_STR = "enter";
146 #endif
147 const bool IS_COORDINATION_SUPPORT =
148     OHOS::system::GetBoolParameter("const.window.foldabledevice.is_coordination_support", false);
149 
150 const std::string FAULT_DESCRIPTION = "842003014";
151 const std::string FAULT_SUGGESTION = "542003014";
152 constexpr uint32_t COMMON_EVENT_SERVICE_ID = 3299;
153 
154 // based on the bundle_util
GetUserIdByCallingUid()155 inline int32_t GetUserIdByCallingUid()
156 {
157     int32_t uid = IPCSkeleton::GetCallingUid();
158     TLOGD(WmsLogTag::WMS_MULTI_USER, "get calling uid(%{public}d)", uid);
159     if (uid <= INVALID_UID) {
160         TLOGE(WmsLogTag::WMS_MULTI_USER, "uid is illegal: %{public}d", uid);
161         return INVALID_USER_ID;
162     }
163     return uid / BASE_USER_RANGE;
164 }
165 } // namespace
166 
167 WM_IMPLEMENT_SINGLE_INSTANCE(ScreenSessionManager)
168 
169 const bool REGISTER_RESULT = !SceneBoardJudgement::IsSceneBoardEnabled() ? false :
170     SystemAbility::MakeAndRegisterAbility(&ScreenSessionManager::GetInstance());
171 
ScreenSessionManager()172 ScreenSessionManager::ScreenSessionManager()
173     : SystemAbility(DISPLAY_MANAGER_SERVICE_SA_ID, true), rsInterface_(RSInterfaces::GetInstance())
174 {
175     screenEventTracker_.RecordEvent("Dms construct.");
176     LoadScreenSceneXml();
177     screenOffDelay_ = CV_WAIT_SCREENOFF_MS;
178     screenOnDelay_ = CV_WAIT_SCREENON_MS;
179     taskScheduler_ = std::make_shared<TaskScheduler>(SCREEN_SESSION_MANAGER_THREAD);
180     screenPowerTaskScheduler_ = std::make_shared<TaskScheduler>(SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD);
181     screenCutoutController_ = new (std::nothrow) ScreenCutoutController();
182     if (!screenCutoutController_) {
183         TLOGE(WmsLogTag::DMS, "screenCutoutController_ is nullptr");
184         return;
185     }
186     sessionDisplayPowerController_ = new SessionDisplayPowerController(
187         std::bind(&ScreenSessionManager::NotifyDisplayStateChange, this,
188             std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
189     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
190         g_foldScreenFlag = false;
191     }
192     if (g_foldScreenFlag) {
193         HandleFoldScreenPowerInit();
194     }
195     WatchParameter(BOOTEVENT_BOOT_COMPLETED.c_str(), BootFinishedCallback, this);
196 }
197 
ConvertOffsetToCorrectRotation(int32_t phyOffset)198 ScreenRotation ScreenSessionManager::ConvertOffsetToCorrectRotation(int32_t phyOffset)
199 {
200     ScreenRotation offsetRotation = ScreenRotation::ROTATION_0;
201     switch (phyOffset) {
202         case 90: // Rotation 90 degree
203             offsetRotation = ScreenRotation::ROTATION_270;
204             break;
205         case 180: // Rotation 180 degree
206             offsetRotation = ScreenRotation::ROTATION_180;
207             break;
208         case 270: // Rotation 270 degree
209             offsetRotation = ScreenRotation::ROTATION_90;
210             break;
211         default:
212             offsetRotation = ScreenRotation::ROTATION_0;
213             break;
214     }
215     return offsetRotation;
216 }
217 
HandleFoldScreenPowerInit()218 void ScreenSessionManager::HandleFoldScreenPowerInit()
219 {
220 #ifdef FOLD_ABILITY_ENABLE
221     TLOGI(WmsLogTag::DMS, "Enter");
222     foldScreenController_ = new (std::nothrow) FoldScreenController(displayInfoMutex_, screenPowerTaskScheduler_);
223     if (!foldScreenController_) {
224         TLOGE(WmsLogTag::DMS, "foldScreenController_ is nullptr");
225         return;
226     }
227     foldScreenController_->SetOnBootAnimation(true);
228     if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
229         SetFoldScreenPowerInit([&]() {
230             foldScreenController_->BootAnimationFinishPowerInit();
231             FixPowerStatus();
232             foldScreenController_->SetOnBootAnimation(false);
233             RegisterApplicationStateObserver();
234         });
235     } else {
236         // 后续其他设备rs上电规格将陆续迁移到BootAnimationFinishPowerInit中
237         FoldScreenPowerInit();
238     }
239 #endif
240 }
241 
IsSupportCoordination()242 bool ScreenSessionManager::IsSupportCoordination()
243 {
244     return !FoldScreenStateInternel::IsDualDisplayFoldDevice() || IS_COORDINATION_SUPPORT;
245 }
246 
FoldScreenPowerInit()247 void ScreenSessionManager::FoldScreenPowerInit()
248 {
249 #ifdef FOLD_ABILITY_ENABLE
250     SetFoldScreenPowerInit([&]() {
251         int64_t timeStamp = 50;
252 #ifdef TP_FEATURE_ENABLE
253         int32_t tpType = 12;
254         std::string fullTpChange = "0";
255         std::string mainTpChange = "1";
256 #endif
257         if (!foldScreenController_) {
258             TLOGE(WmsLogTag::DMS, "foldScreenController_ is nullptr");
259             return;
260         }
261         ScreenId currentScreenId = foldScreenController_->GetCurrentScreenId();
262         if (currentScreenId == SCREEN_ID_FULL) {
263             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Full animation Init 1.");
264             rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF_FAKE);
265             if (IsSupportCoordination()) {
266                 rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
267             }
268             std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
269             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Full animation Init 2.");
270 #ifdef TP_FEATURE_ENABLE
271             rsInterface_.SetTpFeatureConfig(tpType, fullTpChange.c_str());
272 #endif
273             if (IsSupportCoordination()) {
274                 rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
275             }
276             foldScreenController_->AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, REMOVE_DISPLAY_MODE);
277             rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
278         } else if (currentScreenId == SCREEN_ID_MAIN) {
279             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Main animation Init 3.");
280             rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF_FAKE);
281             if (IsSupportCoordination()) {
282                 rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
283             }
284             std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
285             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Main animation Init 4.");
286 #ifdef TP_FEATURE_ENABLE
287             rsInterface_.SetTpFeatureConfig(tpType, mainTpChange.c_str());
288 #endif
289             if (IsSupportCoordination()) {
290                 rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
291             }
292             foldScreenController_->AddOrRemoveDisplayNodeToTree(SCREEN_ID_FULL, REMOVE_DISPLAY_MODE);
293             rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
294         } else {
295             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Init, invalid active screen id");
296         }
297         FixPowerStatus();
298         foldScreenController_->SetOnBootAnimation(false);
299         RegisterApplicationStateObserver();
300     });
301 #endif
302 }
303 
FixPowerStatus()304 void ScreenSessionManager::FixPowerStatus()
305 {
306     if (!PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
307         PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
308         TLOGI(WmsLogTag::DMS, "Fix Screen Power State");
309     }
310 }
311 
Init()312 void ScreenSessionManager::Init()
313 {
314     if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none") {
315         g_isPcDevice = true;
316     }
317     if (system::GetParameter("soc.boot.mode", "") != "rescue") {
318         uint64_t interval = g_isPcDevice ? 10 * 1000 : 5 * 1000; // 10 second for PC
319         if (HiviewDFX::Watchdog::GetInstance().AddThread(
320             SCREEN_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
321             TLOGW(WmsLogTag::DMS, "Add thread %{public}s to watchdog failed.", SCREEN_SESSION_MANAGER_THREAD.c_str());
322         }
323 
324         if (HiviewDFX::Watchdog::GetInstance().AddThread(
325             SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD, screenPowerTaskScheduler_->GetEventHandler(), interval)) {
326             TLOGW(WmsLogTag::DMS, "Add thread %{public}s to watchdog failed.",
327                 SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD.c_str());
328         }
329     } else {
330         TLOGI(WmsLogTag::DMS, "Dms in rescue mode, not need watchdog.");
331         screenEventTracker_.RecordEvent("Dms in rescue mode, not need watchdog.");
332     }
333 
334     auto stringConfig = ScreenSceneConfig::GetStringConfig();
335     if (stringConfig.count("defaultDisplayCutoutPath") != 0) {
336         std::string defaultDisplayCutoutPath = static_cast<std::string>(stringConfig["defaultDisplayCutoutPath"]);
337         TLOGD(WmsLogTag::DMS, "defaultDisplayCutoutPath = %{public}s.", defaultDisplayCutoutPath.c_str());
338         ScreenSceneConfig::SetCutoutSvgPath(GetDefaultScreenId(), defaultDisplayCutoutPath);
339     }
340 
341     if (!LoadMotionSensor()) {
342         screenEventTracker_.RecordEvent("Dms load motion plugin failed.");
343         TLOGW(WmsLogTag::DMS, "load motion plugin failed.");
344     }
345 
346     RegisterScreenChangeListener();
347     if (!ScreenSceneConfig::IsSupportRotateWithSensor()) {
348         TLOGI(WmsLogTag::DMS, "Current type not support SetSensorSubscriptionEnabled.");
349     } else if (GetScreenPower(SCREEN_ID_FULL) == ScreenPowerState::POWER_ON) {
350         // 多屏设备只要有屏幕亮,GetScreenPower获取的任意一块屏幕状态均是ON
351         SetSensorSubscriptionEnabled();
352         screenEventTracker_.RecordEvent("Dms subscribed to sensor successfully.");
353     }
354 
355     // publish init
356     ScreenSessionPublish::GetInstance().InitPublishEvents();
357     screenEventTracker_.RecordEvent("Dms init end.");
358 }
359 
OnStart()360 void ScreenSessionManager::OnStart()
361 {
362     TLOGI(WmsLogTag::DMS, "start");
363     DmsXcollie dmsXcollie("DMS:OnStart", XCOLLIE_TIMEOUT_10S,
364         [this](void *) { screenEventTracker_.LogWarningAllInfos(); });
365     Init();
366     sptr<ScreenSessionManager> dms(this);
367     dms->IncStrongRef(nullptr);
368     if (!Publish(dms)) {
369         TLOGE(WmsLogTag::DMS, "Publish DMS failed");
370         return;
371     }
372     TLOGI(WmsLogTag::DMS, "DMS SA AddSystemAbilityListener");
373     (void)AddSystemAbilityListener(SENSOR_SERVICE_ABILITY_ID);
374     (void)AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
375     screenEventTracker_.RecordEvent("Dms AddSystemAbilityListener finished.");
376     TLOGI(WmsLogTag::DMS, "end");
377     screenEventTracker_.RecordEvent("Dms onstart end.");
378 }
379 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)380 void ScreenSessionManager::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
381 {
382     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "OnAddSystemAbility: %d", systemAbilityId);
383     TLOGI(WmsLogTag::DMS, "receive sa add:%{public}d", systemAbilityId);
384     if (systemAbilityId == SENSOR_SERVICE_ABILITY_ID) {
385 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
386         if (!g_foldScreenFlag) {
387             TLOGI(WmsLogTag::DMS, "current device is not fold phone.");
388             return;
389         }
390         if (!foldScreenController_ || isFoldScreenOuterScreenReady_) {
391             TLOGI(WmsLogTag::DMS, "foldScreenController_ is null or outer screen is not ready.");
392             return;
393         }
394         if (GetDisplayState(foldScreenController_->GetCurrentScreenId()) == DisplayState::ON) {
395             if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
396                 SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
397             } else {
398                 FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
399             }
400             TLOGI(WmsLogTag::DMS, "Recover Posture sensor finished");
401         }
402 
403         if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
404             SecondaryFoldSensorManager::GetInstance().RegisterHallCallback();
405         } else {
406             FoldScreenSensorManager::GetInstance().RegisterHallCallback();
407         }
408         TLOGI(WmsLogTag::DMS, "Recover Hall sensor finished");
409         screenEventTracker_.RecordEvent("Dms recover Posture and Hall sensor finished.");
410 #endif
411     } else if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
412         auto task = []() {
413             ScreenSessionPublish::GetInstance().RegisterLowTempSubscriber();
414             ScreenSessionPublish::GetInstance().RegisterUserSwitchedSubscriber();
415         };
416         taskScheduler_->PostAsyncTask(task, "RegisterCommonEventSubscriber");
417     }
418 }
419 
CheckDisplayMangerAgentTypeAndPermission(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)420 DMError ScreenSessionManager::CheckDisplayMangerAgentTypeAndPermission(
421     const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
422 {
423     if ((type == DisplayManagerAgentType::SCREEN_EVENT_LISTENER ||
424         type == DisplayManagerAgentType::PRIVATE_WINDOW_LISTENER) &&
425         !SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
426         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
427             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
428         return DMError::DM_ERROR_NOT_SYSTEM_APP;
429     }
430 
431     if ((displayManagerAgent == nullptr) || (displayManagerAgent->AsObject() == nullptr)) {
432         TLOGE(WmsLogTag::DMS, "displayManagerAgent invalid");
433         return DMError::DM_ERROR_NULLPTR;
434     }
435     return DMError::DM_OK;
436 }
437 
RegisterDisplayManagerAgent(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)438 DMError ScreenSessionManager::RegisterDisplayManagerAgent(
439     const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
440 {
441     TLOGI(WmsLogTag::DMS, " called type: %{public}u", type);
442     DmsXcollie dmsXcollie("DMS:RegisterDisplayManagerAgent", XCOLLIE_TIMEOUT_10S);
443     DMError ret;
444 
445     ret = CheckDisplayMangerAgentTypeAndPermission(displayManagerAgent, type);
446     if (ret != DMError::DM_OK) {
447         TLOGE(WmsLogTag::DMS, "call CheckDisplayMangerAgentTypeAndPermission fail!");
448         return ret;
449     }
450 
451     if (type < DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER
452         || type >= DisplayManagerAgentType::DISPLAY_MANAGER_MAX_AGENT_TYPE) {
453         TLOGE(WmsLogTag::DMS, "DisplayManagerAgentType: %{public}u", static_cast<uint32_t>(type));
454         return DMError::DM_ERROR_INVALID_PARAM;
455     }
456     return dmAgentContainer_.RegisterAgent(displayManagerAgent, type) ? DMError::DM_OK :DMError::DM_ERROR_NULLPTR;
457 }
458 
UnregisterDisplayManagerAgent(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)459 DMError ScreenSessionManager::UnregisterDisplayManagerAgent(
460     const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
461 {
462     TLOGI(WmsLogTag::DMS, " called type: %{public}u", type);
463     DMError ret;
464 
465     ret = CheckDisplayMangerAgentTypeAndPermission(displayManagerAgent, type);
466     if (ret != DMError::DM_OK) {
467         TLOGE(WmsLogTag::DMS, "call CheckDisplayMangerAgentTypeAndPermission fail!");
468         return ret;
469     }
470     return dmAgentContainer_.UnregisterAgent(displayManagerAgent, type) ? DMError::DM_OK :DMError::DM_ERROR_NULLPTR;
471 }
472 
LoadScreenSceneXml()473 void ScreenSessionManager::LoadScreenSceneXml()
474 {
475     if (ScreenSceneConfig::LoadConfigXml()) {
476         ScreenSceneConfig::DumpConfig();
477         ConfigureScreenScene();
478     }
479 }
480 
ConfigureScreenScene()481 void ScreenSessionManager::ConfigureScreenScene()
482 {
483     auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
484     auto enableConfig = ScreenSceneConfig::GetEnableConfig();
485     auto stringConfig = ScreenSceneConfig::GetStringConfig();
486     ConfigureDpi();
487     if (numbersConfig.count("defaultDeviceRotationOffset") != 0) {
488         defaultDeviceRotationOffset_ = static_cast<uint32_t>(numbersConfig["defaultDeviceRotationOffset"][0]);
489         TLOGD(WmsLogTag::DMS, "defaultDeviceRotationOffset = %{public}u", defaultDeviceRotationOffset_);
490     }
491     if (enableConfig.count("isWaterfallDisplay") != 0) {
492         bool isWaterfallDisplay = static_cast<bool>(enableConfig["isWaterfallDisplay"]);
493         TLOGD(WmsLogTag::DMS, "isWaterfallDisplay = %{public}d", isWaterfallDisplay);
494     }
495     if (numbersConfig.count("curvedScreenBoundary") != 0) {
496         std::vector<int> vtBoundary = static_cast<std::vector<int>>(numbersConfig["curvedScreenBoundary"]);
497         TLOGD(WmsLogTag::DMS, "vtBoundary.size=%{public}u", static_cast<uint32_t>(vtBoundary.size()));
498     }
499     if (stringConfig.count("subDisplayCutoutPath") != 0) {
500         std::string subDisplayCutoutPath = stringConfig["subDisplayCutoutPath"];
501         TLOGD(WmsLogTag::DMS, "subDisplayCutoutPath = %{public}s.", subDisplayCutoutPath.c_str());
502         ScreenSceneConfig::SetSubCutoutSvgPath(subDisplayCutoutPath);
503     }
504     if (stringConfig.count("rotationPolicy") != 0) {
505         std::string rotationPolicy = stringConfig["rotationPolicy"];
506         TLOGD(WmsLogTag::DMS, "rotationPolicy = %{public}s.", rotationPolicy.c_str());
507         deviceScreenConfig_.rotationPolicy_ = rotationPolicy;
508     }
509     if (stringConfig.count("defaultRotationPolicy") != 0) {
510         std::string defaultRotationPolicy = stringConfig["defaultRotationPolicy"];
511         TLOGD(WmsLogTag::DMS, "defaultRotationPolicy = %{public}s.", defaultRotationPolicy.c_str());
512         deviceScreenConfig_.defaultRotationPolicy_ = defaultRotationPolicy;
513     }
514     if (enableConfig.count("isRightPowerButton") != 0) {
515         bool isRightPowerButton = static_cast<bool>(enableConfig["isRightPowerButton"]);
516         TLOGD(WmsLogTag::DMS, "isRightPowerButton = %{public}d", isRightPowerButton);
517         deviceScreenConfig_.isRightPowerButton_ = isRightPowerButton;
518     }
519     ConfigureWaterfallDisplayCompressionParams();
520     ConfigureCastParams();
521 
522     if (numbersConfig.count("buildInDefaultOrientation") != 0) {
523         Orientation orientation = static_cast<Orientation>(numbersConfig["buildInDefaultOrientation"][0]);
524         TLOGD(WmsLogTag::DMS, "orientation = %{public}d", orientation);
525     }
526     allDisplayPhysicalResolution_ = ScreenSceneConfig::GetAllDisplayPhysicalConfig();
527 }
528 
ConfigureDpi()529 void ScreenSessionManager::ConfigureDpi()
530 {
531     auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
532     if (numbersConfig.count("dpi") != 0) {
533         uint32_t densityDpi = static_cast<uint32_t>(numbersConfig["dpi"][0]);
534         TLOGI(WmsLogTag::DMS, "densityDpi = %{public}u", densityDpi);
535         if (densityDpi >= DOT_PER_INCH_MINIMUM_VALUE && densityDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
536             isDensityDpiLoad_ = true;
537             defaultDpi = densityDpi;
538             cachedSettingDpi_ = defaultDpi;
539             densityDpi_ = static_cast<float>(densityDpi) / BASELINE_DENSITY;
540         }
541     }
542     if (numbersConfig.count("subDpi") != 0) {
543         uint32_t subDensityDpi = static_cast<uint32_t>(numbersConfig["subDpi"][0]);
544         TLOGI(WmsLogTag::DMS, "subDensityDpi = %{public}u", subDensityDpi);
545         if (subDensityDpi >= DOT_PER_INCH_MINIMUM_VALUE && subDensityDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
546             isDensityDpiLoad_ = true;
547             subDensityDpi_ = static_cast<float>(subDensityDpi) / BASELINE_DENSITY;
548         }
549     }
550 }
551 
ConfigureCastParams()552 void ScreenSessionManager::ConfigureCastParams()
553 {
554     auto stringConfig = ScreenSceneConfig::GetStringConfig();
555     if (stringConfig.count("castBundleName") == 0) {
556         TLOGE(WmsLogTag::DMS, "not find cast bundleName in config xml");
557         return;
558     }
559     std::string castBundleName = static_cast<std::string>(stringConfig["castBundleName"]);
560     TLOGD(WmsLogTag::DMS, "castBundleName = %{public}s", castBundleName.c_str());
561     ScreenCastConnection::GetInstance().SetBundleName(castBundleName);
562     if (stringConfig.count("castAbilityName") == 0) {
563         TLOGE(WmsLogTag::DMS, "not find cast ability in config xml");
564         return;
565     }
566     std::string castAbilityName = static_cast<std::string>(stringConfig["castAbilityName"]);
567     TLOGD(WmsLogTag::DMS, "castAbilityName = %{public}s", castAbilityName.c_str());
568     ScreenCastConnection::GetInstance().SetAbilityName(castAbilityName);
569 }
570 
ConfigureWaterfallDisplayCompressionParams()571 void ScreenSessionManager::ConfigureWaterfallDisplayCompressionParams()
572 {
573     auto enableConfig = ScreenSceneConfig::GetEnableConfig();
574     if (enableConfig.count("isWaterfallAreaCompressionEnableWhenHorizontal") != 0) {
575         bool enable = static_cast<bool>(enableConfig["isWaterfallAreaCompressionEnableWhenHorizontal"]);
576         TLOGD(WmsLogTag::DMS, "isWaterfallAreaCompressionEnableWhenHorizontal=%{public}d.", enable);
577     }
578     ScreenSceneConfig::SetCurvedCompressionAreaInLandscape();
579 }
580 
ConfigureScreenSnapshotParams()581 void ScreenSessionManager::ConfigureScreenSnapshotParams()
582 {
583     auto stringConfig = ScreenSceneConfig::GetStringConfig();
584     if (stringConfig.count("screenSnapshotBundleName") == 0) {
585         TLOGE(WmsLogTag::DMS, "not find screen snapshot bundleName in config xml");
586         return;
587     }
588     std::string screenSnapshotBundleName = static_cast<std::string>(stringConfig["screenSnapshotBundleName"]);
589     TLOGD(WmsLogTag::DMS, "screenSnapshotBundleName = %{public}s.", screenSnapshotBundleName.c_str());
590     ScreenSnapshotPickerConnection::GetInstance().SetBundleName(screenSnapshotBundleName);
591     if (stringConfig.count("screenSnapshotAbilityName") == 0) {
592         TLOGE(WmsLogTag::DMS, "not find screen snapshot ability in config xml");
593         return;
594     }
595     std::string screenSnapshotAbilityName = static_cast<std::string>(stringConfig["screenSnapshotAbilityName"]);
596     TLOGD(WmsLogTag::DMS, "screenSnapshotAbilityName = %{public}s.", screenSnapshotAbilityName.c_str());
597     ScreenSnapshotPickerConnection::GetInstance().SetAbilityName(screenSnapshotAbilityName);
598 }
599 
RegisterScreenChangeListener()600 void ScreenSessionManager::RegisterScreenChangeListener()
601 {
602     TLOGI(WmsLogTag::DMS, "start");
603     auto res = rsInterface_.SetScreenChangeCallback(
604         [this](ScreenId screenId, ScreenEvent screenEvent, ScreenChangeReason reason) {
605             OnScreenChange(screenId, screenEvent, reason);
606         });
607     if (res != StatusCode::SUCCESS) {
608         auto task = [this]() { RegisterScreenChangeListener(); };
609         taskScheduler_->PostAsyncTask(task, "RegisterScreenChangeListener", 50);  // Retry after 50 ms.
610         screenEventTracker_.RecordEvent("Dms OnScreenChange register failed.");
611     } else {
612         screenEventTracker_.RecordEvent("Dms OnScreenChange register success.");
613     }
614 }
615 
RegisterRefreshRateChangeListener()616 void ScreenSessionManager::RegisterRefreshRateChangeListener()
617 {
618     static bool isRegisterRefreshRateListener = false;
619     if (!isRegisterRefreshRateListener) {
620         TLOGW(WmsLogTag::DMS, "call rsInterface_ RegisterHgmRefreshRateUpdateCallback");
621         auto res = rsInterface_.RegisterHgmRefreshRateUpdateCallback(
622             [this](uint32_t refreshRate) { OnHgmRefreshRateChange(refreshRate); });
623         TLOGW(WmsLogTag::DMS, "call rsInterface_ RegisterHgmRefreshRateUpdateCallback end");
624         if (res != StatusCode::SUCCESS) {
625             TLOGE(WmsLogTag::DMS, "failed");
626             screenEventTracker_.RecordEvent("Dms RefreshRateChange register failed.");
627         } else {
628             isRegisterRefreshRateListener = true;
629             screenEventTracker_.RecordEvent("Dms RefreshRateChange register success.");
630         }
631     }
632 }
633 
OnVirtualScreenChange(ScreenId screenId,ScreenEvent screenEvent)634 void ScreenSessionManager::OnVirtualScreenChange(ScreenId screenId, ScreenEvent screenEvent)
635 {
636     TLOGI(WmsLogTag::DMS, "Notify scb virtual screen change, ScreenId: %{public}" PRIu64 ", ScreenEvent: %{public}d",
637         screenId, static_cast<int>(screenEvent));
638     auto screenSession = GetScreenSession(screenId);
639     if (!screenSession) {
640         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
641         return;
642     }
643     if (screenEvent == ScreenEvent::CONNECTED) {
644         if (clientProxy_) {
645             clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId),
646                 ScreenEvent::CONNECTED);
647         }
648         return;
649     }
650     if (screenEvent == ScreenEvent::DISCONNECTED) {
651         if (clientProxy_) {
652             clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId),
653                 ScreenEvent::DISCONNECTED);
654         }
655     }
656 }
657 
IsDefaultMirrorMode(ScreenId screenId)658 bool ScreenSessionManager::IsDefaultMirrorMode(ScreenId screenId)
659 {
660     if (screenId != SCREEN_ID_MAIN && screenId != SCREEN_ID_FULL && screenId != SCREEN_ID_PC_MAIN) {
661         return true;
662     }
663     return false;
664 }
665 
FreeDisplayMirrorNodeInner(const sptr<ScreenSession> mirrorSession)666 void ScreenSessionManager::FreeDisplayMirrorNodeInner(const sptr<ScreenSession> mirrorSession)
667 {
668     if (mirrorSession == nullptr) {
669         return;
670     }
671     {
672         std::shared_ptr<RSDisplayNode> displayNode = mirrorSession->GetDisplayNode();
673         if (displayNode == nullptr) {
674             return;
675         }
676         if (!g_isPcDevice) {
677             hdmiScreenCount_ = hdmiScreenCount_ > 0 ? hdmiScreenCount_ - 1 : 0;
678             NotifyCaptureStatusChanged();
679         }
680         displayNode->RemoveFromTree();
681         mirrorSession->ReleaseDisplayNode();
682         displayNode = nullptr;
683     }
684     auto transactionProxy = RSTransactionProxy::GetInstance();
685     if (transactionProxy != nullptr) {
686         TLOGI(WmsLogTag::DMS, "free displayNode");
687         transactionProxy->FlushImplicitTransaction();
688     }
689 }
690 
SetScreenCorrection()691 void ScreenSessionManager::SetScreenCorrection()
692 {
693     std::ostringstream oss;
694     if (g_foldScreenFlag) {
695         if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
696             auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_MAIN,
697                 static_cast<ScreenRotation>(ROTATION_90));
698             oss << "main screenRotationOffSet: " << SCREEN_ROTATION_OFFSET << " ret value: " << ret;
699         } else {
700             auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_FULL,
701                 static_cast<ScreenRotation>(SCREEN_ROTATION_OFFSET));
702             oss << "full screenRotationOffSet: " << SCREEN_ROTATION_OFFSET << " ret value: " << ret;
703         }
704     } else {
705         std::vector<std::string> phyOffsets = FoldScreenStateInternel::GetPhyRotationOffset();
706         int32_t phyOffset = static_cast<int32_t>(std::stoi(phyOffsets[0]));
707         ScreenRotation correctRotation = ConvertOffsetToCorrectRotation(phyOffset);
708         auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_DEFAULT, correctRotation);
709         oss << "phyOffset: " << phyOffset << " correctRotation value: " <<
710             static_cast<int32_t>(correctRotation) << " ret value: " << ret;
711     }
712     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
713     screenEventTracker_.RecordEvent(oss.str());
714 }
715 
OnScreenChange(ScreenId screenId,ScreenEvent screenEvent,ScreenChangeReason reason)716 void ScreenSessionManager::OnScreenChange(ScreenId screenId, ScreenEvent screenEvent, ScreenChangeReason reason)
717 {
718     if (reason == ScreenChangeReason::HWCDEAD) {
719         NotifyAbnormalScreenConnectChange(screenId);
720         TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " ScreenChangeReason: %{public}d",
721             screenId, static_cast<int>(reason));
722         return;
723     }
724     std::ostringstream oss;
725     oss << "OnScreenChange triggered. screenId: " << static_cast<int32_t>(screenId)
726         << "  screenEvent: " << static_cast<int32_t>(screenEvent);
727     screenEventTracker_.RecordEvent(oss.str());
728     TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " screenEvent: %{public}d",
729         screenId, static_cast<int>(screenEvent));
730     SetScreenCorrection();
731     auto screenSession = GetOrCreateScreenSession(screenId);
732     if (!screenSession) {
733         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
734         return;
735     }
736 #ifdef FOLD_ABILITY_ENABLE
737     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
738         SuperFoldSensorManager::GetInstance().RegisterPostureCallback();
739         SuperFoldSensorManager::GetInstance().RegisterHallCallback();
740         SetSensorSubscriptionEnabled();
741         screenEventTracker_.RecordEvent("Dms subscribed to sensor successfully.");
742     }
743 
744     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
745         SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
746         SecondaryFoldSensorManager::GetInstance().RegisterHallCallback();
747         SetSensorSubscriptionEnabled();
748         screenEventTracker_.RecordEvent("secondary device: Dms subscribed to sensor successfully.");
749     }
750 
751     if (foldScreenController_ != nullptr) {
752         screenSession->SetFoldScreen(true);
753     }
754 #endif
755     if (screenEvent == ScreenEvent::CONNECTED) {
756         connectScreenNumber_ ++;
757         HandleScreenConnectEvent(screenSession, screenId, screenEvent);
758     } else if (screenEvent == ScreenEvent::DISCONNECTED) {
759         connectScreenNumber_ --;
760         HandleScreenDisconnectEvent(screenSession, screenId, screenEvent);
761     } else {
762         TLOGE(WmsLogTag::DMS, "screenEvent error!");
763     }
764     NotifyScreenModeChange();
765 }
766 
NotifyScreenModeChange(ScreenId disconnectedScreenId)767 void ScreenSessionManager::NotifyScreenModeChange(ScreenId disconnectedScreenId)
768 {
769     auto task = [=] {
770         auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER);
771         if (agents.empty()) {
772             return;
773         }
774         std::vector<sptr<ScreenInfo>> screenInfos;
775         std::vector<ScreenId> screenIds = GetAllScreenIds();
776         for (auto screenId : screenIds) {
777             if (disconnectedScreenId == screenId) {
778                 continue;
779             }
780             TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64, screenId);
781             auto screenSession = GetScreenSession(screenId);
782             screenInfos.emplace_back(screenSession->ConvertToScreenInfo());
783         }
784         for (auto& agent : agents) {
785             int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
786             if (!IsFreezed(agentPid, DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER)) {
787                 agent->NotifyScreenModeChange(screenInfos);
788             }
789         }
790     };
791     taskScheduler_->PostAsyncTask(task, "NotifyScreenModeChange");
792 }
793 
NotifyAbnormalScreenConnectChange(ScreenId screenId)794 void ScreenSessionManager::NotifyAbnormalScreenConnectChange(ScreenId screenId)
795 {
796     auto agents = dmAgentContainer_.GetAgentsByType(
797         DisplayManagerAgentType::ABNORMAL_SCREEN_CONNECT_CHANGE_LISTENER);
798     if (agents.empty()) {
799         TLOGE(WmsLogTag::DMS, "agents is empty");
800         return;
801     }
802     for (auto& agent : agents) {
803         agent->NotifyAbnormalScreenConnectChange(screenId);
804     }
805 }
806 
SendCastEvent(const bool & isPlugIn)807 void ScreenSessionManager::SendCastEvent(const bool &isPlugIn)
808 {
809     TLOGI(WmsLogTag::DMS, "isPlugIn:%{public}d", isPlugIn);
810     if (!ScreenCastConnection::GetInstance().CastConnectExtension(static_cast<int32_t>(isPlugIn))) {
811         TLOGE(WmsLogTag::DMS, "CastConnectionExtension failed");
812         return;
813     }
814     if (!ScreenCastConnection::GetInstance().IsConnectedSync()) {
815         TLOGE(WmsLogTag::DMS, "CastConnectionExtension connected failed");
816         ScreenCastConnection::GetInstance().CastDisconnectExtension();
817         return;
818     }
819     MessageParcel data;
820     MessageParcel reply;
821     if (isPlugIn) {
822         ScreenCastConnection::GetInstance().SendMessageToCastService(CAST_WIRED_PROJECTION_START, data, reply);
823     } else {
824         ScreenCastConnection::GetInstance().SendMessageToCastService(CAST_WIRED_PROJECTION_STOP, data, reply);
825     }
826     ScreenCastConnection::GetInstance().CastDisconnectExtension();
827 }
828 
NotifyCastWhenScreenConnectChange(bool isConnected)829 void ScreenSessionManager::NotifyCastWhenScreenConnectChange(bool isConnected)
830 {
831     if (g_isPcDevice) {
832         TLOGI(WmsLogTag::DMS, "pc device");
833         return;
834     }
835     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
836         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
837             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
838         return;
839     }
840     if (isConnected) {
841         auto task = [this]() {
842             SendCastEvent(true);
843             ScreenSessionPublish::GetInstance().PublishCastPlugInEvent();
844         };
845         taskScheduler_->PostAsyncTask(task, "SendCastEventTrue");
846         TLOGI(WmsLogTag::DMS, "PostAsyncTask SendCastEventTrue");
847     } else {
848         auto task = [this]() {
849             SendCastEvent(false);
850             ScreenSessionPublish::GetInstance().PublishCastPlugOutEvent();
851         };
852         taskScheduler_->PostAsyncTask(task, "SendCastEventFalse");
853         TLOGI(WmsLogTag::DMS, "PostAsyncTask SendCastEventFalse");
854     }
855 }
856 
PhyMirrorConnectWakeupScreen()857 void ScreenSessionManager::PhyMirrorConnectWakeupScreen()
858 {
859 #ifdef WM_MULTI_SCREEN_ENABLE
860     if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "mirror") {
861         TLOGI(WmsLogTag::DMS, "Connect to an external screen to wakeup the phone screen");
862         FixPowerStatus();
863     }
864 #endif
865 }
866 
GetIsCurrentInUseById(ScreenId screenId)867 bool ScreenSessionManager::GetIsCurrentInUseById(ScreenId screenId)
868 {
869     auto session = GetScreenSession(screenId);
870     if (session == nullptr) {
871         TLOGE(WmsLogTag::DMS, "session not found");
872         return false;
873     }
874     if (!session->GetIsCurrentInUse()) {
875         TLOGE(WmsLogTag::DMS, "session not in use");
876         return false;
877     }
878     return true;
879 }
880 
SetMultiScreenDefaultRelativePosition()881 void ScreenSessionManager::SetMultiScreenDefaultRelativePosition()
882 {
883 #ifdef WM_MULTI_SCREEN_ENABLE
884     MultiScreenPositionOptions mainOptions;
885     MultiScreenPositionOptions extendOptions;
886     sptr<ScreenSession> mainSession = nullptr;
887     sptr<ScreenSession> extendSession = nullptr;
888     for (auto sessionIt : screenSessionMap_) {
889         auto screenSession = sessionIt.second;
890         if (screenSession == nullptr) {
891             TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64,
892                 sessionIt.first);
893             continue;
894         }
895         if (screenSession->GetIsRealScreen()) {
896             if (screenSession->GetIsExtend() && extendSession == nullptr) {
897                 extendSession = screenSession;
898             } else {
899                 mainSession = screenSession;
900             }
901         }
902     }
903     if (extendSession != nullptr && mainSession != nullptr) {
904         ScreenProperty mainProperty = mainSession->GetScreenProperty();
905         int32_t mainWidth = mainProperty.GetBounds().rect_.GetWidth();
906         int32_t mainHeight = mainProperty.GetBounds().rect_.GetHeight();
907         if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && GetIsExtendScreenConnected() &&
908             mainHeight > mainWidth) {
909             mainWidth = mainHeight;
910         }
911         mainOptions = { mainSession->GetScreenId(), 0, 0 };
912         extendOptions = { extendSession->GetScreenId(), mainWidth, 0 };
913         auto ret = SetMultiScreenRelativePosition(mainOptions, extendOptions);
914         if (ret != DMError::DM_OK) {
915             TLOGE(WmsLogTag::DMS, "set Relative Position failed, DMError:%{public}d", static_cast<int32_t>(ret));
916         }
917     }
918 #endif
919 }
920 
GetAndMergeEdidInfo(sptr<ScreenSession> screenSession)921 void ScreenSessionManager::GetAndMergeEdidInfo(sptr<ScreenSession> screenSession)
922 {
923     ScreenId screenId = screenSession->GetScreenId();
924     struct BaseEdid edid;
925     if (!GetEdid(screenId, edid)) {
926         TLOGE(WmsLogTag::DMS, "get EDID failed.");
927         return;
928     }
929     std::string serialNumber = ConvertEdidToString(edid);
930     screenSession->SetSerialNumber(serialNumber);
931     if (g_isPcDevice) {
932         screenSession->SetName(edid.manufacturerName_ + std::to_string(screenSession->GetScreenId()));
933     }
934 }
935 
ConvertEdidToString(const struct BaseEdid edid)936 std::string ScreenSessionManager::ConvertEdidToString(const struct BaseEdid edid)
937 {
938     std::string edidInfo = "_";
939     edidInfo = edidInfo + std::to_string(edid.serialNumber_);
940     return edidInfo;
941 }
942 
RecoverRestoredMultiScreenMode(sptr<ScreenSession> screenSession)943 bool ScreenSessionManager::RecoverRestoredMultiScreenMode(sptr<ScreenSession> screenSession)
944 {
945 #ifdef WM_MULTI_SCREEN_ENABLE
946     if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL) {
947         TLOGI(WmsLogTag::DMS, "not real screen, no need recover");
948         return true;
949     }
950     std::map<std::string, MultiScreenInfo> multiScreenInfoMap = ScreenSettingHelper::GetMultiScreenInfo();
951     if (multiScreenInfoMap.empty()) {
952         TLOGE(WmsLogTag::DMS, "no restored screen, use default mode!");
953         return false;
954     }
955     std::string serialNumber = screenSession->GetSerialNumber();
956     if (serialNumber.size() == 0) {
957         TLOGE(WmsLogTag::DMS, "serialNumber empty!");
958         return false;
959     }
960     if (multiScreenInfoMap.find(serialNumber) == multiScreenInfoMap.end()) {
961         TLOGE(WmsLogTag::DMS, "screen not found, use default mode!");
962         return false;
963     }
964 
965     auto info = multiScreenInfoMap[serialNumber];
966     if (info.isExtendMain) {
967         info.mainScreenOption.screenId_ = screenSession->GetScreenId();
968     } else {
969         info.secondaryScreenOption.screenId_ = screenSession->GetScreenId();
970     }
971     if (info.multiScreenMode == MultiScreenMode::SCREEN_MIRROR) {
972         SetMultiScreenMode(info.mainScreenOption.screenId_, info.secondaryScreenOption.screenId_, info.multiScreenMode);
973         TLOGW(WmsLogTag::DMS, "mirror, return befor OnScreenConnectionChanged");
974         ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_MIRROR);
975         return true;
976     }
977     NotifyScreenModeChange();
978     if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
979         SetMultiScreenMode(info.mainScreenOption.screenId_, info.secondaryScreenOption.screenId_,
980             info.multiScreenMode);
981     } else {
982         clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenSession->GetScreenId()),
983             ScreenEvent::CONNECTED);
984     }
985     auto ret = SetMultiScreenRelativePosition(info.mainScreenOption, info.secondaryScreenOption);
986     if (ret != DMError::DM_OK) {
987         SetMultiScreenDefaultRelativePosition();
988     }
989     ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_EXTEND);
990     return true;
991 #else
992     return false;
993 #endif
994 }
995 
ReportHandleScreenEvent(ScreenEvent screenEvent,ScreenCombination screenCombination)996 void ScreenSessionManager::ReportHandleScreenEvent(ScreenEvent screenEvent, ScreenCombination screenCombination)
997 {
998     MultiScreenMode multiScreenMode;
999     if (screenCombination == ScreenCombination::SCREEN_EXTEND) {
1000         multiScreenMode = MultiScreenMode::SCREEN_EXTEND;
1001     } else {
1002         multiScreenMode = MultiScreenMode::SCREEN_MIRROR;
1003     }
1004     int32_t ret = HiSysEventWrite(
1005         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
1006         "EXTEND_DISPLAY_PLUG_IN_AND_OUT",
1007         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
1008         "PLUG_IN_AND_OUT", static_cast<int32_t>(screenEvent),
1009         "DISPLAY_CONNECT_NUM", connectScreenNumber_,
1010         "DISPLAY_INUSED_NUM", GetCurrentInUseScreenNumber(),
1011         "EXTENSION_DISPLAY_MODE_STATUS", static_cast<int32_t>(multiScreenMode),
1012         "MAIN_DISPLAY_ID", GetInternalScreenId());
1013     if (ret != 0) {
1014         TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d", ret);
1015     }
1016 }
1017 
GetCurrentInUseScreenNumber()1018 int32_t ScreenSessionManager::GetCurrentInUseScreenNumber()
1019 {
1020     int32_t inUseScreenNumber_ = 0;
1021     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1022     for (auto sessionIt : screenSessionMap_) {
1023         auto screenSession = sessionIt.second;
1024         if (screenSession == nullptr) {
1025             TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
1026             continue;
1027         }
1028         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
1029             screenSession->GetIsCurrentInUse()) {
1030             TLOGI(WmsLogTag::DMS, "found screenId = %{public}" PRIu64, sessionIt.first);
1031             inUseScreenNumber_++;
1032         }
1033     }
1034     return inUseScreenNumber_;
1035 }
1036 
SetCastPrivacyToRS(sptr<ScreenSession> screenSession,bool enable)1037 bool ScreenSessionManager::SetCastPrivacyToRS(sptr<ScreenSession> screenSession, bool enable)
1038 {
1039     bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId());
1040     if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL || !phyMirrorEnable) {
1041         TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"",
1042             screenSession->GetScreenId());
1043         return false;
1044     }
1045     ScreenId rsScreenId = INVALID_SCREEN_ID;
1046     if (!screenIdManager_.ConvertToRsScreenId(screenSession->GetScreenId(), rsScreenId) ||
1047         rsScreenId == INVALID_SCREEN_ID) {
1048         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
1049         return false;
1050     }
1051     rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, enable);
1052     return true;
1053 }
1054 
SetCastPrivacyFromSettingData()1055 void ScreenSessionManager::SetCastPrivacyFromSettingData()
1056 {
1057     bool enable = true;
1058     bool isOK = ScreenSettingHelper::GetSettingCast(enable);
1059     TLOGI(WmsLogTag::DMS, "get setting cast done, isOK: %{public}u, enable: %{public}u", isOK, enable);
1060     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1061     for (const auto& sessionIt : screenSessionMap_) {
1062         auto screenSession = sessionIt.second;
1063         if (screenSession == nullptr) {
1064             TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first);
1065             continue;
1066         }
1067         bool isSuc = SetCastPrivacyToRS(screenSession, enable);
1068         TLOGI(WmsLogTag::DMS, "set cast privacy done, isSuc:%{public}d, enable:%{public}d, screenId:%{public}" PRIu64"",
1069             isSuc, enable, sessionIt.first);
1070     }
1071 }
1072 
RegisterSettingWireCastObserver(sptr<ScreenSession> & screenSession)1073 void ScreenSessionManager::RegisterSettingWireCastObserver(sptr<ScreenSession>& screenSession)
1074 {
1075     if (screenSession == nullptr) {
1076         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
1077         return;
1078     }
1079     bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId());
1080     if (!g_isPcDevice && phyMirrorEnable && screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL) {
1081         TLOGI(WmsLogTag::DMS, "Register Setting wire cast Observer");
1082         SettingObserver::UpdateFunc updateFunc = [this](const std::string& key) { SetCastPrivacyFromSettingData(); };
1083         ScreenSettingHelper::RegisterSettingWireCastObserver(updateFunc);
1084     }
1085 }
1086 
UnregisterSettingWireCastObserver(ScreenId screenId)1087 void ScreenSessionManager::UnregisterSettingWireCastObserver(ScreenId screenId)
1088 {
1089     if (g_isPcDevice) {
1090         return;
1091     }
1092     for (const auto& sessionIt : screenSessionMap_) {
1093         auto screenSession = sessionIt.second;
1094         if (screenSession == nullptr) {
1095             TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first);
1096             continue;
1097         }
1098         bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId());
1099         if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL || !phyMirrorEnable) {
1100             TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"", sessionIt.first);
1101             continue;
1102         }
1103         if (screenSession ->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR &&
1104             screenSession->GetScreenId() != screenId) {
1105             return;
1106         }
1107     }
1108     ScreenSettingHelper::UnregisterSettingWireCastObserver();
1109     TLOGI(WmsLogTag::DMS, "unregister Setting wire cast Observer");
1110 }
1111 
HandleScreenConnectEvent(sptr<ScreenSession> screenSession,ScreenId screenId,ScreenEvent screenEvent)1112 void ScreenSessionManager::HandleScreenConnectEvent(sptr<ScreenSession> screenSession,
1113     ScreenId screenId, ScreenEvent screenEvent)
1114 {
1115     bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
1116     HandlePhysicalMirrorConnect(screenSession, phyMirrorEnable);
1117 #ifdef FOLD_ABILITY_ENABLE
1118     if (foldScreenController_ != nullptr) {
1119         if ((screenId == 0 || (screenId == SCREEN_ID_MAIN && isCoordinationFlag_ == true)) &&
1120             clientProxy_) {
1121             TLOGW(WmsLogTag::DMS, "event: connect %{public}" PRIu64 ", %{public}" PRIu64 ", "
1122                 "name=%{public}s", screenId, screenSession->GetRSScreenId(), screenSession->GetName().c_str());
1123             clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1124         }
1125         return;
1126     }
1127 #endif
1128     if (clientProxy_ && g_isPcDevice) {
1129         SetExtendedScreenFallbackPlan(screenId);
1130         if (g_outerOnly == ONLY_OUTER_SCREEN_VALUE) {
1131             if (screenId != SCREEN_ID_FULL) {
1132                 defaultScreenId_ = screenId;
1133                 TLOGW(WmsLogTag::DMS, "event screen %{public}" PRIu64, screenId);
1134                 clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1135                 CallRsSetScreenPowerStatusSync(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
1136             }
1137         } else {
1138             if (!RecoverRestoredMultiScreenMode(screenSession)) {
1139                 clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1140                 SetMultiScreenDefaultRelativePosition();
1141                 ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_EXTEND);
1142             }
1143         }
1144     }
1145     if (clientProxy_ && !g_isPcDevice && !phyMirrorEnable) {
1146         TLOGW(WmsLogTag::DMS, "screen connect and notify to scb.");
1147         clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1148     }
1149     if (phyMirrorEnable) {
1150         NotifyScreenConnected(screenSession->ConvertToScreenInfo());
1151         NotifyDisplayCreate(screenSession->ConvertToDisplayInfo());
1152     }
1153     TLOGW(WmsLogTag::DMS, "connect end. ScreenId: %{public}" PRIu64, screenId);
1154 }
1155 
HandleScreenDisconnectEvent(sptr<ScreenSession> screenSession,ScreenId screenId,ScreenEvent screenEvent)1156 void ScreenSessionManager::HandleScreenDisconnectEvent(sptr<ScreenSession> screenSession,
1157     ScreenId screenId, ScreenEvent screenEvent)
1158 {
1159     bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
1160     if (phyMirrorEnable) {
1161         NotifyDisplayDestroy(screenSession->GetScreenId());
1162         NotifyCastWhenScreenConnectChange(false);
1163         FreeDisplayMirrorNodeInner(screenSession);
1164         if (!g_isPcDevice) {
1165             std::vector<ScreenId> screenIdsToExclude = { screenId };
1166             if (!HasCastEngineOrPhyMirror(screenIdsToExclude)) {
1167                 ScreenPowerUtils::DisablePowerForceTimingOut();
1168                 ScreenPowerUtils::LightAndLockScreen("light and lock screen");
1169             }
1170         }
1171     }
1172     HandlePCScreenDisconnect(screenSession);
1173     if (clientProxy_) {
1174         TLOGW(WmsLogTag::DMS, "screen disconnect and notify to scb.");
1175         clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), ScreenEvent::DISCONNECTED);
1176     }
1177 #ifdef WM_MULTI_SCREEN_ENABLE
1178     HandleExtendScreenDisconnect(screenId);
1179 #endif
1180     {
1181         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1182         screenSessionMap_.erase(screenId);
1183     }
1184     if (g_isPcDevice) {
1185         ScreenCombination screenCombination = screenSession->GetScreenCombination();
1186         ReportHandleScreenEvent(ScreenEvent::DISCONNECTED, screenCombination);
1187         SetMultiScreenFrameControl();
1188     }
1189     if (!(screenId == SCREEN_ID_MAIN && isCoordinationFlag_ == true)) {
1190         std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
1191         phyScreenPropMap_.erase(screenId);
1192     }
1193     if (phyMirrorEnable) {
1194         NotifyScreenDisconnected(screenSession->GetScreenId());
1195         isPhyScreenConnected_ = false;
1196     }
1197     if (!g_isPcDevice && phyMirrorEnable) {
1198         UnregisterSettingWireCastObserver(screenId);
1199     }
1200     TLOGW(WmsLogTag::DMS, "disconnect success. ScreenId: %{public}" PRIu64 "", screenId);
1201 }
1202 
HandlePhysicalMirrorConnect(sptr<ScreenSession> screenSession,bool phyMirrorEnable)1203 void ScreenSessionManager::HandlePhysicalMirrorConnect(sptr<ScreenSession> screenSession, bool phyMirrorEnable)
1204 {
1205     if (phyMirrorEnable) {
1206         PhyMirrorConnectWakeupScreen();
1207         NotifyCastWhenScreenConnectChange(true);
1208         isPhyScreenConnected_ = true;
1209         RegisterSettingWireCastObserver(screenSession);
1210         if (!g_isPcDevice) {
1211             ScreenPowerUtils::EnablePowerForceTimingOut();
1212             DisablePowerOffRenderControl(0);
1213         }
1214     }
1215 }
1216 
HandlePCScreenDisconnect(sptr<ScreenSession> screenSession)1217 void ScreenSessionManager::HandlePCScreenDisconnect(sptr<ScreenSession> screenSession)
1218 {
1219     ScreenCombination screenCombination = screenSession->GetScreenCombination();
1220     if (g_isPcDevice) {
1221         if (screenCombination == ScreenCombination::SCREEN_MAIN ||
1222             screenCombination == ScreenCombination::SCREEN_EXTEND) {
1223             TLOGW(WmsLogTag::DMS, "need to change screen");
1224             ScreenId internalScreenId = GetInternalScreenId();
1225             sptr<ScreenSession> internalSession = GetScreenSession(internalScreenId);
1226             if (screenCombination == ScreenCombination::SCREEN_EXTEND) {
1227 #ifdef WM_MULTI_SCREEN_ENABLE
1228                 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_EXIT_STR);
1229 #endif
1230             }
1231         } else {
1232 #ifdef WM_MULTI_SCREEN_ENABLE
1233             MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_MIRROR, MULTI_SCREEN_EXIT_STR);
1234 #endif
1235             NotifyCaptureStatusChanged(false);
1236         }
1237         MultiScreenPositionOptions defaultOptions = { GetDefaultScreenId(), 0, 0 };
1238         SetRelativePositionForDisconnect(defaultOptions);
1239         FreeDisplayMirrorNodeInner(screenSession);
1240     }
1241 }
1242 
OnHgmRefreshRateChange(uint32_t refreshRate)1243 void ScreenSessionManager::OnHgmRefreshRateChange(uint32_t refreshRate)
1244 {
1245     GetDefaultScreenId();
1246     TLOGD(WmsLogTag::DMS, "Set refreshRate: %{public}u, defaultScreenId: %{public}" PRIu64"",
1247         refreshRate, defaultScreenId_);
1248     sptr<ScreenSession> screenSession = GetScreenSession(defaultScreenId_);
1249     if (screenSession) {
1250         screenSession->UpdateRefreshRate(refreshRate);
1251         NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
1252             DisplayChangeEvent::UPDATE_REFRESHRATE);
1253     } else {
1254         TLOGE(WmsLogTag::DMS, "Get default screen session failed.");
1255     }
1256     return;
1257 }
1258 
IsPhysicalScreenAndInUse(sptr<ScreenSession> screenSession) const1259 bool ScreenSessionManager::IsPhysicalScreenAndInUse(sptr<ScreenSession> screenSession) const
1260 {
1261     if (!screenSession) {
1262         return false;
1263     }
1264     if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
1265         screenSession->GetIsCurrentInUse()) {
1266         return true;
1267     }
1268     return false;
1269 }
1270 
SetMultiScreenFrameControl(void)1271 void ScreenSessionManager::SetMultiScreenFrameControl(void)
1272 {
1273 #ifdef WM_MULTI_SCREEN_CTL_ABILITY_ENABLE
1274     uint32_t count = 0;
1275     {
1276         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1277         for (auto sessionIt : screenSessionMap_) {
1278             if (IsPhysicalScreenAndInUse(sessionIt.second)) {
1279                 count++;
1280             }
1281         }
1282     }
1283     if (count >= NUMBER_OF_PHYSICAL_SCREEN) {
1284         TLOGW(WmsLogTag::DMS, "MultiScreen control frame rate to 60");
1285         EventInfo event = { "VOTER_MUTIPHSICALSCREEN", ADD_VOTE, OLED_60_HZ, OLED_60_HZ };
1286         rsInterface_.NotifyRefreshRateEvent(event);
1287     } else {
1288         TLOGW(WmsLogTag::DMS, "Disabling frame rate control");
1289         EventInfo event = { "VOTER_MUTIPHSICALSCREEN", REMOVE_VOTE };
1290         rsInterface_.NotifyRefreshRateEvent(event);
1291     }
1292 #endif
1293 }
1294 
GetScreenSession(ScreenId screenId) const1295 sptr<ScreenSession> ScreenSessionManager::GetScreenSession(ScreenId screenId) const
1296 {
1297     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1298     if (screenSessionMap_.empty()) {
1299         screenEventTracker_.LogWarningAllInfos();
1300     }
1301     auto iter = screenSessionMap_.find(screenId);
1302     if (iter == screenSessionMap_.end()) {
1303         TLOGW(WmsLogTag::DMS, "not found screen session id: %{public}" PRIu64" and create new.", screenId);
1304         return nullptr;
1305     }
1306     return iter->second;
1307 }
1308 
GetDefaultScreenSession()1309 sptr<ScreenSession> ScreenSessionManager::GetDefaultScreenSession()
1310 {
1311     GetDefaultScreenId();
1312     return GetScreenSession(defaultScreenId_);
1313 }
1314 
HookDisplayInfoByUid(sptr<DisplayInfo> displayInfo,const sptr<ScreenSession> & screenSession)1315 sptr<DisplayInfo> ScreenSessionManager::HookDisplayInfoByUid(sptr<DisplayInfo> displayInfo,
1316     const sptr<ScreenSession>& screenSession)
1317 {
1318     if (displayInfo == nullptr) {
1319         TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1320         return nullptr;
1321     }
1322     auto uid = IPCSkeleton::GetCallingUid();
1323     std::shared_lock<std::shared_mutex> lock(hookInfoMutex_);
1324     if (displayHookMap_.find(uid) != displayHookMap_.end()) {
1325         auto info = displayHookMap_[uid];
1326         TLOGI(WmsLogTag::DMS, "hW: %{public}u, hH: %{public}u, hD: %{public}f, hR: %{public}u, hER: %{public}d, "
1327             "dW: %{public}u, dH: %{public}u, dR: %{public}u, dO: %{public}u", info.width_, info.height_, info.density_,
1328             info.rotation_, info.enableHookRotation_, displayInfo->GetWidth(), displayInfo->GetHeight(),
1329             displayInfo->GetRotation(), displayInfo->GetDisplayOrientation());
1330 
1331         displayInfo->SetWidth(info.width_);
1332         displayInfo->SetHeight(info.height_);
1333         displayInfo->SetVirtualPixelRatio(info.density_);
1334         if (info.enableHookRotation_) {
1335             if (screenSession) {
1336                 Rotation targetRotation = screenSession->ConvertIntToRotation(static_cast<int32_t>(info.rotation_));
1337                 displayInfo->SetRotation(targetRotation);
1338                 DisplayOrientation targetOrientation = screenSession->CalcDisplayOrientation(targetRotation,
1339                     FoldDisplayMode::UNKNOWN, IsOrientationNeedChanged());
1340                 TLOGI(WmsLogTag::DMS, "tR: %{public}u, tO: %{public}u", targetRotation, targetOrientation);
1341                 displayInfo->SetDisplayOrientation(targetOrientation);
1342             } else {
1343                 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, screenSession is nullptr.");
1344                 return nullptr;
1345             }
1346         }
1347     }
1348     return displayInfo;
1349 }
1350 
GetDefaultDisplayInfo()1351 sptr<DisplayInfo> ScreenSessionManager::GetDefaultDisplayInfo()
1352 {
1353     GetDefaultScreenId();
1354     sptr<ScreenSession> screenSession = GetScreenSession(defaultScreenId_);
1355     std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
1356     if (screenSession) {
1357         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1358         if (displayInfo == nullptr) {
1359             TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1360             return nullptr;
1361         }
1362         // 在PC/PAD上安装的竖屏应用以及白名单中的应用在显示状态非全屏时需要hook displayinfo
1363         displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
1364         return displayInfo;
1365     } else {
1366         TLOGE(WmsLogTag::DMS, "failed");
1367         return nullptr;
1368     }
1369 }
1370 
GetDisplayInfoById(DisplayId displayId)1371 sptr<DisplayInfo> ScreenSessionManager::GetDisplayInfoById(DisplayId displayId)
1372 {
1373     TLOGD(WmsLogTag::DMS, "enter, displayId: %{public}" PRIu64" ", displayId);
1374     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1375     for (auto sessionIt : screenSessionMap_) {
1376         auto screenSession = sessionIt.second;
1377         if (screenSession == nullptr) {
1378             TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64 "",
1379                 sessionIt.first);
1380             continue;
1381         }
1382         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1383         if (displayInfo == nullptr) {
1384             TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1385             continue;
1386         }
1387         if (displayId == displayInfo->GetDisplayId()) {
1388             TLOGD(WmsLogTag::DMS, "success");
1389             displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
1390             return displayInfo;
1391         }
1392         if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1393             continue;
1394         }
1395         if (!screenSession->GetScreenProperty().GetIsFakeInUse()) {
1396             continue;
1397         }
1398         sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
1399         if (fakeScreenSession == nullptr) {
1400             TLOGE(WmsLogTag::DMS, "error, fakeScreenSession is nullptr.");
1401             continue;
1402         }
1403         sptr<DisplayInfo> fakeDisplayInfo = fakeScreenSession->ConvertToDisplayInfo();
1404         if (fakeDisplayInfo == nullptr) {
1405             TLOGE(WmsLogTag::DMS, "error, fakeDisplayInfo is nullptr.");
1406             continue;
1407         }
1408         fakeDisplayInfo = HookDisplayInfoByUid(fakeDisplayInfo, fakeScreenSession);
1409         DisplayId fakeDisplayId = fakeDisplayInfo->GetDisplayId();
1410         if (displayId == fakeDisplayId) {
1411             TLOGD(WmsLogTag::DMS, "find fake success");
1412             return fakeDisplayInfo;
1413         }
1414     }
1415     TLOGE(WmsLogTag::DMS, "GetDisplayInfoById failed. displayId: %{public}" PRIu64" ", displayId);
1416     return nullptr;
1417 }
1418 
GetVisibleAreaDisplayInfoById(DisplayId displayId)1419 sptr<DisplayInfo> ScreenSessionManager::GetVisibleAreaDisplayInfoById(DisplayId displayId)
1420 {
1421     TLOGD(WmsLogTag::DMS, "enter, displayId: %{public}" PRIu64" ", displayId);
1422     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1423     for (auto sessionIt : screenSessionMap_) {
1424         auto screenSession = sessionIt.second;
1425         if (screenSession == nullptr) {
1426             TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64 "",
1427                 sessionIt.first);
1428             continue;
1429         }
1430         sptr<DisplayInfo> displayInfo = screenSession->ConvertToRealDisplayInfo();
1431         if (displayInfo == nullptr) {
1432             TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1433             continue;
1434         }
1435         if (displayId != displayInfo->GetDisplayId()) {
1436             continue;
1437         }
1438         TLOGD(WmsLogTag::DMS, "success");
1439         displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
1440         if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1441             return displayInfo;
1442         }
1443 #ifdef FOLD_ABILITY_ENABLE
1444         SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
1445         RRect bounds = screenSession->GetScreenProperty().GetBounds();
1446         auto screenWdith = bounds.rect_.GetWidth();
1447         auto screenHeight = bounds.rect_.GetHeight();
1448         if (status == SuperFoldStatus::KEYBOARD) {
1449             if (screenWdith > screenHeight) {
1450                 std::swap(screenWdith, screenHeight);
1451             }
1452             DMRect creaseRect = screenSession->GetScreenProperty().GetCreaseRect();
1453             if (creaseRect.posY_ > 0) {
1454                 displayInfo->SetHeight(creaseRect.posY_);
1455             } else {
1456                 displayInfo->SetHeight(screenHeight / HALF_SCREEN_PARAM);
1457             }
1458             displayInfo->SetWidth(screenWdith);
1459         } else {
1460             displayInfo->SetWidth(screenWdith);
1461             displayInfo->SetHeight(screenHeight);
1462         }
1463         return displayInfo;
1464 #endif
1465     }
1466     TLOGE(WmsLogTag::DMS, "GetVisibleAreaDisplayInfoById failed. displayId: %{public}" PRIu64" ", displayId);
1467     return nullptr;
1468 }
1469 
GetDisplayInfoByScreen(ScreenId screenId)1470 sptr<DisplayInfo> ScreenSessionManager::GetDisplayInfoByScreen(ScreenId screenId)
1471 {
1472     TLOGD(WmsLogTag::DMS, "enter, screenId: %{public}" PRIu64"", screenId);
1473     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1474     for (auto sessionIt : screenSessionMap_) {
1475         auto screenSession = sessionIt.second;
1476         if (screenSession == nullptr) {
1477             TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId:%{public}" PRIu64"",
1478                 sessionIt.first);
1479             continue;
1480         }
1481         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1482         if (displayInfo == nullptr) {
1483             TLOGI(WmsLogTag::DMS, "error, displayInfo is nullptr.");
1484             continue;
1485         }
1486         if (screenId == displayInfo->GetScreenId()) {
1487             return displayInfo;
1488         }
1489     }
1490     TLOGE(WmsLogTag::DMS, "failed. screenId: %{public}" PRIu64" ", screenId);
1491     return nullptr;
1492 }
1493 
GetFakeDisplayId(sptr<ScreenSession> screenSession)1494 DisplayId ScreenSessionManager::GetFakeDisplayId(sptr<ScreenSession> screenSession)
1495 {
1496     sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
1497     if (fakeScreenSession == nullptr) {
1498         TLOGE(WmsLogTag::DMS, "error, fakeScreenSession is nullptr.");
1499         return DISPLAY_ID_INVALID;
1500     }
1501     sptr<DisplayInfo> fakeDisplayInfo = fakeScreenSession->ConvertToDisplayInfo();
1502     if (fakeDisplayInfo == nullptr) {
1503         TLOGE(WmsLogTag::DMS, "error, fakeDisplayInfo is nullptr.");
1504         return DISPLAY_ID_INVALID;
1505     }
1506     DisplayId fakeDisplayId = fakeDisplayInfo->GetDisplayId();
1507     return fakeDisplayId;
1508 }
1509 
GetAllDisplayIds()1510 std::vector<DisplayId> ScreenSessionManager::GetAllDisplayIds()
1511 {
1512     TLOGI(WmsLogTag::DMS, "enter");
1513     std::vector<DisplayId> res;
1514     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1515     for (auto sessionIt : screenSessionMap_) {
1516         auto screenSession = sessionIt.second;
1517         if (screenSession == nullptr) {
1518             TLOGE(WmsLogTag::DMS, "screenSession is nullptr, ScreenId:%{public}" PRIu64"",
1519                 sessionIt.first);
1520             continue;
1521         }
1522         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1523         if (displayInfo == nullptr) {
1524             TLOGE(WmsLogTag::DMS, "error, displayInfo is nullptr.");
1525             continue;
1526         }
1527         DisplayId displayId = displayInfo->GetDisplayId();
1528         res.push_back(displayId);
1529         if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1530             continue;
1531         }
1532         if (!screenSession->GetScreenProperty().GetIsFakeInUse()) {
1533             continue;
1534         }
1535         DisplayId fakeDisplayId = GetFakeDisplayId(screenSession);
1536         if (fakeDisplayId == DISPLAY_ID_FAKE) {
1537             res.push_back(fakeDisplayId);
1538             TLOGI(WmsLogTag::DMS, "add fakeDisplayId: %{public}" PRIu64 "", fakeDisplayId);
1539         }
1540     }
1541     return res;
1542 }
1543 
CalculateXYPosition(sptr<ScreenSession> screenSession)1544 void ScreenSessionManager::CalculateXYPosition(sptr<ScreenSession> screenSession)
1545 {
1546     if (screenSession == nullptr) {
1547         TLOGI(WmsLogTag::DMS, "screenSession is nullptr");
1548         return;
1549     }
1550     if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && screenSession->isInternal_) {
1551         screenSession->SetXYPosition(0, 0);
1552     } else {
1553         ScreenId internalScreenId = GetInternalScreenId();
1554         sptr<ScreenSession> internalSession = GetScreenSession(internalScreenId);
1555         if (internalSession == nullptr) {
1556             TLOGI(WmsLogTag::DMS, "internalSession is nullptr");
1557             return;
1558         }
1559         ScreenProperty internalScreenProperty = internalSession->GetScreenProperty();
1560         ScreenProperty secondaryScreenProperty = screenSession->GetScreenProperty();
1561         int32_t internalX = internalScreenProperty.GetStartX();
1562         int32_t internalY = internalScreenProperty.GetStartY();
1563         int32_t secondaryX = secondaryScreenProperty.GetStartX();
1564         int32_t secondaryY = secondaryScreenProperty.GetStartY();
1565         secondaryX = secondaryX + ~internalX + 1;
1566         secondaryY = secondaryY + ~internalY + 1;
1567         screenSession->SetXYPosition(secondaryX, secondaryY);
1568     }
1569 }
1570 
GetScreenInfoById(ScreenId screenId)1571 sptr<ScreenInfo> ScreenSessionManager::GetScreenInfoById(ScreenId screenId)
1572 {
1573     if (!SessionPermission::IsSystemCalling() &&
1574         !Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION)) {
1575         TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
1576             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1577         return nullptr;
1578     }
1579     auto screenSession = GetScreenSession(screenId);
1580     if (screenSession == nullptr) {
1581         TLOGE(WmsLogTag::DMS, "cannot find screenInfo: %{public}" PRIu64"", screenId);
1582         return nullptr;
1583     }
1584     return screenSession->ConvertToScreenInfo();
1585 }
1586 
SetScreenActiveMode(ScreenId screenId,uint32_t modeId)1587 DMError ScreenSessionManager::SetScreenActiveMode(ScreenId screenId, uint32_t modeId)
1588 {
1589 #ifdef WM_SCREEN_ACTIVE_MODE_ENABLE
1590     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", modeId: %{public}u", screenId, modeId);
1591     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1592         TLOGE(WmsLogTag::DMS, "Permission Denied!  calling: %{public}s, calling pid: %{public}d",
1593             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1594         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1595     }
1596     if (screenId == SCREEN_ID_INVALID) {
1597         TLOGE(WmsLogTag::DMS, "invalid screenId");
1598         return DMError::DM_ERROR_NULLPTR;
1599     }
1600     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1601     if (screenSession == nullptr) {
1602         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1603         return DMError::DM_ERROR_NULLPTR;
1604     }
1605     ScreenId rsScreenId = SCREEN_ID_INVALID;
1606     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
1607         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
1608         return DMError::DM_ERROR_NULLPTR;
1609     }
1610     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetScreenActiveMode(%" PRIu64", %u)", screenId, modeId);
1611     rsInterface_.SetScreenActiveMode(rsScreenId, modeId);
1612     screenSession->activeIdx_ = static_cast<int32_t>(modeId);
1613     screenSession->UpdatePropertyByActiveMode();
1614     ScreenProperty property = screenSession->GetScreenProperty();
1615     property.SetPropertyChangeReason("active mode change");
1616     screenSession->PropertyChange(property, ScreenPropertyChangeReason::CHANGE_MODE);
1617     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
1618     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
1619 #endif
1620     return DMError::DM_OK;
1621 }
1622 
ConvertScreenIdToRsScreenId(ScreenId screenId,ScreenId & rsScreenId)1623 bool ScreenSessionManager::ConvertScreenIdToRsScreenId(ScreenId screenId, ScreenId& rsScreenId)
1624 {
1625     return screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
1626 }
1627 
UpdateDisplayHookInfo(int32_t uid,bool enable,const DMHookInfo & hookInfo)1628 void ScreenSessionManager::UpdateDisplayHookInfo(int32_t uid, bool enable, const DMHookInfo& hookInfo)
1629 {
1630     TLOGD(WmsLogTag::DMS, "DisplayHookInfo will update");
1631     if (!SessionPermission::IsSystemCalling()) {
1632         TLOGE(WmsLogTag::DMS, "permission denied!");
1633         return;
1634     }
1635 
1636     std::unique_lock<std::shared_mutex> lock(hookInfoMutex_);
1637     if (enable) {
1638         if (uid != 0) {
1639             displayHookMap_[uid] = hookInfo;
1640         }
1641     } else {
1642         displayHookMap_.erase(uid);
1643     }
1644 }
1645 
GetDisplayHookInfo(int32_t uid,DMHookInfo & hookInfo)1646 void ScreenSessionManager::GetDisplayHookInfo(int32_t uid, DMHookInfo& hookInfo)
1647 {
1648     std::shared_lock<std::shared_mutex> lock(hookInfoMutex_);
1649     if (displayHookMap_.find(uid) != displayHookMap_.end()) {
1650         hookInfo = displayHookMap_[uid];
1651     }
1652 }
1653 
IsFreezed(const int32_t & agentPid,const DisplayManagerAgentType & agentType)1654 bool ScreenSessionManager::IsFreezed(const int32_t& agentPid, const DisplayManagerAgentType& agentType)
1655 {
1656     std::lock_guard<std::mutex> lock(freezedPidListMutex_);
1657     if (freezedPidList_.count(agentPid) == 0) {
1658         return false;
1659     }
1660     // 冻结的应用记录应用 pid 和注册的 agentType
1661     if (pidAgentTypeMap_.count(agentPid) == 0) {
1662         std::set agentTypes = { agentType };
1663         pidAgentTypeMap_[agentPid] = agentTypes;
1664     } else {
1665         pidAgentTypeMap_[agentPid].insert(agentType);
1666     }
1667     TLOGD(WmsLogTag::DMS, "Agent is freezed, no need notify. PID: %{public}d.", agentPid);
1668     return true;
1669 }
1670 
NotifyScreenChanged(sptr<ScreenInfo> screenInfo,ScreenChangeEvent event)1671 void ScreenSessionManager::NotifyScreenChanged(sptr<ScreenInfo> screenInfo, ScreenChangeEvent event)
1672 {
1673     if (screenInfo == nullptr) {
1674         TLOGE(WmsLogTag::DMS, "error, screenInfo is nullptr.");
1675         return;
1676     }
1677     {
1678         std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
1679         lastScreenChangeEvent_ = event;
1680     }
1681     auto task = [=] {
1682         auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
1683         TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", agent size: %{public}u",
1684             screenInfo->GetScreenId(), static_cast<uint32_t>(agents.size()));
1685         if (agents.empty()) {
1686             return;
1687         }
1688         for (auto& agent : agents) {
1689             int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
1690             if (!IsFreezed(agentPid, DisplayManagerAgentType::SCREEN_EVENT_LISTENER)) {
1691                 agent->OnScreenChange(screenInfo, event);
1692             }
1693         }
1694     };
1695     taskScheduler_->PostAsyncTask(task, "NotifyScreenChanged:SID:" + std::to_string(screenInfo->GetScreenId()));
1696 }
1697 
SetVirtualPixelRatio(ScreenId screenId,float virtualPixelRatio)1698 DMError ScreenSessionManager::SetVirtualPixelRatio(ScreenId screenId, float virtualPixelRatio)
1699 {
1700     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1701         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
1702             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1703         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1704     }
1705 
1706     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1707     if (!screenSession) {
1708         TLOGE(WmsLogTag::DMS, "screen session is nullptr");
1709         return DMError::DM_ERROR_UNKNOWN;
1710     }
1711     if (screenSession->isScreenGroup_) {
1712         TLOGE(WmsLogTag::DMS, "cannot set virtual pixel ratio to the combination. screen: %{public}" PRIu64"",
1713             screenId);
1714         return DMError::DM_ERROR_NULLPTR;
1715     }
1716     // less to 1e-6 mean equal
1717     if (fabs(screenSession->GetScreenProperty().GetVirtualPixelRatio() - virtualPixelRatio) < 1e-6) {
1718         TLOGE(WmsLogTag::DMS,
1719             "The density is equivalent to the original value, no update operation is required, aborted.");
1720         return DMError::DM_OK;
1721     }
1722     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetVirtualPixelRatio(%" PRIu64", %f)", screenId,
1723         virtualPixelRatio);
1724     screenSession->SetVirtualPixelRatio(virtualPixelRatio);
1725     std::map<DisplayId, sptr<DisplayInfo>> emptyMap;
1726     OnPropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::VIRTUAL_PIXEL_RATIO_CHANGE,
1727         screenId);
1728     NotifyDisplayStateChange(screenId, screenSession->ConvertToDisplayInfo(),
1729         emptyMap, DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE);
1730     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::VIRTUAL_PIXEL_RATIO_CHANGED);
1731     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
1732         DisplayChangeEvent::DISPLAY_VIRTUAL_PIXEL_RATIO_CHANGED);
1733     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && screenSession->GetScreenProperty().GetIsFakeInUse()) {
1734         sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
1735         if (fakeScreenSession == nullptr) {
1736             TLOGE(WmsLogTag::DMS, "error,fakeScreenSession is nullptr.");
1737             return DMError::DM_OK;
1738         }
1739         fakeScreenSession->SetVirtualPixelRatio(virtualPixelRatio);
1740     }
1741     return DMError::DM_OK;
1742 }
1743 
SetVirtualPixelRatioSystem(ScreenId screenId,float virtualPixelRatio)1744 DMError ScreenSessionManager::SetVirtualPixelRatioSystem(ScreenId screenId, float virtualPixelRatio)
1745 {
1746     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1747         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
1748             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1749         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1750     }
1751 
1752     if (clientProxy_) {
1753         clientProxy_->SetVirtualPixelRatioSystem(screenId, virtualPixelRatio);
1754     }
1755     return DMError::DM_OK;
1756 }
1757 
SetDefaultDensityDpi(ScreenId screenId,float virtualPixelRatio)1758 DMError ScreenSessionManager::SetDefaultDensityDpi(ScreenId screenId, float virtualPixelRatio)
1759 {
1760     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1761         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
1762             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1763         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1764     }
1765 
1766     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1767     if (!screenSession) {
1768         TLOGE(WmsLogTag::DMS, "screen session is nullptr");
1769         return DMError::DM_ERROR_UNKNOWN;
1770     }
1771     if (screenSession->isScreenGroup_) {
1772         TLOGE(WmsLogTag::DMS, "cannot set virtual pixel ratio to the combination. screen: %{public}" PRIu64"",
1773             screenId);
1774         return DMError::DM_ERROR_NULLPTR;
1775     }
1776     // less to 1e-6 mean equal
1777     if (fabs(screenSession->GetScreenProperty().GetDefaultDensity() - virtualPixelRatio) < 1e-6) {
1778         TLOGE(WmsLogTag::DMS,
1779             "The density is equivalent to the original value, no update operation is required, aborted.");
1780         return DMError::DM_OK;
1781     }
1782     screenSession->SetDefaultDensity(virtualPixelRatio);
1783     return DMError::DM_OK;
1784 }
1785 
SetResolution(ScreenId screenId,uint32_t width,uint32_t height,float virtualPixelRatio)1786 DMError ScreenSessionManager::SetResolution(ScreenId screenId, uint32_t width, uint32_t height, float virtualPixelRatio)
1787 {
1788     TLOGI(WmsLogTag::DMS,
1789         "ScreenId: %{public}" PRIu64 ", w: %{public}u, h: %{public}u, virtualPixelRatio: %{public}f",
1790         screenId, width, height, virtualPixelRatio);
1791     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1792         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
1793             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1794         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1795     }
1796     if (screenId == SCREEN_ID_INVALID) {
1797         TLOGE(WmsLogTag::DMS, "invalid screenId");
1798         return DMError::DM_ERROR_NULLPTR;
1799     }
1800     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1801     if (screenSession == nullptr) {
1802         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1803         return DMError::DM_ERROR_NULLPTR;
1804     }
1805     sptr<SupportedScreenModes> screenSessionModes = screenSession->GetActiveScreenMode();
1806     if (screenSessionModes == nullptr) {
1807         return DMError::DM_ERROR_NULLPTR;
1808     }
1809     if (width <= 0 || width > screenSessionModes->width_ ||
1810         height <= 0 || height > screenSessionModes->height_ ||
1811         virtualPixelRatio < (static_cast<float>(DOT_PER_INCH_MINIMUM_VALUE) / DOT_PER_INCH) ||
1812         virtualPixelRatio > (static_cast<float>(DOT_PER_INCH_MAXIMUM_VALUE) / DOT_PER_INCH)) {
1813         TLOGE(WmsLogTag::DMS, "invalid param! w:%{public}u h:%{public}u min:%{public}f max:%{public}f",
1814             screenSessionModes->width_, screenSessionModes->height_,
1815             static_cast<float>(DOT_PER_INCH_MINIMUM_VALUE) / DOT_PER_INCH,
1816             static_cast<float>(DOT_PER_INCH_MAXIMUM_VALUE) / DOT_PER_INCH);
1817         return DMError::DM_ERROR_INVALID_PARAM;
1818     }
1819     screenSession->SetDensityInCurResolution(virtualPixelRatio);
1820     DMError ret = SetVirtualPixelRatio(screenId, virtualPixelRatio);
1821     if (ret != DMError::DM_OK) {
1822         TLOGE(WmsLogTag::DMS, "Failed to setVirtualPixelRatio when settingResolution");
1823         screenSession->SetDensityInCurResolution(screenSession->GetScreenProperty().GetVirtualPixelRatio());
1824         return ret;
1825     }
1826     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetResolution(%" PRIu64", %u, %u, %f)",
1827         screenId, width, height, virtualPixelRatio);
1828     screenSession->UpdatePropertyByResolution(width, height);
1829     screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::CHANGE_MODE);
1830     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
1831     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
1832     return DMError::DM_OK;
1833 }
1834 
GetDensityInCurResolution(ScreenId screenId,float & virtualPixelRatio)1835 DMError ScreenSessionManager::GetDensityInCurResolution(ScreenId screenId, float& virtualPixelRatio)
1836 {
1837     DmsXcollie dmsXcollie("DMS:GetDensityInCurResolution", XCOLLIE_TIMEOUT_10S);
1838     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1839     if (screenSession == nullptr) {
1840         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1841         return DMError::DM_ERROR_NULLPTR;
1842     }
1843 
1844     virtualPixelRatio = screenSession->GetScreenProperty().GetDensityInCurResolution();
1845     return DMError::DM_OK;
1846 }
1847 
GetScreenColorGamut(ScreenId screenId,ScreenColorGamut & colorGamut)1848 DMError ScreenSessionManager::GetScreenColorGamut(ScreenId screenId, ScreenColorGamut& colorGamut)
1849 {
1850 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
1851     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 "", screenId);
1852     if (screenId == SCREEN_ID_INVALID) {
1853         TLOGE(WmsLogTag::DMS, "screenId invalid");
1854         return DMError::DM_ERROR_INVALID_PARAM;
1855     }
1856     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1857     if (screenSession == nullptr) {
1858         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1859         return DMError::DM_ERROR_INVALID_PARAM;
1860     }
1861     return screenSession->GetScreenColorGamut(colorGamut);
1862 #else
1863     return DMError::DM_OK;
1864 #endif
1865 }
1866 
SetScreenColorGamut(ScreenId screenId,int32_t colorGamutIdx)1867 DMError ScreenSessionManager::SetScreenColorGamut(ScreenId screenId, int32_t colorGamutIdx)
1868 {
1869 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
1870     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1871         TLOGE(WmsLogTag::DMS, "permission denied!");
1872         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1873     }
1874 
1875     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", colorGamutIdx %{public}d",
1876         screenId, colorGamutIdx);
1877     if (screenId == SCREEN_ID_INVALID) {
1878         TLOGE(WmsLogTag::DMS, "screenId invalid");
1879         return DMError::DM_ERROR_INVALID_PARAM;
1880     }
1881     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1882     if (screenSession == nullptr) {
1883         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1884         return DMError::DM_ERROR_INVALID_PARAM;
1885     }
1886     return screenSession->SetScreenColorGamut(colorGamutIdx);
1887 #else
1888     return DMError::DM_OK;
1889 #endif
1890 }
1891 
GetScreenGamutMap(ScreenId screenId,ScreenGamutMap & gamutMap)1892 DMError ScreenSessionManager::GetScreenGamutMap(ScreenId screenId, ScreenGamutMap& gamutMap)
1893 {
1894 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
1895     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 "", screenId);
1896     if (screenId == SCREEN_ID_INVALID) {
1897         TLOGE(WmsLogTag::DMS, "screenId invalid");
1898         return DMError::DM_ERROR_INVALID_PARAM;
1899     }
1900     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1901     if (screenSession == nullptr) {
1902         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1903         return DMError::DM_ERROR_INVALID_PARAM;
1904     }
1905     return screenSession->GetScreenGamutMap(gamutMap);
1906 #else
1907     return DMError::DM_OK;
1908 #endif
1909 }
1910 
SetScreenGamutMap(ScreenId screenId,ScreenGamutMap gamutMap)1911 DMError ScreenSessionManager::SetScreenGamutMap(ScreenId screenId, ScreenGamutMap gamutMap)
1912 {
1913 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
1914     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1915         TLOGE(WmsLogTag::DMS, "permission denied!");
1916         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1917     }
1918 
1919     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", ScreenGamutMap %{public}u",
1920         screenId, static_cast<uint32_t>(gamutMap));
1921     if (screenId == SCREEN_ID_INVALID) {
1922         TLOGE(WmsLogTag::DMS, "screenId invalid");
1923         return DMError::DM_ERROR_INVALID_PARAM;
1924     }
1925     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1926     if (screenSession == nullptr) {
1927         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1928         return DMError::DM_ERROR_INVALID_PARAM;
1929     }
1930     return screenSession->SetScreenGamutMap(gamutMap);
1931 #else
1932     return DMError::DM_OK;
1933 #endif
1934 }
1935 
SetScreenColorTransform(ScreenId screenId)1936 DMError ScreenSessionManager::SetScreenColorTransform(ScreenId screenId)
1937 {
1938     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1939         TLOGE(WmsLogTag::DMS, "permission denied!");
1940         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1941     }
1942 
1943     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 "", screenId);
1944     if (screenId == SCREEN_ID_INVALID) {
1945         TLOGE(WmsLogTag::DMS, "screenId invalid");
1946         return DMError::DM_ERROR_INVALID_PARAM;
1947     }
1948     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1949     if (screenSession == nullptr) {
1950         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1951         return DMError::DM_ERROR_INVALID_PARAM;
1952     }
1953     return screenSession->SetScreenColorTransform();
1954 }
1955 
GetPhysicalScreenSession(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)1956 sptr<ScreenSession> ScreenSessionManager::GetPhysicalScreenSession(ScreenId screenId, ScreenId defScreenId,
1957     ScreenProperty property)
1958 {
1959     sptr<ScreenSession> screenSession = nullptr;
1960     ScreenSessionConfig config;
1961     if (g_isPcDevice) {
1962         if (g_outerOnly == ONLY_OUTER_SCREEN_VALUE) {
1963             config = {
1964                 .screenId = screenId,
1965                 .rsId = screenId,
1966                 .property = property,
1967             };
1968         } else {
1969             config = {
1970                 .screenId = screenId,
1971                 .rsId = screenId,
1972                 .defaultScreenId = defScreenId,
1973                 .property = property,
1974             };
1975         }
1976         screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_REAL);
1977     } else {
1978         sptr<ScreenSession> defaultScreen = GetDefaultScreenSession();
1979         if (defaultScreen == nullptr || defaultScreen->GetDisplayNode() == nullptr) {
1980             TLOGE(WmsLogTag::DMS, "default screen null");
1981             return screenSession;
1982         }
1983         NodeId nodeId = defaultScreen->GetDisplayNode()->GetId();
1984         TLOGI(WmsLogTag::DMS, "physical mirror screen nodeId: %{public}" PRIu64, nodeId);
1985         config = {
1986             .screenId = screenId,
1987             .defaultScreenId = defScreenId,
1988             .mirrorNodeId = nodeId,
1989             .property = property,
1990         };
1991         screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_MIRROR);
1992         screenSession->SetIsPhysicalMirrorSwitch(true);
1993 #ifdef FOLD_ABILITY_ENABLE
1994         if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
1995             DMRect mainScreenRegion = {0, 0, 0, 0};
1996             foldScreenController_->SetMainScreenRegion(mainScreenRegion);
1997             screenSession->SetMirrorScreenRegion(screenId, mainScreenRegion);
1998             screenSession->EnableMirrorScreenRegion();
1999         }
2000 #endif
2001     }
2002     return screenSession;
2003 }
2004 
CreatePhysicalMirrorSessionInner(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)2005 sptr<ScreenSession> ScreenSessionManager::CreatePhysicalMirrorSessionInner(ScreenId screenId, ScreenId defScreenId,
2006     ScreenProperty property)
2007 {
2008 #ifdef WM_MULTI_SCREEN_ENABLE
2009     sptr<ScreenSession> screenSession = nullptr;
2010     if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
2011         TLOGW(WmsLogTag::DMS, "mirror disabled by edm!");
2012         return screenSession;
2013     }
2014     screenSession = GetPhysicalScreenSession(screenId, defScreenId, property);
2015     if (!screenSession) {
2016         TLOGE(WmsLogTag::DMS, "screenSession is null");
2017         return nullptr;
2018     }
2019     MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_ENTER_STR);
2020     HandleExtendScreenConnect(screenId);
2021     if (g_isPcDevice) {
2022         // pc is none, pad&&phone is mirror
2023         InitExtendScreenProperty(screenId, screenSession, property);
2024         screenSession->SetName("ExtendedDisplay");
2025         if (g_outerOnly == ONLY_OUTER_SCREEN_VALUE) {
2026             screenSession->SetIsExtend(false);
2027             screenSession->SetScreenCombination(ScreenCombination::SCREEN_MAIN);
2028         } else {
2029             screenSession->SetIsExtend(true);
2030             screenSession->SetScreenCombination(ScreenCombination::SCREEN_EXTEND);
2031         }
2032     } else {
2033         screenSession->SetIsExtend(true);
2034         screenSession->SetName("CastEngine");
2035         screenSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
2036     }
2037     GetAndMergeEdidInfo(screenSession);
2038     screenSession->SetMirrorScreenType(MirrorScreenType::PHYSICAL_MIRROR);
2039     screenSession->SetIsPcUse(g_isPcDevice ? true : false);
2040     screenSession->SetIsInternal(false);
2041     screenSession->SetIsRealScreen(true);
2042     screenSession->SetIsCurrentInUse(true);
2043     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE);
2044     if (!g_isPcDevice) {
2045         hdmiScreenCount_ = hdmiScreenCount_ + 1;
2046         NotifyCaptureStatusChanged();
2047     }
2048     return screenSession;
2049 #else
2050     return nullptr;
2051 #endif
2052 }
2053 
GetScreenSessionInner(ScreenId screenId,ScreenProperty property)2054 sptr<ScreenSession> ScreenSessionManager::GetScreenSessionInner(ScreenId screenId, ScreenProperty property)
2055 {
2056     ScreenId defScreenId = GetDefaultScreenId();
2057     TLOGW(WmsLogTag::DMS, "screenId:%{public}" PRIu64 "", screenId);
2058     if (IsDefaultMirrorMode(screenId)) {
2059 #ifdef WM_MULTI_SCREEN_ENABLE
2060         return CreatePhysicalMirrorSessionInner(screenId, defScreenId, property);
2061 #else
2062         return nullptr;
2063 #endif
2064     }
2065     std::string screenName = "UNKNOWN";
2066     if (screenId == SCREEN_ID_MAIN) {
2067         screenName = "SubScreen";
2068     }
2069     ScreenSessionConfig config = {
2070         .screenId = screenId,
2071         .defaultScreenId = defScreenId,
2072         .name = screenName,
2073         .property = property,
2074     };
2075     sptr<ScreenSession> screenSession = nullptr;
2076     if (g_isPcDevice && g_outerOnly == ONLY_OUTER_SCREEN_VALUE) {
2077         return screenSession;
2078     }
2079     screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_REAL);
2080     screenSession->SetIsExtend(false);
2081     screenSession->SetScreenCombination(ScreenCombination::SCREEN_MAIN);
2082     screenSession->SetIsInternal(true);
2083     screenSession->SetIsRealScreen(true);
2084     screenSession->SetIsCurrentInUse(true);
2085     screenSession->SetIsPcUse(g_isPcDevice ? true : false);
2086     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
2087         InitFakeScreenSession(screenSession);
2088     }
2089     return screenSession;
2090 }
2091 
CreateScreenProperty(ScreenId screenId,ScreenProperty & property)2092 void ScreenSessionManager::CreateScreenProperty(ScreenId screenId, ScreenProperty& property)
2093 {
2094     int id = HiviewDFX::XCollie::GetInstance().SetTimer("CreateScreenPropertyCallRS", XCOLLIE_TIMEOUT_10S, nullptr,
2095         nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
2096     TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenActiveMode ScreenId: %{public}" PRIu64, screenId);
2097     auto screenMode = rsInterface_.GetScreenActiveMode(screenId);
2098     TLOGW(WmsLogTag::DMS, "get screenWidth: %{public}d, screenHeight: %{public}d",
2099         static_cast<uint32_t>(screenMode.GetScreenWidth()), static_cast<uint32_t>(screenMode.GetScreenHeight()));
2100     auto screenBounds = RRect({ 0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight() }, 0.0f, 0.0f);
2101     auto screenRefreshRate = screenMode.GetScreenRefreshRate();
2102     TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenCapability ScreenId: %{public}" PRIu64, screenId);
2103     auto screenCapability = rsInterface_.GetScreenCapability(screenId);
2104     HiviewDFX::XCollie::GetInstance().CancelTimer(id);
2105     TLOGW(WmsLogTag::DMS, "Call RS interface end, create ScreenProperty begin");
2106     InitScreenProperty(screenId, screenMode, screenCapability, property);
2107 
2108     if (isDensityDpiLoad_) {
2109         if (screenId == SCREEN_ID_MAIN) {
2110             TLOGW(WmsLogTag::DMS, "subDensityDpi_ = %{public}f", subDensityDpi_);
2111             property.SetVirtualPixelRatio(subDensityDpi_);
2112             property.SetDefaultDensity(subDensityDpi_);
2113             property.SetDensityInCurResolution(subDensityDpi_);
2114         } else {
2115             TLOGW(WmsLogTag::DMS, "densityDpi_ = %{public}f", densityDpi_);
2116             property.SetVirtualPixelRatio(densityDpi_);
2117             property.SetDefaultDensity(densityDpi_);
2118             property.SetDensityInCurResolution(densityDpi_);
2119         }
2120     } else {
2121         property.UpdateVirtualPixelRatio(screenBounds);
2122     }
2123     property.SetRefreshRate(screenRefreshRate);
2124     property.SetDefaultDeviceRotationOffset(defaultDeviceRotationOffset_);
2125 #ifdef FOLD_ABILITY_ENABLE
2126     if (foldScreenController_ != nullptr && screenId == 0
2127         && (SCREEN_ROTATION_OFFSET == ROTATION_90 || SCREEN_ROTATION_OFFSET == ROTATION_270)) {
2128         screenBounds = RRect({ 0, 0, screenMode.GetScreenHeight(), screenMode.GetScreenWidth() }, 0.0f, 0.0f);
2129         property.SetBounds(screenBounds);
2130     }
2131     sptr<FoldCreaseRegion> creaseRegion = GetCurrentFoldCreaseRegion();
2132     if (creaseRegion != nullptr) {
2133         std::vector<DMRect> creaseRects = creaseRegion->GetCreaseRects();
2134         if (creaseRects.size() > 0) {
2135             property.SetCreaseRect(creaseRects[0]);
2136         }
2137     }
2138 #endif
2139     property.CalcDefaultDisplayOrientation();
2140     property.SetScreenShape(ScreenSettingHelper::GetScreenShape(screenId));
2141 }
2142 
InitScreenProperty(ScreenId screenId,RSScreenModeInfo & screenMode,RSScreenCapability & screenCapability,ScreenProperty & property)2143 void ScreenSessionManager::InitScreenProperty(ScreenId screenId, RSScreenModeInfo& screenMode,
2144     RSScreenCapability& screenCapability, ScreenProperty& property)
2145 {
2146     auto screenBounds = RRect({ 0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight() }, 0.0f, 0.0f);
2147     property.SetRotation(0.0f);
2148     property.SetPhyWidth(screenCapability.GetPhyWidth());
2149     property.SetPhyHeight(screenCapability.GetPhyHeight());
2150     property.SetValidWidth(screenBounds.rect_.width_);
2151     property.SetValidHeight(screenBounds.rect_.height_);
2152     property.SetDpiPhyBounds(screenCapability.GetPhyWidth(), screenCapability.GetPhyHeight());
2153     property.SetPhyBounds(screenBounds);
2154     property.SetBounds(screenBounds);
2155     property.SetAvailableArea({0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight()});
2156     property.SetPhysicalTouchBounds();
2157     property.SetInputOffsetY();
2158     property.SetCurrentOffScreenRendering(false);
2159     property.SetScreenRealWidth(property.GetBounds().rect_.GetWidth());
2160     property.SetScreenRealHeight(property.GetBounds().rect_.GetHeight());
2161     property.SetScreenRealPPI();
2162     property.SetScreenRealDPI();
2163 }
2164 
GetInternalWidth()2165 void ScreenSessionManager::GetInternalWidth()
2166 {
2167     ScreenId screenId = GetInternalScreenId();
2168     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2169     if (screenSession == nullptr) {
2170         TLOGE(WmsLogTag::DMS, "screen session is null");
2171         return;
2172     }
2173     ScreenProperty screenProperty = screenSession->GetScreenProperty();
2174     uint32_t screenWidth = screenProperty.GetScreenRealWidth();
2175     uint32_t screenHeight = screenProperty.GetScreenRealHeight();
2176     g_internalWidth = (screenWidth > screenHeight) ? screenWidth : screenHeight;
2177     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", g_internalWidth is:%{public}u",
2178         screenId, static_cast<uint32_t>(g_internalWidth));
2179     return;
2180 }
2181 
InitExtendScreenProperty(ScreenId screenId,sptr<ScreenSession> session,ScreenProperty property)2182 void ScreenSessionManager::InitExtendScreenProperty(ScreenId screenId, sptr<ScreenSession> session,
2183     ScreenProperty property)
2184 {
2185     if (!g_isPcDevice) {
2186         TLOGW(WmsLogTag::DMS, "not PC device");
2187         return;
2188     }
2189     bool isSupportOffScreenRendering = ScreenSceneConfig::IsSupportOffScreenRendering();
2190     if (!isSupportOffScreenRendering) {
2191         TLOGW(WmsLogTag::DMS, "xml isSupportOffScreenRendering is fasle");
2192         return;
2193     }
2194     GetInternalWidth();
2195     TLOGD(WmsLogTag::DMS, "g_internalWidth: %{public}u", static_cast<uint32_t>(g_internalWidth));
2196     float offScreenPPIThreshold = static_cast<float>(ScreenSceneConfig::GetOffScreenPPIThreshold());
2197     uint32_t screenWidth = property.GetBounds().rect_.GetWidth();
2198     uint32_t screenHeight = property.GetBounds().rect_.GetHeight();
2199     float screenPPI = property.GetScreenRealPPI();
2200     if (screenWidth == 0) {
2201         TLOGE(WmsLogTag::DMS, "screenWidth is zero");
2202         return;
2203     }
2204     if (screenWidth > FOUR_K_WIDTH) {
2205         float scale = static_cast<float>(FOUR_K_WIDTH) / screenWidth;
2206         uint32_t screenAdjustHeight = static_cast<uint32_t>(std::round(screenHeight * scale));
2207         auto screenBounds = RRect({ 0, 0, FOUR_K_WIDTH, screenAdjustHeight }, 0.0f, 0.0f);
2208         session->SetExtendProperty(screenBounds, false);
2209         session->SetAvailableArea({0, 0, FOUR_K_WIDTH, screenAdjustHeight});
2210         TLOGD(WmsLogTag::DMS, "screenWidth > 4K, screenId:%{public}" PRIu64"", screenId);
2211     } else if (screenWidth < THREE_K_WIDTH && screenPPI < offScreenPPIThreshold) {
2212         float scale = static_cast<float>(g_internalWidth) / screenWidth;
2213         uint32_t screenAdjustHeight = static_cast<uint32_t>(std::round(screenHeight * scale));
2214         auto screenBounds = RRect({ 0, 0, g_internalWidth, screenAdjustHeight }, 0.0f, 0.0f);
2215         session->SetExtendProperty(screenBounds, true);
2216         session->SetAvailableArea({0, 0, g_internalWidth, screenAdjustHeight});
2217         TLOGD(WmsLogTag::DMS, "screenWidth < g_internalWidth, screenId:%{public}" PRIu64"", screenId);
2218     } else {
2219         TLOGW(WmsLogTag::DMS, "no need adjust, screenId:%{public}" PRIu64"", screenId);
2220         return;
2221     }
2222     std::ostringstream oss;
2223     oss << "screenId:" << screenId
2224         << ", screenWidth: " <<  session->GetScreenProperty().GetBounds().rect_.GetWidth()
2225         << ", screenHeight: " << session->GetScreenProperty().GetBounds().rect_.GetHeight()
2226         << ", propertyCurrentOffScreenRendering: " << session->GetScreenProperty().GetCurrentOffScreenRendering()
2227         << ", screenPPI: " << screenPPI;
2228     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
2229 }
2230 
SetExtendedScreenFallbackPlan(ScreenId screenId)2231 void ScreenSessionManager::SetExtendedScreenFallbackPlan(ScreenId screenId)
2232 {
2233     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2234     if (screenSession == nullptr) {
2235         TLOGE(WmsLogTag::DMS, "screen session is null");
2236         return;
2237     }
2238     if (screenSession->GetIsInternal()) {
2239         TLOGW(WmsLogTag::DMS, "screen is internal");
2240         return;
2241     }
2242     ScreenProperty screenProperty = screenSession->GetScreenProperty();
2243     if (!screenProperty.GetCurrentOffScreenRendering()) {
2244         TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", propertyCurrentOffScreenRendering is false", screenId);
2245         return;
2246     }
2247     uint32_t screenAdjustWidth = 0;
2248     uint32_t screenAdjustHeight = 0;
2249     if (screenSession ->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
2250         TLOGD(WmsLogTag::DMS, "Screen is mirror");
2251         screenAdjustWidth = screenProperty.GetScreenRealWidth();
2252         screenAdjustHeight = screenProperty.GetScreenRealHeight();
2253     } else {
2254         TLOGD(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", setPhysicalScreenResolution", screenId);
2255         screenAdjustWidth = screenProperty.GetBounds().rect_.GetWidth();
2256         screenAdjustHeight = screenProperty.GetBounds().rect_.GetHeight();
2257     }
2258     ScreenId rsScreenId;
2259     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
2260         TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
2261         return;
2262     }
2263     int32_t res = -1;
2264     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetPhysicalScreenResolution(%" PRIu64")", screenId);
2265     res = rsInterface_.SetPhysicalScreenResolution(rsScreenId, screenAdjustWidth, screenAdjustHeight);
2266     screenSession->Resize(screenAdjustWidth, screenAdjustHeight, false);
2267     if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
2268         screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::UNDEFINED);
2269     }
2270     if (res != StatusCode::SUCCESS) {
2271         TLOGE(WmsLogTag::DMS, "RS SetPhysicalScreenResolution failed.");
2272         screenEventTracker_.RecordEvent("SetPhysicalScreenResolution failed.");
2273     } else {
2274         TLOGD(WmsLogTag::DMS, "RS SetPhysicalScreenResolution success.");
2275         screenEventTracker_.RecordEvent("SetPhysicalScreenResolution success.");
2276     }
2277     std::ostringstream oss;
2278     oss << "screenId:" << screenId << ", screenAdjustWidth: " <<  screenAdjustWidth
2279         << ", screenAdjustHeight: " << screenAdjustHeight;
2280     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
2281 }
2282 
InitExtendScreenDensity(sptr<ScreenSession> session,ScreenProperty property)2283 void ScreenSessionManager::InitExtendScreenDensity(sptr<ScreenSession> session, ScreenProperty property)
2284 {
2285     if (session->GetScreenProperty().GetScreenType() != ScreenType::REAL || session->isInternal_) {
2286         // 表示非拓展屏
2287         TLOGW(WmsLogTag::DMS, "Not expandable screen, no need to set dpi");
2288         return;
2289     }
2290     ScreenId mainScreenId = GetDefaultScreenId();
2291     sptr<ScreenSession> screenSession = GetScreenSession(mainScreenId);
2292     if (screenSession == nullptr) {
2293         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
2294         return;
2295     }
2296     float extendDensity = screenSession->GetScreenProperty().GetDensity();
2297     float curResolution = screenSession->GetScreenProperty().GetDensityInCurResolution();
2298     TLOGW(WmsLogTag::DMS, "extendDensity = %{public}f", extendDensity);
2299     session->SetVirtualPixelRatio(extendDensity * EXTEND_SCREEN_DPI_PARAMETER);
2300     session->SetDefaultDensity(extendDensity * EXTEND_SCREEN_DPI_PARAMETER);
2301     session->SetDensityInCurResolution(curResolution);
2302     ScreenId screenId = session->GetScreenId();
2303     property.SetVirtualPixelRatio(extendDensity * EXTEND_SCREEN_DPI_PARAMETER);
2304     property.SetDefaultDensity(extendDensity* EXTEND_SCREEN_DPI_PARAMETER);
2305     property.SetDensityInCurResolution(curResolution);
2306     {
2307         std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
2308         phyScreenPropMap_[screenId] = property;
2309     }
2310     return;
2311 }
2312 
GetOrCreateScreenSession(ScreenId screenId)2313 sptr<ScreenSession> ScreenSessionManager::GetOrCreateScreenSession(ScreenId screenId)
2314 {
2315     TLOGW(WmsLogTag::DMS, "ENTER. ScreenId: %{public}" PRIu64 "", screenId);
2316     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2317     if (screenSession) {
2318         TLOGW(WmsLogTag::DMS, "screenSession Exist ScreenId: %{public}" PRIu64, screenId);
2319         return screenSession;
2320     }
2321 
2322     if (g_isPcDevice && phyScreenPropMap_.size() > 1) {
2323         // pc is none, pad&&phone is mirror
2324         TLOGW(WmsLogTag::DMS, "Only Support one External screen.");
2325         return nullptr;
2326     }
2327     screenIdManager_.UpdateScreenId(screenId, screenId);
2328 
2329     ScreenProperty property;
2330     CreateScreenProperty(screenId, property);
2331     TLOGW(WmsLogTag::DMS, "call create screen property end");
2332     screenEventTracker_.RecordEvent("CreateScreenProperty by rsInterface success.");
2333     {
2334         std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
2335         phyScreenPropMap_[screenId] = property;
2336     }
2337 
2338     if (HandleFoldScreenSessionCreate(screenId) == false) {
2339         return nullptr;
2340     }
2341 
2342     sptr<ScreenSession> session = GetScreenSessionInner(screenId, property);
2343     if (session == nullptr) {
2344         TLOGE(WmsLogTag::DMS, "get screen session fail ScreenId: %{public}" PRIu64, screenId);
2345         return session;
2346     }
2347     session->RegisterScreenChangeListener(this);
2348     InitExtendScreenDensity(session, property);
2349     InitAbstractScreenModesInfo(session);
2350     session->groupSmsId_ = 1;
2351     {
2352         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2353         screenSessionMap_[screenId] = session;
2354     }
2355     if (g_isPcDevice) {
2356         SetMultiScreenFrameControl();
2357     }
2358     screenEventTracker_.RecordEvent("create screen session success.");
2359     SetHdrFormats(screenId, session);
2360     SetColorSpaces(screenId, session);
2361     RegisterRefreshRateChangeListener();
2362     TLOGW(WmsLogTag::DMS, "CreateScreenSession success. ScreenId: %{public}" PRIu64 "", screenId);
2363     return session;
2364 }
2365 
HandleFoldScreenSessionCreate(ScreenId screenId)2366 bool ScreenSessionManager::HandleFoldScreenSessionCreate(ScreenId screenId)
2367 {
2368 #ifdef FOLD_ABILITY_ENABLE
2369     if (foldScreenController_ != nullptr) {
2370         // sensor may earlier than screen connect, when physical screen property changed, update
2371         foldScreenController_->UpdateForPhyScreenPropertyChange();
2372         /* folder screen outer screenId is 5 */
2373         if (screenId == SCREEN_ID_MAIN) {
2374             SetPostureAndHallSensorEnabled();
2375             ScreenSensorConnector::SubscribeTentSensor();
2376             isFoldScreenOuterScreenReady_ = true;
2377             if (!FoldScreenStateInternel::IsDualDisplayFoldDevice() && isCoordinationFlag_ == false) {
2378                 return false;
2379             }
2380         }
2381     }
2382 #endif
2383     return true;
2384 }
2385 
SetHdrFormats(ScreenId screenId,sptr<ScreenSession> & session)2386 void ScreenSessionManager::SetHdrFormats(ScreenId screenId, sptr<ScreenSession>& session)
2387 {
2388     TLOGI(WmsLogTag::DMS, "SetHdrFormats %{public}" PRIu64, screenId);
2389     std::vector<ScreenHDRFormat> rsHdrFormat;
2390     auto status = rsInterface_.GetScreenSupportedHDRFormats(screenId, rsHdrFormat);
2391     if (static_cast<StatusCode>(status) != StatusCode::SUCCESS) {
2392         TLOGE(WmsLogTag::DMS, "get hdr format failed! status code: %{public}d", status);
2393     } else {
2394         std::vector<uint32_t> hdrFormat(rsHdrFormat.size());
2395         std::transform(rsHdrFormat.begin(), rsHdrFormat.end(), hdrFormat.begin(), [](int val) {
2396             return static_cast<uint32_t>(val);
2397         });
2398         session->SetHdrFormats(std::move(hdrFormat));
2399     }
2400 }
2401 
SetColorSpaces(ScreenId screenId,sptr<ScreenSession> & session)2402 void ScreenSessionManager::SetColorSpaces(ScreenId screenId, sptr<ScreenSession>& session)
2403 {
2404     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2405         TLOGE(WmsLogTag::DMS, "spaces permission denied!");
2406         return;
2407     }
2408 
2409     TLOGI(WmsLogTag::DMS, "SetColorSpaces %{public}" PRIu64, screenId);
2410     std::vector<GraphicCM_ColorSpaceType> rsColorSpace;
2411     auto status = rsInterface_.GetScreenSupportedColorSpaces(screenId, rsColorSpace);
2412     if (static_cast<StatusCode>(status) != StatusCode::SUCCESS) {
2413         TLOGE(WmsLogTag::DMS, "get color space failed! status code: %{public}d", status);
2414     } else {
2415         std::vector<uint32_t> colorSpace(rsColorSpace.size());
2416         std::transform(rsColorSpace.begin(), rsColorSpace.end(), colorSpace.begin(), [](int val) {
2417             return static_cast<uint32_t>(val);
2418         });
2419         session->SetColorSpaces(std::move(colorSpace));
2420     }
2421 }
2422 
GetDefaultScreenId()2423 ScreenId ScreenSessionManager::GetDefaultScreenId()
2424 {
2425     if (defaultScreenId_ == INVALID_SCREEN_ID) {
2426         defaultScreenId_ = rsInterface_.GetDefaultScreenId();
2427         std::ostringstream oss;
2428         oss << "Default screen id : " << defaultScreenId_;
2429         TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
2430         screenEventTracker_.RecordEvent(oss.str());
2431     }
2432     return defaultScreenId_;
2433 }
2434 
WakeUpBegin(PowerStateChangeReason reason)2435 bool ScreenSessionManager::WakeUpBegin(PowerStateChangeReason reason)
2436 {
2437     // 该接口当前只有Power调用
2438     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:WakeUpBegin(%u)", reason);
2439     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2440         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2441             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2442         return false;
2443     }
2444     TLOGI(WmsLogTag::DMS, "[UL_POWER]WakeUpBegin reason: %{public}u", reason);
2445     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_START_DREAM) {
2446         TLOGI(WmsLogTag::DMS, "[UL_POWER]wakeup cannot start dream");
2447         return false;
2448     }
2449     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_END_DREAM) {
2450         NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_END_DREAM, EventStatus::BEGIN, reason);
2451         return BlockScreenWaitPictureFrameByCV(false);
2452     }
2453     currentWakeUpReason_ = reason;
2454     // 多屏协作灭屏不通知锁屏
2455     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
2456         isMultiScreenCollaboration_ = true;
2457         return true;
2458     }
2459     lastWakeUpReason_ = reason;
2460     return NotifyDisplayPowerEvent(DisplayPowerEvent::WAKE_UP, EventStatus::BEGIN, reason);
2461 }
2462 
WakeUpEnd()2463 bool ScreenSessionManager::WakeUpEnd()
2464 {
2465     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:WakeUpEnd");
2466     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2467         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2468             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2469         return false;
2470     }
2471     TLOGI(WmsLogTag::DMS, "[UL_POWER]WakeUpEnd enter");
2472     // 多屏协作灭屏不通知锁屏
2473     if (isMultiScreenCollaboration_) {
2474         isMultiScreenCollaboration_ = false;
2475         return true;
2476     }
2477     return NotifyDisplayPowerEvent(DisplayPowerEvent::WAKE_UP, EventStatus::END,
2478         PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
2479 }
2480 
SuspendBegin(PowerStateChangeReason reason)2481 bool ScreenSessionManager::SuspendBegin(PowerStateChangeReason reason)
2482 {
2483     // only power use
2484     powerStateChangeReason_ = reason;
2485     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:SuspendBegin(%u)", reason);
2486     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2487         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2488             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2489         return false;
2490     }
2491     TLOGI(WmsLogTag::DMS, "[UL_POWER]Reason: %{public}u", static_cast<uint32_t>(reason));
2492     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_END_DREAM) {
2493         TLOGI(WmsLogTag::DMS, "[UL_POWER]suspend cannot end dream");
2494         return false;
2495     }
2496     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_START_DREAM) {
2497         NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_START_DREAM, EventStatus::BEGIN, reason);
2498         return BlockScreenWaitPictureFrameByCV(true);
2499     }
2500     gotScreenlockFingerprint_ = false;
2501     lastWakeUpReason_ = PowerStateChangeReason::STATE_CHANGE_REASON_INIT;
2502     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
2503         lastWakeUpReason_ = PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF;
2504     }
2505     // 多屏协作灭屏不通知锁屏
2506     gotScreenOffNotify_  = false;
2507     if (!g_isPcDevice && reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT &&
2508         reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_SUCCESS &&
2509         reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_ON &&
2510         reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
2511         sessionDisplayPowerController_->canCancelSuspendNotify_ = true;
2512     }
2513     sessionDisplayPowerController_->isSuspendBegin_ = true;
2514     sessionDisplayPowerController_->SuspendBegin(reason);
2515     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
2516         isMultiScreenCollaboration_ = true;
2517         return true;
2518     }
2519     return NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::BEGIN, reason);
2520 }
2521 
SuspendEnd()2522 bool ScreenSessionManager::SuspendEnd()
2523 {
2524     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2525         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2526             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2527         return false;
2528     }
2529     TLOGI(WmsLogTag::DMS, "[UL_POWER] enter");
2530     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:SuspendEnd");
2531     // 多屏协作灭屏不通知锁屏
2532     if (isMultiScreenCollaboration_) {
2533         isMultiScreenCollaboration_ = false;
2534         return true;
2535     }
2536     return NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::END,
2537         PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
2538 }
2539 
GetInternalScreenId()2540 ScreenId ScreenSessionManager::GetInternalScreenId()
2541 {
2542     ScreenId screenId = SCREEN_ID_INVALID;
2543     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2544     for (auto sessionIt : screenSessionMap_) {
2545         auto screenSession = sessionIt.second;
2546         if (screenSession == nullptr) {
2547             TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
2548             continue;
2549         }
2550         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && screenSession->isInternal_) {
2551             TLOGI(WmsLogTag::DMS, "found screenId = %{public}" PRIu64, sessionIt.first);
2552             screenId = sessionIt.first;
2553             break;
2554         }
2555     }
2556     return screenId;
2557 }
2558 
GetInternalAndExternalSession(sptr<ScreenSession> & internalSession,sptr<ScreenSession> & externalSession)2559 void ScreenSessionManager::GetInternalAndExternalSession(sptr<ScreenSession>& internalSession,
2560     sptr<ScreenSession>& externalSession)
2561 {
2562     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2563     for (auto sessionIt : screenSessionMap_) {
2564         auto screenSession = sessionIt.second;
2565         if (screenSession == nullptr) {
2566             TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
2567             continue;
2568         }
2569         if (!screenSession->GetIsCurrentInUse()) {
2570             TLOGE(WmsLogTag::DMS, "screenSession not in use!");
2571             continue;
2572         }
2573         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && screenSession->isInternal_) {
2574             TLOGI(WmsLogTag::DMS, "found internalSession, screenId = %{public}" PRIu64, sessionIt.first);
2575             internalSession = screenSession;
2576         } else {
2577             TLOGI(WmsLogTag::DMS, "found externalSession, screenId = %{public}" PRIu64, sessionIt.first);
2578             externalSession = screenSession;
2579         }
2580     }
2581 }
2582 
SetScreenPowerById(ScreenId screenId,ScreenPowerState state,PowerStateChangeReason reason)2583 bool ScreenSessionManager::SetScreenPowerById(ScreenId screenId, ScreenPowerState state,
2584     PowerStateChangeReason reason)
2585 {
2586     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2587         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2588             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2589         return false;
2590     }
2591 
2592     TLOGI(WmsLogTag::DMS, "screen id:%{public}" PRIu64
2593     ", state:%{public}u, reason:%{public}u", screenId, state, static_cast<uint32_t>(reason));
2594 
2595     sptr<ScreenSession> internalSession;
2596     sptr<ScreenSession> externalSession;
2597     GetInternalAndExternalSession(internalSession, externalSession);
2598     ScreenPowerStatus status;
2599     switch (state) {
2600         case ScreenPowerState::POWER_ON: {
2601             status = ScreenPowerStatus::POWER_STATUS_ON;
2602             MultiScreenManager::GetInstance().InternalScreenOnChange(internalSession, externalSession);
2603             TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_ON");
2604             break;
2605         }
2606         case ScreenPowerState::POWER_OFF: {
2607             status = ScreenPowerStatus::POWER_STATUS_OFF;
2608             MultiScreenManager::GetInstance().InternalScreenOffChange(internalSession, externalSession);
2609             TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_OFF");
2610             break;
2611         }
2612         default: {
2613             TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerById state not support");
2614             return false;
2615         }
2616     }
2617 
2618     CallRsSetScreenPowerStatusSync(screenId, status);
2619     return true;
2620 }
2621 
SetLastScreenMode(sptr<ScreenSession> firstSession,sptr<ScreenSession> secondarySession)2622 void ScreenSessionManager::SetLastScreenMode(sptr<ScreenSession> firstSession, sptr<ScreenSession> secondarySession)
2623 {
2624 #ifdef WM_MULTI_SCREEN_ENABLE
2625     if (firstSession == nullptr || secondarySession == nullptr) {
2626         TLOGE(WmsLogTag::DMS, "first or second screen is null");
2627         return;
2628     }
2629 
2630     ScreenId mainScreenId = SCREEN_ID_INVALID;
2631     MultiScreenMode secondaryScreenMode = MultiScreenMode::SCREEN_MIRROR;
2632     {
2633         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2634         for (auto sessionIt : screenSessionMap_) {
2635             auto screenSession = sessionIt.second;
2636             if (screenSession == nullptr) {
2637                 TLOGW(WmsLogTag::DMS, "screenSession is nullptr!");
2638                 continue;
2639             }
2640             if (screenSession != firstSession && screenSession != secondarySession) {
2641                 continue;
2642             }
2643             if (!screenSession->GetIsCurrentInUse()) {
2644                 TLOGE(WmsLogTag::DMS, "screenSession not in use!");
2645                 continue;
2646             }
2647             ScreenCombination screenCombination = screenSession->GetScreenCombination();
2648             if (screenCombination == ScreenCombination::SCREEN_MAIN) {
2649                 mainScreenId = sessionIt.first;
2650                 TLOGI(WmsLogTag::DMS, "found main screen");
2651             } else if (screenCombination == ScreenCombination::SCREEN_MIRROR) {
2652                 secondaryScreenMode = MultiScreenMode::SCREEN_MIRROR;
2653                 TLOGI(WmsLogTag::DMS, "found mirror screen");
2654             } else if (screenCombination == ScreenCombination::SCREEN_EXTEND) {
2655                 secondaryScreenMode = MultiScreenMode::SCREEN_EXTEND;
2656                 TLOGI(WmsLogTag::DMS, "found extend screen");
2657             } else {
2658                 TLOGE(WmsLogTag::DMS, "screen id or screen mode error");
2659             }
2660         }
2661     }
2662 
2663     if (mainScreenId == SCREEN_ID_INVALID) {
2664         TLOGE(WmsLogTag::DMS, "param error!");
2665         return;
2666     }
2667     MultiScreenManager::GetInstance().SetLastScreenMode(mainScreenId, secondaryScreenMode);
2668 #endif
2669 }
2670 
IsPreBrightAuthFail(void)2671 bool ScreenSessionManager::IsPreBrightAuthFail(void)
2672 {
2673     return lastWakeUpReason_ == PowerStateChangeReason::
2674         STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF;
2675 }
2676 
BlockSetDisplayState(void)2677 bool ScreenSessionManager::BlockSetDisplayState(void)
2678 {
2679     return prePowerStateChangeReason_ == PowerStateChangeReason::POWER_BUTTON;
2680 }
2681 
SetDisplayState(DisplayState state)2682 bool ScreenSessionManager::SetDisplayState(DisplayState state)
2683 {
2684     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2685         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2686             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2687         return false;
2688     }
2689     if (!sessionDisplayPowerController_) {
2690         TLOGE(WmsLogTag::DMS, "[UL_POWER]sessionDisplayPowerController_ is null");
2691         return false;
2692     }
2693     TLOGI(WmsLogTag::DMS, "[UL_POWER] enter");
2694     auto screenIds = GetAllScreenIds();
2695     if (screenIds.empty()) {
2696         TLOGI(WmsLogTag::DMS, "[UL_POWER]no screen info");
2697         return sessionDisplayPowerController_->SetDisplayState(state);
2698     }
2699 
2700     UpdateDisplayState(screenIds, state);
2701     bool ret = sessionDisplayPowerController_->SetDisplayState(state);
2702     if (!ret && state == DisplayState::OFF) {
2703         state = lastDisplayState_;
2704         UpdateDisplayState(screenIds, state);
2705     }
2706     lastDisplayState_ = state;
2707     return ret;
2708 }
2709 
UpdateDisplayState(std::vector<ScreenId> screenIds,DisplayState state)2710 void ScreenSessionManager::UpdateDisplayState(std::vector<ScreenId> screenIds, DisplayState state)
2711 {
2712     for (auto screenId : screenIds) {
2713         sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2714         if (screenSession == nullptr) {
2715             TLOGW(WmsLogTag::DMS, "[UL_POWER] cannot get ScreenSession, screenId: %{public}" PRIu64"",
2716                 screenId);
2717             continue;
2718         }
2719         screenSession->UpdateDisplayState(state);
2720         TLOGI(WmsLogTag::DMS, "[UL_POWER]set screenSession displayState property: %{public}u",
2721             screenSession->GetScreenProperty().GetDisplayState());
2722     }
2723 }
2724 
BlockScreenOnByCV(void)2725 void ScreenSessionManager::BlockScreenOnByCV(void)
2726 {
2727     if (keyguardDrawnDone_ == false) {
2728         TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOnCV_ set");
2729         needScreenOnWhenKeyguardNotify_ = true;
2730         std::unique_lock<std::mutex> lock(screenOnMutex_);
2731         if (screenOnCV_.wait_for(lock, std::chrono::milliseconds(screenOnDelay_)) == std::cv_status::timeout) {
2732             TLOGI(WmsLogTag::DMS, "[UL_POWER]wait ScreenOnCV_ timeout");
2733         }
2734     }
2735 }
2736 
BlockScreenOffByCV(void)2737 void ScreenSessionManager::BlockScreenOffByCV(void)
2738 {
2739     if (gotScreenOffNotify_ == false) {
2740         TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOffCV_ set, delay:%{public}d", screenOffDelay_);
2741         needScreenOffNotify_ = true;
2742         std::unique_lock<std::mutex> lock(screenOffMutex_);
2743         if (screenOffCV_.wait_for(lock, std::chrono::milliseconds(screenOffDelay_)) == std::cv_status::timeout) {
2744             isScreenLockSuspend_ = false;
2745             needScreenOffNotify_ = false;
2746             TLOGI(WmsLogTag::DMS, "[UL_POWER]wait ScreenOffCV_ timeout, isScreenLockSuspend_ is false");
2747         }
2748     }
2749 }
2750 
TryToCancelScreenOff()2751 bool ScreenSessionManager::TryToCancelScreenOff()
2752 {
2753     std::lock_guard<std::mutex> notifyLock(sessionDisplayPowerController_->notifyMutex_);
2754     TLOGI(WmsLogTag::DMS, "[UL_POWER]about to cancel suspend, can:%{public}d, got:%{public}d, need:%{public}d",
2755         sessionDisplayPowerController_->canCancelSuspendNotify_, gotScreenOffNotify_, needScreenOffNotify_);
2756     if (sessionDisplayPowerController_->canCancelSuspendNotify_) {
2757         sessionDisplayPowerController_->needCancelNotify_ = true;
2758         TLOGI(WmsLogTag::DMS, "[UL_POWER]notify cancel screenoff");
2759         ScreenSessionManager::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_OFF_CANCELED,
2760             EventStatus::BEGIN, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
2761         return true;
2762     }
2763     if (gotScreenOffNotify_ == false && needScreenOffNotify_ == true) {
2764         std::unique_lock <std::mutex> lock(screenOffMutex_);
2765         sessionDisplayPowerController_->canceledSuspend_ = true;
2766         screenOffCV_.notify_all();
2767         needScreenOffNotify_ = false;
2768         TLOGI(WmsLogTag::DMS, "[UL_POWER]cancel wait and notify cancel screenoff");
2769         ScreenSessionManager::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_OFF_CANCELED,
2770             EventStatus::BEGIN, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
2771         return true;
2772     }
2773     TLOGW(WmsLogTag::DMS, "[UL_POWER]failed to cancel suspend");
2774     return false;
2775 }
2776 
ForceSkipScreenOffAnimation()2777 void ScreenSessionManager::ForceSkipScreenOffAnimation()
2778 {
2779     std::lock_guard<std::mutex> notifyLock(sessionDisplayPowerController_->notifyMutex_);
2780     TLOGI(WmsLogTag::DMS, "[UL_POWER]about to skip animation, can:%{public}d, got:%{public}d, need:%{public}d",
2781         sessionDisplayPowerController_->canCancelSuspendNotify_, gotScreenOffNotify_, needScreenOffNotify_);
2782     if (sessionDisplayPowerController_->canCancelSuspendNotify_) {
2783         sessionDisplayPowerController_->skipScreenOffBlock_ = true;
2784         TLOGI(WmsLogTag::DMS, "[UL_POWER]skip screenoff animation");
2785         return;
2786     }
2787     if (gotScreenOffNotify_ == false && needScreenOffNotify_ == true) {
2788         std::unique_lock <std::mutex> lock(screenOffMutex_);
2789         screenOffCV_.notify_all();
2790         needScreenOffNotify_ = false;
2791         TLOGI(WmsLogTag::DMS, "[UL_POWER]skip wait");
2792         return;
2793     }
2794 }
2795 
SetScreenBrightness(uint64_t screenId,uint32_t level)2796 bool ScreenSessionManager::SetScreenBrightness(uint64_t screenId, uint32_t level)
2797 {
2798     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2799         TLOGE(WmsLogTag::DMS, "set screen brightness permission denied!");
2800         return false;
2801     }
2802     TLOGD(WmsLogTag::DMS, "screenId:%{public}" PRIu64", level:%{public}u,", screenId, level);
2803     RSInterfaces::GetInstance().SetScreenBacklight(screenId, level);
2804     return true;
2805 }
2806 
GetScreenBrightness(uint64_t screenId)2807 uint32_t ScreenSessionManager::GetScreenBrightness(uint64_t screenId)
2808 {
2809     uint32_t level = static_cast<uint32_t>(RSInterfaces::GetInstance().GetScreenBacklight(screenId));
2810     TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", level:%{public}u,", screenId, level);
2811     return level;
2812 }
2813 
SetScreenOffDelayTime(int32_t delay)2814 int32_t ScreenSessionManager::SetScreenOffDelayTime(int32_t delay)
2815 {
2816     DmsXcollie dmsXcollie("DMS:SetScreenOffDelayTime", XCOLLIE_TIMEOUT_10S);
2817     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2818         TLOGE(WmsLogTag::DMS, "set screen off delay time permission denied!");
2819         return 0;
2820     }
2821 
2822     if (delay > SCREEN_OFF_MIN_DELAY_TIME && delay < CV_WAIT_SCREENOFF_MS) {
2823         screenOffDelay_ = CV_WAIT_SCREENOFF_MS;
2824     } else if (delay > CV_WAIT_SCREENOFF_MS_MAX) {
2825         screenOffDelay_ = CV_WAIT_SCREENOFF_MS_MAX;
2826     } else {
2827         screenOffDelay_ = delay;
2828     }
2829     TLOGI(WmsLogTag::DMS, "delay:%{public}d, screenOffDelay_:%{public}d",
2830         delay, screenOffDelay_);
2831     return screenOffDelay_;
2832 }
2833 
SetScreenOnDelayTime(int32_t delay)2834 int32_t ScreenSessionManager::SetScreenOnDelayTime(int32_t delay)
2835 {
2836     DmsXcollie dmsXcollie("DMS:SetScreenOnDelayTime", XCOLLIE_TIMEOUT_10S);
2837     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2838         TLOGE(WmsLogTag::DMS, "set screen on delay time permission denied!");
2839         return 0;
2840     }
2841 
2842     if (delay > CV_WAIT_SCREENON_MS) {
2843         screenOnDelay_ = CV_WAIT_SCREENON_MS;
2844     } else {
2845         screenOnDelay_ = delay;
2846     }
2847     TLOGI(WmsLogTag::DMS, "delay:%{public}d, screenOnDelay_:%{public}d",
2848         delay, screenOnDelay_);
2849     return screenOnDelay_;
2850 }
2851 
SetCameraStatus(int32_t cameraStatus,int32_t cameraPosition)2852 void ScreenSessionManager::SetCameraStatus(int32_t cameraStatus, int32_t cameraPosition)
2853 {
2854 #ifdef WM_CAM_MODE_ABILITY_ENABLE
2855     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2856         TLOGE(WmsLogTag::DMS, "set camera status permission denied!");
2857         return;
2858     }
2859 
2860     if ((cameraStatus_ == cameraStatus) && (cameraPosition_ == cameraPosition)) {
2861         return;  // no need to update
2862     }
2863     cameraStatus_ = cameraStatus;
2864     cameraPosition_ = cameraPosition;
2865     TLOGI(WmsLogTag::DMS, "SetCameraStatus, cameraStatus:%{public}d, cameraPosition:%{public}d",
2866         cameraStatus, cameraPosition);
2867 #endif
2868 }
2869 
IsScreenLockSuspend(void)2870 bool ScreenSessionManager::IsScreenLockSuspend(void)
2871 {
2872     return isScreenLockSuspend_;
2873 }
2874 
NotifyDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)2875 void ScreenSessionManager::NotifyDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
2876     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
2877 {
2878     if (clientProxy_) {
2879         clientProxy_->OnDisplayStateChanged(defaultDisplayId, displayInfo, displayInfoMap, type);
2880     }
2881 }
2882 
NotifyScreenshot(DisplayId displayId)2883 void ScreenSessionManager::NotifyScreenshot(DisplayId displayId)
2884 {
2885     if (clientProxy_) {
2886         clientProxy_->OnScreenshot(displayId);
2887     }
2888 }
2889 
SetSpecifiedScreenPower(ScreenId screenId,ScreenPowerState state,PowerStateChangeReason reason)2890 bool ScreenSessionManager::SetSpecifiedScreenPower(ScreenId screenId, ScreenPowerState state,
2891     PowerStateChangeReason reason)
2892 {
2893     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2894         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
2895             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2896         return false;
2897     }
2898     TLOGI(WmsLogTag::DMS, "screen id:%{public}" PRIu64 ", state:%{public}u",
2899         screenId, state);
2900 
2901     ScreenPowerStatus status;
2902     switch (state) {
2903         case ScreenPowerState::POWER_ON: {
2904             status = ScreenPowerStatus::POWER_STATUS_ON;
2905             break;
2906         }
2907         case ScreenPowerState::POWER_OFF: {
2908             status = ScreenPowerStatus::POWER_STATUS_OFF;
2909             break;
2910         }
2911         default: {
2912             TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerStatus state not support");
2913             return false;
2914         }
2915     }
2916 
2917     CallRsSetScreenPowerStatusSync(screenId, status);
2918     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
2919         return true;
2920     }
2921     return NotifyDisplayPowerEvent(state == ScreenPowerState::POWER_ON ? DisplayPowerEvent::DISPLAY_ON :
2922         DisplayPowerEvent::DISPLAY_OFF, EventStatus::END, reason);
2923 }
2924 
SetScreenPowerForAll(ScreenPowerState state,PowerStateChangeReason reason)2925 bool ScreenSessionManager::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)
2926 {
2927     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2928         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2929             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2930         return false;
2931     }
2932     TLOGI(WmsLogTag::DMS, "[UL_POWER]state: %{public}u, reason: %{public}u",
2933         static_cast<uint32_t>(state), static_cast<uint32_t>(reason));
2934     ScreenPowerStatus status;
2935 
2936     if (!GetPowerStatus(state, reason, status)) {
2937         return false;
2938     }
2939     gotScreenOffNotify_  = false;
2940     keyguardDrawnDone_ = false;
2941     TLOGI(WmsLogTag::DMS, "keyguardDrawnDone_ is false");
2942     prePowerStateChangeReason_ = reason;
2943     return SetScreenPower(status, reason);
2944 }
2945 
GetPowerStatus(ScreenPowerState state,PowerStateChangeReason reason,ScreenPowerStatus & status)2946 bool ScreenSessionManager::GetPowerStatus(ScreenPowerState state, PowerStateChangeReason reason,
2947     ScreenPowerStatus& status)
2948 {
2949     switch (state) {
2950         case ScreenPowerState::POWER_ON: {
2951             if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT) {
2952                 // 预亮屏
2953                 status = ScreenPowerStatus::POWER_STATUS_ON_ADVANCED;
2954                 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_ON_ADVANCED");
2955             } else {
2956                 status = ScreenPowerStatus::POWER_STATUS_ON;
2957                 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_ON");
2958             }
2959             break;
2960         }
2961         case ScreenPowerState::POWER_OFF: {
2962             if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
2963                 // 预亮屏时指纹认证失败
2964                 status = ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED;
2965                 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_OFF_ADVANCED");
2966             } else {
2967                 status = ScreenPowerStatus::POWER_STATUS_OFF;
2968                 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_OFF");
2969             }
2970             rsInterface_.MarkPowerOffNeedProcessOneFrame();
2971             break;
2972         }
2973         case ScreenPowerState::POWER_SUSPEND: {
2974             status = ScreenPowerStatus::POWER_STATUS_SUSPEND;
2975             TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_SUSPEND");
2976             rsInterface_.MarkPowerOffNeedProcessOneFrame();
2977             break;
2978         }
2979         case ScreenPowerState::POWER_DOZE: {
2980             status = ScreenPowerStatus::POWER_STATUS_DOZE;
2981             TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_DOZE");
2982             break;
2983         }
2984         case ScreenPowerState::POWER_DOZE_SUSPEND: {
2985             status = ScreenPowerStatus::POWER_STATUS_DOZE_SUSPEND;
2986             TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_DOZE_SUSPEND");
2987             break;
2988         }
2989         default: {
2990             TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerStatus state not support");
2991             return false;
2992         }
2993     }
2994     return true;
2995 }
2996 
ExitCoordination(const std::string & reason)2997 void ScreenSessionManager::ExitCoordination(const std::string& reason)
2998 {
2999 #ifdef FOLD_ABILITY_ENABLE
3000     if (GetFoldDisplayMode() != FoldDisplayMode::COORDINATION) {
3001         return;
3002     }
3003     if (foldScreenController_ != nullptr) {
3004         TLOGI(WmsLogTag::DMS, "[UL_POWER] reason:%{public}s", reason.c_str());
3005         foldScreenController_->ExitCoordination();
3006     }
3007 #endif
3008 }
3009 
TryToRecoverFoldDisplayMode(ScreenPowerStatus status)3010 void ScreenSessionManager::TryToRecoverFoldDisplayMode(ScreenPowerStatus status)
3011 {
3012 #ifdef FOLD_ABILITY_ENABLE
3013     if (foldScreenController_ == nullptr) {
3014         TLOGW(WmsLogTag::DMS, "foldScreenController_ is null");
3015         return;
3016     }
3017     if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED ||
3018         status == ScreenPowerStatus::POWER_STATUS_OFF_FAKE || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3019         status == ScreenPowerStatus::POWER_STATUS_DOZE) {
3020         foldScreenController_->RecoverDisplayMode();
3021     }
3022 #endif
3023 }
3024 
SetScreenPower(ScreenPowerStatus status,PowerStateChangeReason reason)3025 bool ScreenSessionManager::SetScreenPower(ScreenPowerStatus status, PowerStateChangeReason reason)
3026 {
3027     TLOGI(WmsLogTag::DMS, "[UL_POWER] enter status:%{public}u", status);
3028     auto screenIds = GetAllScreenIds();
3029     if (screenIds.empty()) {
3030         TLOGI(WmsLogTag::DMS, "[UL_POWER] screenIds empty");
3031         return false;
3032     }
3033 
3034     if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3035         status == ScreenPowerStatus::POWER_STATUS_DOZE) {
3036         ExitCoordination("Press PowerKey");
3037     }
3038     DisplayPowerEvent notifyEvent = DisplayPowerEvent::DISPLAY_OFF;
3039     auto iter = SCREEN_STATUS_POWER_EVENT_MAP.find(status);
3040     if (iter != SCREEN_STATUS_POWER_EVENT_MAP.end()) {
3041         notifyEvent = iter->second;
3042     }
3043     if (((status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3044         status == ScreenPowerStatus::POWER_STATUS_DOZE) &&
3045         gotScreenlockFingerprint_ == true) &&
3046         prePowerStateChangeReason_ != PowerStateChangeReason::STATE_CHANGE_REASON_SHUT_DOWN) {
3047         gotScreenlockFingerprint_ = false;
3048         TLOGI(WmsLogTag::DMS, "[UL_POWER] screenlockFingerprint or shutdown");
3049         return NotifyDisplayPowerEvent(notifyEvent, EventStatus::END, reason);
3050     }
3051 #ifdef FOLD_ABILITY_ENABLE
3052     if (foldScreenController_ != nullptr) {
3053         CallRsSetScreenPowerStatusSyncForFold(status);
3054         CallRsSetScreenPowerStatusSyncForExtend(screenIds, status);
3055         TryToRecoverFoldDisplayMode(status);
3056     } else {
3057         SetRsSetScreenPowerStatusSync(screenIds, status);
3058     }
3059 #else
3060     SetRsSetScreenPowerStatusSync(screenIds, status);
3061 #endif
3062     HandlerSensor(status, reason);
3063     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3064         return true;
3065     }
3066     if ((status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3067         status == ScreenPowerStatus::POWER_STATUS_DOZE) &&
3068         gotScreenlockFingerprint_ == true) {
3069         gotScreenlockFingerprint_ = false;
3070     }
3071 
3072     return NotifyDisplayPowerEvent(notifyEvent, EventStatus::END, reason);
3073 }
3074 
SetRsSetScreenPowerStatusSync(const std::vector<ScreenId> & screenIds,ScreenPowerStatus status)3075 void ScreenSessionManager::SetRsSetScreenPowerStatusSync(const std::vector<ScreenId>& screenIds,
3076     ScreenPowerStatus status)
3077 {
3078     if (!g_isPcDevice) {
3079         for (auto screenId : screenIds) {
3080             CallRsSetScreenPowerStatusSync(screenId, status);
3081         }
3082     } else {
3083         TLOGI(WmsLogTag::DMS, "[UL_POWER] isPcDevice");
3084         for (auto screenId : screenIds) {
3085             if (screenId == SCREEN_ID_DEFAULT) {
3086                 TLOGI(WmsLogTag::DMS, "[UL_POWER] screen id is 0, pass");
3087                 continue;
3088             }
3089             CallRsSetScreenPowerStatusSync(screenId, status);
3090         }
3091         TLOGI(WmsLogTag::DMS, "[UL_POWER] screen 0 power off");
3092         CallRsSetScreenPowerStatusSync(SCREEN_ID_DEFAULT, status);
3093     }
3094 }
3095 
CallRsSetScreenPowerStatusSyncForExtend(const std::vector<ScreenId> & screenIds,ScreenPowerStatus status)3096 void ScreenSessionManager::CallRsSetScreenPowerStatusSyncForExtend(const std::vector<ScreenId>& screenIds,
3097     ScreenPowerStatus status)
3098 {
3099     for (auto screenId : screenIds) {
3100         auto session = GetScreenSession(screenId);
3101         if (session && session->GetScreenProperty().GetScreenType() == ScreenType::REAL && !session->isInternal_) {
3102             CallRsSetScreenPowerStatusSync(screenId, status);
3103         }
3104     }
3105 }
3106 #ifdef FOLD_ABILITY_ENABLE
SetScreenPowerForFold(ScreenPowerStatus status)3107 void ScreenSessionManager::SetScreenPowerForFold(ScreenPowerStatus status)
3108 {
3109     if (foldScreenController_ == nullptr) {
3110         TLOGW(WmsLogTag::DMS, "foldScreenController_ is null");
3111         return;
3112     }
3113     SetScreenPowerForFold(foldScreenController_->GetCurrentScreenId(), status);
3114 }
3115 
SetScreenPowerForFold(ScreenId screenId,ScreenPowerStatus status)3116 void ScreenSessionManager::SetScreenPowerForFold(ScreenId screenId, ScreenPowerStatus status)
3117 {
3118     if (status != ScreenPowerStatus::POWER_STATUS_OFF) {
3119         rsInterface_.SetScreenPowerStatus(screenId, status);
3120         return;
3121     }
3122     ScreenPowerStatus preStatus = rsInterface_.GetScreenPowerStatus(screenId);
3123     if (preStatus != ScreenPowerStatus::POWER_STATUS_ON_ADVANCED) {
3124         rsInterface_.SetScreenPowerStatus(screenId, status);
3125         return;
3126     }
3127     TLOGW(WmsLogTag::DMS,
3128         "screenId = %{public}" PRIu64\
3129         ", prepare set power status %{public}u, set %{public}u instead because preStatus is %{public}u",
3130         screenId,
3131         ScreenPowerStatus::POWER_STATUS_OFF,
3132         ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED,
3133         preStatus
3134     );
3135     rsInterface_.SetScreenPowerStatus(screenId, ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED);
3136 }
3137 
TriggerDisplayModeUpdate(FoldDisplayMode targetDisplayMode)3138 void ScreenSessionManager::TriggerDisplayModeUpdate(FoldDisplayMode targetDisplayMode)
3139 {
3140     auto updateDisplayModeTask = [=] {
3141         TLOGNI(WmsLogTag::DMS, "start change displaymode to lastest mode");
3142         foldScreenController_->SetDisplayMode(targetDisplayMode);
3143     };
3144     taskScheduler_->PostAsyncTask(updateDisplayModeTask, "updateDisplayModeTask");
3145 }
3146 #endif
CallRsSetScreenPowerStatusSync(ScreenId screenId,ScreenPowerStatus status)3147 void ScreenSessionManager::CallRsSetScreenPowerStatusSync(ScreenId screenId, ScreenPowerStatus status)
3148 {
3149     auto rsSetScreenPowerStatusTask = [=] {
3150         bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
3151         if (phyMirrorEnable && !g_isPcDevice) {
3152             auto screenSession = GetScreenSession(screenId);
3153             if (screenSession == nullptr) {
3154                 return;
3155             }
3156             auto sourceMode = screenSession->GetSourceMode();
3157             if (sourceMode == ScreenSourceMode::SCREEN_MIRROR &&
3158                 status != ScreenPowerStatus::POWER_STATUS_ON &&
3159                 powerStateChangeReason_ == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3160                 return;
3161             }
3162             if (sourceMode == ScreenSourceMode::SCREEN_UNIQUE &&
3163                 status != ScreenPowerStatus::POWER_STATUS_ON &&
3164                 powerStateChangeReason_ == PowerStateChangeReason::STATE_CHANGE_REASON_HARD_KEY) {
3165                 return;
3166             }
3167         }
3168         rsInterface_.SetScreenPowerStatus(screenId, status);
3169     };
3170     screenPowerTaskScheduler_->PostVoidSyncTask(rsSetScreenPowerStatusTask, "rsInterface_.SetScreenPowerStatus task");
3171 }
3172 
CallRsSetScreenPowerStatusSyncForFold(ScreenPowerStatus status)3173 void ScreenSessionManager::CallRsSetScreenPowerStatusSyncForFold(ScreenPowerStatus status)
3174 {
3175 #ifdef FOLD_ABILITY_ENABLE
3176     auto rsSetScreenPowerStatusTask = [=] {
3177         if (foldScreenController_ == nullptr) {
3178             TLOGNW(WmsLogTag::DMS, "foldScreenController_ is null");
3179             return;
3180         }
3181         rsInterface_.SetScreenPowerStatus(foldScreenController_->GetCurrentScreenId(), status);
3182     };
3183     screenPowerTaskScheduler_->PostVoidSyncTask(rsSetScreenPowerStatusTask, "rsInterface_.SetScreenPowerStatus task");
3184 #endif
3185 }
3186 
SetKeyguardDrawnDoneFlag(bool flag)3187 void ScreenSessionManager::SetKeyguardDrawnDoneFlag(bool flag)
3188 {
3189     keyguardDrawnDone_ = flag;
3190 }
3191 
HandlerSensor(ScreenPowerStatus status,PowerStateChangeReason reason)3192 void ScreenSessionManager::HandlerSensor(ScreenPowerStatus status, PowerStateChangeReason reason)
3193 {
3194     if (!ScreenSceneConfig::IsSupportRotateWithSensor()) {
3195         TLOGW(WmsLogTag::DMS, "not supportRotateWithSensor.");
3196         return;
3197     }
3198     if (status == ScreenPowerStatus::POWER_STATUS_ON) {
3199         DmsXcollie dmsXcollie("DMS:SubscribeRotationSensor", XCOLLIE_TIMEOUT_10S);
3200         TLOGI(WmsLogTag::DMS, "subscribe rotation and posture sensor when phone turn on");
3201         ScreenSensorConnector::SubscribeRotationSensor();
3202 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
3203         if (g_foldScreenFlag && reason != PowerStateChangeReason::STATE_CHANGE_REASON_DISPLAY_SWITCH) {
3204             if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
3205                 SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
3206                 SecondaryFoldSensorManager::GetInstance().PowerKeySetScreenActiveRect();
3207             } else {
3208                 FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
3209             }
3210         } else {
3211             TLOGI(WmsLogTag::DMS, "not fold product, switch screen reason, failed register posture.");
3212         }
3213 #endif
3214     } else if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3215         status == ScreenPowerStatus::POWER_STATUS_DOZE || status == ScreenPowerStatus::POWER_STATUS_DOZE_SUSPEND) {
3216         UnregisterInHandlerSensorWithPowerOff(reason);
3217     } else {
3218         TLOGI(WmsLogTag::DMS, "SetScreenPower state not support");
3219         screenEventTracker_.RecordEvent("HandlerSensor start!");
3220     }
3221 }
3222 
UnregisterInHandlerSensorWithPowerOff(PowerStateChangeReason reason)3223 void ScreenSessionManager::UnregisterInHandlerSensorWithPowerOff(PowerStateChangeReason reason)
3224 {
3225     TLOGI(WmsLogTag::DMS, "unsubscribe rotation and posture sensor when phone turn off");
3226     if (isMultiScreenCollaboration_) {
3227         TLOGI(WmsLogTag::DMS, "[UL_POWER]MultiScreenCollaboration, not unsubscribe rotation sensor");
3228     } else {
3229         DmsXcollie dmsXcollie("DMS:UnsubscribeRotationSensor", XCOLLIE_TIMEOUT_10S);
3230         ScreenSensorConnector::UnsubscribeRotationSensor();
3231     }
3232 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
3233     if (g_foldScreenFlag && reason != PowerStateChangeReason::STATE_CHANGE_REASON_DISPLAY_SWITCH &&
3234         !FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
3235         if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
3236             SecondaryFoldSensorManager::GetInstance().UnRegisterPostureCallback();
3237             SecondaryFoldSensorManager::GetInstance().isPowerRectExe_ = false;
3238         } else {
3239             FoldScreenSensorManager::GetInstance().UnRegisterPostureCallback();
3240         }
3241     } else {
3242         TLOGI(WmsLogTag::DMS, "not fold product, switch screen reason, failed unregister posture.");
3243     }
3244 #endif
3245 }
3246 
BootFinishedCallback(const char * key,const char * value,void * context)3247 void ScreenSessionManager::BootFinishedCallback(const char *key, const char *value, void *context)
3248 {
3249     if (strcmp(key, BOOTEVENT_BOOT_COMPLETED.c_str()) == 0 && strcmp(value, "true") == 0) {
3250         TLOGI(WmsLogTag::DMS, "boot animation finished");
3251         auto &that = *reinterpret_cast<ScreenSessionManager *>(context);
3252         that.SetRotateLockedFromSettingData();
3253         that.SetDpiFromSettingData();
3254         that.SetDisplayState(DisplayState::ON);
3255         that.RegisterSettingDpiObserver();
3256         if (that.foldScreenPowerInit_ != nullptr) {
3257             that.foldScreenPowerInit_();
3258         }
3259         that.RegisterSettingRotationObserver();
3260         that.RegisterSettingscreenSkipProtectedWindowObserver();
3261         if (that.defaultDpi) {
3262             auto ret = ScreenSettingHelper::SetSettingDefaultDpi(that.defaultDpi, SET_SETTING_DPI_KEY);
3263             if (!ret) {
3264                 TLOGE(WmsLogTag::DMS, "set setting defaultDpi failed");
3265             } else {
3266                 TLOGI(WmsLogTag::DMS, "set setting defaultDpi:%{public}d", that.defaultDpi);
3267             }
3268         }
3269 #ifdef FOLD_ABILITY_ENABLE
3270         if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
3271             auto screenSession = that.GetDefaultScreenSession();
3272             if (screenSession == nullptr) {
3273                 TLOGE(WmsLogTag::DMS, "screen session is null!");
3274                 return;
3275             }
3276             ScreenId screenId = screenSession->GetScreenId();
3277             SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
3278             that.OnSuperFoldStatusChange(screenId, status);
3279             float sensorRotation = screenSession->GetSensorRotation();
3280             if (sensorRotation >= 0.0f) {
3281                 that.OnSensorRotationChange(sensorRotation, screenId);
3282             }
3283             screenSession->PropertyChange(screenSession->GetScreenProperty(),
3284                 ScreenPropertyChangeReason::SUPER_FOLD_STATUS_CHANGE);
3285         }
3286 #endif
3287     }
3288 }
3289 
SetFoldScreenPowerInit(std::function<void ()> foldScreenPowerInit)3290 void ScreenSessionManager::SetFoldScreenPowerInit(std::function<void()> foldScreenPowerInit)
3291 {
3292     foldScreenPowerInit_ = foldScreenPowerInit;
3293 }
3294 
SetRotateLockedFromSettingData()3295 void ScreenSessionManager::SetRotateLockedFromSettingData()
3296 {
3297     uint32_t autoRotateStatus = AUTO_ROTATE_OFF;  // 0代表自动旋转关闭,1代表自动旋转打开
3298     bool islocked = true;
3299     // ret为true表示从数据库读到了值,并赋给了autoRotateStatus
3300     bool ret = ScreenSettingHelper::GetSettingValue(autoRotateStatus, SETTING_LOCKED_KEY);
3301     TLOGI(WmsLogTag::DMS, "get autoRotateStatus from settingdata: %{public}u", autoRotateStatus);
3302     if (autoRotateStatus) {
3303         islocked =false;
3304     }
3305     if (ret) {
3306         TLOGI(WmsLogTag::DMS, "get islocked success");
3307         SetScreenRotationLockedFromJs(islocked);
3308     }
3309 }
3310 
RegisterSettingDpiObserver()3311 void ScreenSessionManager::RegisterSettingDpiObserver()
3312 {
3313     TLOGI(WmsLogTag::DMS, "Register Setting Dpi Observer");
3314     SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetDpiFromSettingData(); };
3315     ScreenSettingHelper::RegisterSettingDpiObserver(updateFunc);
3316 }
3317 
SetDpiFromSettingData()3318 void ScreenSessionManager::SetDpiFromSettingData()
3319 {
3320     uint32_t settingDpi;
3321     bool ret = ScreenSettingHelper::GetSettingDpi(settingDpi);
3322     if (!ret) {
3323         TLOGW(WmsLogTag::DMS, "get setting dpi failed,use default dpi");
3324         settingDpi = defaultDpi;
3325     } else {
3326         TLOGI(WmsLogTag::DMS, "get setting dpi success,settingDpi: %{public}u", settingDpi);
3327     }
3328     if (settingDpi >= DOT_PER_INCH_MINIMUM_VALUE && settingDpi <= DOT_PER_INCH_MAXIMUM_VALUE
3329         && cachedSettingDpi_ != settingDpi) {
3330         cachedSettingDpi_ = settingDpi;
3331         float dpi = static_cast<float>(settingDpi) / BASELINE_DENSITY;
3332         ScreenId defaultScreenId = GetDefaultScreenId();
3333         SetVirtualPixelRatio(defaultScreenId, dpi);
3334         if (g_isPcDevice) {
3335             SetExtendPixelRatio(dpi * EXTEND_SCREEN_DPI_PARAMETER);
3336         }
3337     } else {
3338         TLOGE(WmsLogTag::DMS, "setting dpi error, settingDpi: %{public}d", settingDpi);
3339     }
3340 }
3341 
SetExtendPixelRatio(const float & dpi)3342 void ScreenSessionManager::SetExtendPixelRatio(const float& dpi)
3343 {
3344     auto screenIds = GetAllScreenIds();
3345     if (screenIds.empty()) {
3346         TLOGE(WmsLogTag::DMS, "no screenId");
3347         return;
3348     }
3349     for (auto screenId : screenIds) {
3350         auto screenSession = GetScreenSession(screenId);
3351         if (screenSession == nullptr) {
3352             TLOGE(WmsLogTag::DMS, "screensession is nullptr, screenId: %{public}" PRIu64"", screenId);
3353             continue;
3354         }
3355         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && !screenSession->isInternal_) {
3356             SetVirtualPixelRatio(screenId, dpi);
3357         }
3358     }
3359 }
3360 
GetAllScreenIds()3361 std::vector<ScreenId> ScreenSessionManager::GetAllScreenIds()
3362 {
3363     std::vector<ScreenId> res;
3364     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3365     for (const auto& iter : screenSessionMap_) {
3366         res.emplace_back(iter.first);
3367     }
3368     return res;
3369 }
3370 
GetDisplayState(DisplayId displayId)3371 DisplayState ScreenSessionManager::GetDisplayState(DisplayId displayId)
3372 {
3373     return sessionDisplayPowerController_->GetDisplayState(displayId);
3374 }
3375 
NotifyDisplayEvent(DisplayEvent event)3376 void ScreenSessionManager::NotifyDisplayEvent(DisplayEvent event)
3377 {
3378     TLOGI(WmsLogTag::DMS, "[UL_POWER] receive keyguardDrawnDone");
3379     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3380         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3381             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3382         return;
3383     }
3384     sessionDisplayPowerController_->NotifyDisplayEvent(event);
3385     if (event == DisplayEvent::KEYGUARD_DRAWN) {
3386         keyguardDrawnDone_ = true;
3387         TLOGI(WmsLogTag::DMS, "[UL_POWER]keyguardDrawnDone_ is true");
3388         if (needScreenOnWhenKeyguardNotify_) {
3389             std::unique_lock <std::mutex> lock(screenOnMutex_);
3390             screenOnCV_.notify_all();
3391             TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOnCV_ notify one");
3392             needScreenOnWhenKeyguardNotify_ = false;
3393         }
3394     }
3395     if (event == DisplayEvent::SCREEN_LOCK_SUSPEND) {
3396         TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock suspend");
3397         if (isPhyScreenConnected_) {
3398             isScreenLockSuspend_ = false;
3399             TLOGI(WmsLogTag::DMS, "[UL_POWER]isScreenLockSuspend__  is false");
3400         } else {
3401             isScreenLockSuspend_ = true;
3402         }
3403         SetGotScreenOffAndWakeUpBlock();
3404     }
3405     if (event == DisplayEvent::SCREEN_LOCK_OFF) {
3406         TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock off");
3407         isScreenLockSuspend_ = false;
3408         TLOGI(WmsLogTag::DMS, "[UL_POWER]isScreenLockSuspend__  is false");
3409         SetGotScreenOffAndWakeUpBlock();
3410     }
3411     if (event == DisplayEvent::SCREEN_LOCK_FINGERPRINT) {
3412         TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock fingerprint");
3413         gotScreenlockFingerprint_ = true;
3414         SetGotScreenOffAndWakeUpBlock();
3415     }
3416     if (event == DisplayEvent::SCREEN_LOCK_DOZE_FINISH) {
3417         TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock doze finish");
3418         SetGotScreenOffAndWakeUpBlock();
3419     }
3420     WakeUpPictureFrameBlock(event);
3421 }
3422 
SetGotScreenOffAndWakeUpBlock()3423 void ScreenSessionManager::SetGotScreenOffAndWakeUpBlock()
3424 {
3425     gotScreenOffNotify_ = true;
3426     if (needScreenOffNotify_) {
3427         ScreenOffCVNotify();
3428     }
3429 }
3430 
ScreenOffCVNotify(void)3431 void ScreenSessionManager::ScreenOffCVNotify(void)
3432 {
3433     std::unique_lock <std::mutex> lock(screenOffMutex_);
3434     screenOffCV_.notify_all();
3435     needScreenOffNotify_ = false;
3436     TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOffCV_ notify one");
3437 }
3438 
GetScreenPower(ScreenId screenId)3439 ScreenPowerState ScreenSessionManager::GetScreenPower(ScreenId screenId)
3440 {
3441     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3442         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3443             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3444         return ScreenPowerState::INVALID_STATE;
3445     }
3446     auto state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance().GetScreenPowerStatus(screenId));
3447     std::ostringstream oss;
3448     oss << "GetScreenPower state:" << static_cast<uint32_t>(state) << " screenId:" << static_cast<uint64_t>(screenId);
3449     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
3450     screenEventTracker_.RecordEvent(oss.str());
3451     return state;
3452 }
3453 
GetScreenPower()3454 ScreenPowerState ScreenSessionManager::GetScreenPower()
3455 {
3456     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3457         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3458             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3459         return ScreenPowerState::INVALID_STATE;
3460     }
3461     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetScreenPower");
3462     ScreenPowerState state = ScreenPowerState::INVALID_STATE;
3463 #ifdef FOLD_ABILITY_ENABLE
3464     if (!g_foldScreenFlag || FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
3465         state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance()
3466             .GetScreenPowerStatus(GetDefaultScreenId()));
3467     } else {
3468         state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance()
3469             .GetScreenPowerStatus(foldScreenController_->GetCurrentScreenId()));
3470     }
3471 #else
3472     state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance()
3473             .GetScreenPowerStatus(foldScreenController_->GetCurrentScreenId()));
3474 #endif
3475     std::ostringstream oss;
3476     oss << "GetScreenPower state:" << static_cast<uint32_t>(state);
3477     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
3478     screenEventTracker_.RecordEvent(oss.str());
3479     return state;
3480 }
3481 
IsScreenRotationLocked(bool & isLocked)3482 DMError ScreenSessionManager::IsScreenRotationLocked(bool& isLocked)
3483 {
3484     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3485         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3486             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3487         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3488     }
3489     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
3490     if (screenSession == nullptr) {
3491         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
3492         return DMError::DM_ERROR_INVALID_PARAM;
3493     }
3494     isLocked = screenSession->IsScreenRotationLocked();
3495     TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
3496     return DMError::DM_OK;
3497 }
3498 
SetScreenRotationLocked(bool isLocked)3499 DMError ScreenSessionManager::SetScreenRotationLocked(bool isLocked)
3500 {
3501     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3502         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3503             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3504         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3505     }
3506     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
3507     if (screenSession == nullptr) {
3508         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
3509         return DMError::DM_ERROR_INVALID_PARAM;
3510     }
3511     screenSession->SetScreenRotationLocked(isLocked);
3512     TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
3513     return DMError::DM_OK;
3514 }
3515 
SetScreenRotationLockedFromJs(bool isLocked)3516 DMError ScreenSessionManager::SetScreenRotationLockedFromJs(bool isLocked)
3517 {
3518     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3519         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3520             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3521         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3522     }
3523     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
3524     if (screenSession == nullptr) {
3525         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
3526         return DMError::DM_ERROR_INVALID_PARAM;
3527     }
3528     screenSession->SetScreenRotationLockedFromJs(isLocked);
3529     TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
3530     return DMError::DM_OK;
3531 }
3532 
NotifyAndPublishEvent(sptr<DisplayInfo> displayInfo,ScreenId screenId,sptr<ScreenSession> screenSession)3533 void ScreenSessionManager::NotifyAndPublishEvent(sptr<DisplayInfo> displayInfo, ScreenId screenId,
3534     sptr<ScreenSession> screenSession)
3535 {
3536     if (displayInfo == nullptr || screenSession == nullptr) {
3537         TLOGE(WmsLogTag::DMS, "error, displayInfo or screenSession is nullptr");
3538         return;
3539     }
3540     NotifyDisplayChanged(displayInfo, DisplayChangeEvent::UPDATE_ROTATION);
3541     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
3542     UpdateDisplayScaleState(screenId);
3543     std::map<DisplayId, sptr<DisplayInfo>> emptyMap;
3544     NotifyDisplayStateChange(GetDefaultScreenId(), screenSession->ConvertToDisplayInfo(),
3545         emptyMap, DisplayStateChangeType::UPDATE_ROTATION);
3546     std::string identity = IPCSkeleton::ResetCallingIdentity();
3547     ScreenSessionPublish::GetInstance().PublishDisplayRotationEvent(
3548         displayInfo->GetScreenId(), displayInfo->GetRotation());
3549     IPCSkeleton::SetCallingIdentity(identity);
3550 }
3551 
UpdateScreenDirectionInfo(ScreenId screenId,float screenComponentRotation,float rotation,float phyRotation,ScreenPropertyChangeType screenPropertyChangeType)3552 void ScreenSessionManager::UpdateScreenDirectionInfo(ScreenId screenId, float screenComponentRotation, float rotation,
3553     float phyRotation, ScreenPropertyChangeType screenPropertyChangeType)
3554 {
3555     if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_END) {
3556         TLOGI(WmsLogTag::DMS, "ROTATION_END");
3557         return;
3558     }
3559     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3560     if (screenSession == nullptr) {
3561         TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"",
3562             screenId);
3563         return;
3564     }
3565     screenSession->SetPhysicalRotation(phyRotation);
3566     screenSession->SetScreenComponentRotation(screenComponentRotation);
3567     screenSession->UpdateRotationOrientation(rotation, GetFoldDisplayMode(), IsOrientationNeedChanged());
3568     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", rotation: %{public}f, screenComponentRotation: %{public}f",
3569         screenId, rotation, screenComponentRotation);
3570 }
3571 
UpdateScreenRotationProperty(ScreenId screenId,const RRect & bounds,float rotation,ScreenPropertyChangeType screenPropertyChangeType)3572 void ScreenSessionManager::UpdateScreenRotationProperty(ScreenId screenId, const RRect& bounds, float rotation,
3573     ScreenPropertyChangeType screenPropertyChangeType)
3574 {
3575     std::ostringstream oss;
3576     std::string changeType = TransferPropertyChangeTypeToString(screenPropertyChangeType);
3577     oss << "screenId: " << screenId << " rotation: " << rotation << " width: " << bounds.rect_.width_ \
3578         << " height: " << bounds.rect_.height_ << " type: " << changeType;
3579     screenEventTracker_.RecordBoundsEvent(oss.str());
3580     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3581         TLOGE(WmsLogTag::DMS, "permission denied!");
3582         return;
3583     }
3584     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3585     if (screenSession == nullptr) {
3586         TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"", screenId);
3587         return;
3588     }
3589     {
3590         DmsXcollie dmsXcollie("DMS:UpdateScreenRotationProperty:CacheForRotation", XCOLLIE_TIMEOUT_10S);
3591         if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_BEGIN) {
3592             // Rs is used to mark the start of the rotation animation
3593             TLOGI(WmsLogTag::DMS, "EnableCacheForRotation");
3594             RSInterfaces::GetInstance().EnableCacheForRotation();
3595         } else if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_END) {
3596             // Rs is used to mark the end of the rotation animation
3597             TLOGI(WmsLogTag::DMS, "DisableCacheForRotation");
3598             RSInterfaces::GetInstance().DisableCacheForRotation();
3599             return;
3600         } else if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY ||
3601             screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY) {
3602             sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
3603             TLOGI(WmsLogTag::DMS, "Update Screen Rotation Property Only");
3604             {
3605                 std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
3606                 screenSession->UpdatePropertyOnly(bounds, rotation, GetFoldDisplayMode(), IsOrientationNeedChanged());
3607             }
3608             if (screenPropertyChangeType != ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY) {
3609                 NotifyDisplayChanged(displayInfo, DisplayChangeEvent::UPDATE_ROTATION);
3610                 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
3611             }
3612             return;
3613         }
3614     }
3615     {
3616         std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
3617         screenSession->UpdatePropertyAfterRotation(bounds, rotation, GetFoldDisplayMode(), IsOrientationNeedChanged());
3618     }
3619     sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
3620     NotifyAndPublishEvent(displayInfo, screenId, screenSession);
3621 }
3622 
NotifyDisplayChanged(sptr<DisplayInfo> displayInfo,DisplayChangeEvent event)3623 void ScreenSessionManager::NotifyDisplayChanged(sptr<DisplayInfo> displayInfo, DisplayChangeEvent event)
3624 {
3625     if (displayInfo == nullptr) {
3626         TLOGE(WmsLogTag::DMS, "error, displayInfo is nullptr.");
3627         return;
3628     }
3629     auto task = [=] {
3630         auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
3631         if (event == DisplayChangeEvent::UPDATE_REFRESHRATE) {
3632             TLOGND(WmsLogTag::DMS, "evevt:%{public}d, displayId:%{public}" PRIu64", agent size: %{public}u",
3633                 event, displayInfo->GetDisplayId(), static_cast<uint32_t>(agents.size()));
3634         } else {
3635             TLOGNI(WmsLogTag::DMS, "evevt:%{public}d, displayId:%{public}" PRIu64", agent size: %{public}u",
3636                 event, displayInfo->GetDisplayId(), static_cast<uint32_t>(agents.size()));
3637         }
3638         if (agents.empty()) {
3639             return;
3640         }
3641         for (auto& agent : agents) {
3642             int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
3643             if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
3644                 agent->OnDisplayChange(displayInfo, event);
3645             }
3646         }
3647     };
3648     taskScheduler_->PostAsyncTask(task, "NotifyDisplayChanged");
3649 }
3650 
SetOrientation(ScreenId screenId,Orientation orientation)3651 DMError ScreenSessionManager::SetOrientation(ScreenId screenId, Orientation orientation)
3652 {
3653     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3654         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3655             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3656         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3657     }
3658     if (orientation < Orientation::UNSPECIFIED || orientation > Orientation::REVERSE_HORIZONTAL) {
3659         TLOGE(WmsLogTag::DMS, "set: %{public}u", static_cast<uint32_t>(orientation));
3660         return DMError::DM_ERROR_INVALID_PARAM;
3661     }
3662     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetOrientation");
3663     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3664     if (screenSession == nullptr) {
3665         TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"", screenId);
3666         return DMError::DM_ERROR_NULLPTR;
3667     }
3668     // just for get orientation test
3669     screenSession->SetOrientation(orientation);
3670     screenSession->ScreenOrientationChange(orientation, GetFoldDisplayMode());
3671     return DMError::DM_OK;
3672 }
3673 
SetRotation(ScreenId screenId,Rotation rotationAfter,bool isFromWindow)3674 bool ScreenSessionManager::SetRotation(ScreenId screenId, Rotation rotationAfter, bool isFromWindow)
3675 {
3676     TLOGI(WmsLogTag::DMS,
3677         "Enter, screenId: %{public}" PRIu64 ", rotation: %{public}u, isFromWindow: %{public}u,",
3678         screenId, rotationAfter, isFromWindow);
3679     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3680     if (screenSession == nullptr) {
3681         TLOGE(WmsLogTag::DMS, "error, cannot get screen with screenId: %{public}" PRIu64, screenId);
3682         return false;
3683     }
3684     if (rotationAfter == screenSession->GetRotation()) {
3685         TLOGE(WmsLogTag::DMS, "rotation not changed. screen %{public}" PRIu64" rotation %{public}u",
3686             screenId, rotationAfter);
3687         return false;
3688     }
3689     TLOGI(WmsLogTag::DMS, "set orientation. rotation %{public}u", rotationAfter);
3690     SetDisplayBoundary(screenSession);
3691     screenSession->SetRotation(rotationAfter);
3692     screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::ROTATION);
3693     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
3694     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::UPDATE_ROTATION);
3695     return true;
3696 }
3697 
SetSensorSubscriptionEnabled()3698 void ScreenSessionManager::SetSensorSubscriptionEnabled()
3699 {
3700     isAutoRotationOpen_ = system::GetParameter("persist.display.ar.enabled", "1") == "1";
3701     if (!isAutoRotationOpen_) {
3702         TLOGE(WmsLogTag::DMS, "autoRotation is not open");
3703         return;
3704     }
3705     ScreenSensorConnector::SubscribeRotationSensor();
3706     TLOGI(WmsLogTag::DMS, "subscribe rotation sensor successful");
3707 }
3708 
SetPostureAndHallSensorEnabled()3709 void ScreenSessionManager::SetPostureAndHallSensorEnabled()
3710 {
3711 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
3712     if (!g_foldScreenFlag) {
3713         TLOGI(WmsLogTag::DMS, "current device is not fold phone.");
3714         return;
3715     }
3716     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
3717         SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
3718         SecondaryFoldSensorManager::GetInstance().RegisterHallCallback();
3719     } else {
3720         FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
3721         FoldScreenSensorManager::GetInstance().RegisterHallCallback();
3722     }
3723     TLOGI(WmsLogTag::DMS, "successful");
3724     screenEventTracker_.RecordEvent("Dms subscribe Posture and Hall sensor finished.");
3725 #endif
3726 }
3727 
SetRotationFromWindow(Rotation targetRotation)3728 bool ScreenSessionManager::SetRotationFromWindow(Rotation targetRotation)
3729 {
3730     sptr<DisplayInfo> displayInfo = GetDefaultDisplayInfo();
3731     if (displayInfo == nullptr) {
3732         return false;
3733     }
3734     return SetRotation(displayInfo->GetScreenId(), targetRotation, true);
3735 }
3736 
GetScreenModesByDisplayId(DisplayId displayId)3737 sptr<SupportedScreenModes> ScreenSessionManager::GetScreenModesByDisplayId(DisplayId displayId)
3738 {
3739     auto displayInfo = GetDisplayInfoById(displayId);
3740     if (displayInfo == nullptr) {
3741         TLOGE(WmsLogTag::DMS, "can not get display.");
3742         return nullptr;
3743     }
3744     auto screenInfo = GetScreenInfoById(displayInfo->GetScreenId());
3745     if (screenInfo == nullptr) {
3746         TLOGE(WmsLogTag::DMS, "can not get screen.");
3747         return nullptr;
3748     }
3749     auto modes = screenInfo->GetModes();
3750     auto id = screenInfo->GetModeId();
3751     if (id >= modes.size()) {
3752         TLOGE(WmsLogTag::DMS, "can not get screenMode.");
3753         return nullptr;
3754     }
3755     return modes[id];
3756 }
3757 
GetScreenInfoByDisplayId(DisplayId displayId)3758 sptr<ScreenInfo> ScreenSessionManager::GetScreenInfoByDisplayId(DisplayId displayId)
3759 {
3760     auto displayInfo = GetDisplayInfoById(displayId);
3761     if (displayInfo == nullptr) {
3762         TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
3763         return nullptr;
3764     }
3765     return GetScreenInfoById(displayInfo->GetScreenId());
3766 }
3767 
NotifyPowerEventForDualDisplay(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)3768 int ScreenSessionManager::NotifyPowerEventForDualDisplay(DisplayPowerEvent event, EventStatus status,
3769     PowerStateChangeReason reason)
3770 {
3771     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3772     if (screenSessionMap_.empty()) {
3773         TLOGE(WmsLogTag::DMS, "[UL_POWER]screenSessionMap is empty");
3774         return NOTIFY_EVENT_FOR_DUAL_FAILED;
3775     }
3776 #ifdef FOLD_ABILITY_ENABLE
3777     // The on/off screen will send a notification based on the number of screens.
3778     // The dual display device just notify the current screen usage
3779     if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
3780         ScreenId currentScreenId = foldScreenController_->GetCurrentScreenId();
3781         auto iter = screenSessionMap_.find(currentScreenId);
3782         if (iter != screenSessionMap_.end() && iter->second != nullptr) {
3783             iter->second->PowerStatusChange(event, status, reason);
3784         }
3785         return NOTIFY_EVENT_FOR_DUAL_SUCESS;
3786     }
3787 #endif
3788     return NO_NEED_NOTIFY_EVENT_FOR_DUAL;
3789 }
3790 
NotifyDisplayPowerEvent(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)3791 bool ScreenSessionManager::NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status,
3792     PowerStateChangeReason reason)
3793 {
3794     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER);
3795     if (agents.empty()) {
3796         TLOGI(WmsLogTag::DMS, "[UL_POWER] agents is empty");
3797         return false;
3798     }
3799     TLOGD(WmsLogTag::DMS, "[UL_POWER] start");
3800     for (auto& agent : agents) {
3801         agent->NotifyDisplayPowerEvent(event, status);
3802     }
3803     auto ret = NotifyPowerEventForDualDisplay(event, status, reason);
3804     if (ret == NOTIFY_EVENT_FOR_DUAL_FAILED) {
3805         TLOGE(WmsLogTag::DMS, "[UL_POWER]NotifyPowerEventForDualDisplay ret false");
3806         return false;
3807     } else if (ret == NOTIFY_EVENT_FOR_DUAL_SUCESS) {
3808         TLOGD(WmsLogTag::DMS, "[UL_POWER]NotifyPowerEventForDualDisplay ret sucess");
3809         return true;
3810     }
3811     auto screenIds = GetAllScreenIds();
3812     if (screenIds.empty()) {
3813         TLOGI(WmsLogTag::DMS, "[UL_POWER]no screenID");
3814         return false;
3815     }
3816     auto screenId = screenIds[0];
3817     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3818     if (screenSession == nullptr) {
3819         TLOGE(WmsLogTag::DMS, "[UL_POWER]Cannot get ScreenSession, screenId: %{public}" PRIu64"", screenId);
3820         return false;
3821     }
3822     screenSession->PowerStatusChange(event, status, reason);
3823     return true;
3824 }
3825 
NotifyDisplayStateChanged(DisplayId id,DisplayState state)3826 bool ScreenSessionManager::NotifyDisplayStateChanged(DisplayId id, DisplayState state)
3827 {
3828     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_STATE_LISTENER);
3829     if (agents.empty()) {
3830         TLOGI(WmsLogTag::DMS, "agents is empty");
3831         return false;
3832     }
3833     TLOGI(WmsLogTag::DMS, "notify enter!");
3834     for (auto& agent : agents) {
3835         agent->NotifyDisplayStateChanged(id, state);
3836     }
3837     return true;
3838 }
GetAllScreenInfos(std::vector<sptr<ScreenInfo>> & screenInfos)3839 DMError ScreenSessionManager::GetAllScreenInfos(std::vector<sptr<ScreenInfo>>& screenInfos)
3840 {
3841     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3842         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3843             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3844         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3845     }
3846     std::vector<ScreenId> screenIds = GetAllScreenIds();
3847     if (screenIds.empty()) {
3848         TLOGI(WmsLogTag::DMS, "[UL_POWER]no screen info");
3849         return DMError::DM_OK;
3850     }
3851     for (auto screenId : screenIds) {
3852         auto screenInfo = GetScreenInfoById(screenId);
3853         if (screenInfo == nullptr) {
3854             TLOGE(WmsLogTag::DMS, "cannot find screenInfo: %{public}" PRIu64"", screenId);
3855             continue;
3856         }
3857         screenInfos.emplace_back(screenInfo);
3858     }
3859     return DMError::DM_OK;
3860 }
3861 
GetAllScreenIds() const3862 std::vector<ScreenId> ScreenSessionManager::GetAllScreenIds() const
3863 {
3864     std::vector<ScreenId> res;
3865     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3866     for (const auto& iter : screenSessionMap_) {
3867         res.emplace_back(iter.first);
3868     }
3869     return res;
3870 }
3871 
GetScreenSupportedColorGamuts(ScreenId screenId,std::vector<ScreenColorGamut> & colorGamuts)3872 DMError ScreenSessionManager::GetScreenSupportedColorGamuts(ScreenId screenId,
3873     std::vector<ScreenColorGamut>& colorGamuts)
3874 {
3875     TLOGI(WmsLogTag::DMS, "ENTER");
3876     if (!SessionPermission::IsSystemCalling()) {
3877         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3878             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3879         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3880     }
3881     sptr<ScreenSession> screen = GetScreenSession(screenId);
3882     if (screen == nullptr) {
3883         TLOGE(WmsLogTag::DMS, "nullptr");
3884         return DMError::DM_ERROR_INVALID_PARAM;
3885     }
3886     return screen->GetScreenSupportedColorGamuts(colorGamuts);
3887 }
3888 
GetPixelFormat(ScreenId screenId,GraphicPixelFormat & pixelFormat)3889 DMError ScreenSessionManager::GetPixelFormat(ScreenId screenId, GraphicPixelFormat& pixelFormat)
3890 {
3891     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64, screenId);
3892     if (screenId == SCREEN_ID_INVALID) {
3893         TLOGE(WmsLogTag::DMS, "screenId invalid");
3894         return DMError::DM_ERROR_INVALID_PARAM;
3895     }
3896     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3897     if (screenSession == nullptr) {
3898         return DMError::DM_ERROR_INVALID_PARAM;
3899     }
3900     return screenSession->GetPixelFormat(pixelFormat);
3901 }
3902 
SetPixelFormat(ScreenId screenId,GraphicPixelFormat pixelFormat)3903 DMError ScreenSessionManager::SetPixelFormat(ScreenId screenId, GraphicPixelFormat pixelFormat)
3904 {
3905     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3906         TLOGE(WmsLogTag::DMS, "permission denied!");
3907         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3908     }
3909 
3910     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", pixelFormat %{public}d",
3911         screenId, pixelFormat);
3912     if (screenId == SCREEN_ID_INVALID) {
3913         TLOGE(WmsLogTag::DMS, "screenId invalid");
3914         return DMError::DM_ERROR_INVALID_PARAM;
3915     }
3916     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3917     if (screenSession == nullptr) {
3918         return DMError::DM_ERROR_INVALID_PARAM;
3919     }
3920     return screenSession->SetPixelFormat(pixelFormat);
3921 }
3922 
GetSupportedHDRFormats(ScreenId screenId,std::vector<ScreenHDRFormat> & hdrFormats)3923 DMError ScreenSessionManager::GetSupportedHDRFormats(ScreenId screenId,
3924     std::vector<ScreenHDRFormat>& hdrFormats)
3925 {
3926 #ifdef WM_SCREEN_HDR_FORMAT_ENABLE
3927     TLOGI(WmsLogTag::DMS, "start %{public}" PRIu64, screenId);
3928     if (screenId == SCREEN_ID_INVALID) {
3929         TLOGE(WmsLogTag::DMS, "screenId invalid");
3930         return DMError::DM_ERROR_INVALID_PARAM;
3931     }
3932     sptr<ScreenSession> screen = GetScreenSession(screenId);
3933     if (screen == nullptr) {
3934         TLOGE(WmsLogTag::DMS, "nullptr");
3935         return DMError::DM_ERROR_INVALID_PARAM;
3936     }
3937     return screen->GetSupportedHDRFormats(hdrFormats);
3938 #else
3939     return DMError::DM_OK;
3940 #endif
3941 }
3942 
GetScreenHDRFormat(ScreenId screenId,ScreenHDRFormat & hdrFormat)3943 DMError ScreenSessionManager::GetScreenHDRFormat(ScreenId screenId, ScreenHDRFormat& hdrFormat)
3944 {
3945 #ifdef WM_SCREEN_HDR_FORMAT_ENABLE
3946     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64, screenId);
3947     if (screenId == SCREEN_ID_INVALID) {
3948         TLOGE(WmsLogTag::DMS, "screenId invalid");
3949         return DMError::DM_ERROR_INVALID_PARAM;
3950     }
3951     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3952     if (screenSession == nullptr) {
3953         return DMError::DM_ERROR_INVALID_PARAM;
3954     }
3955     return screenSession->GetScreenHDRFormat(hdrFormat);
3956 #else
3957     return DMError::DM_OK;
3958 #endif
3959 }
3960 
SetScreenHDRFormat(ScreenId screenId,int32_t modeIdx)3961 DMError ScreenSessionManager::SetScreenHDRFormat(ScreenId screenId, int32_t modeIdx)
3962 {
3963 #ifdef WM_SCREEN_HDR_FORMAT_ENABLE
3964     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3965         TLOGE(WmsLogTag::DMS, "permission denied!");
3966         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3967     }
3968 
3969     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", modeIdx %{public}d", screenId, modeIdx);
3970     if (screenId == SCREEN_ID_INVALID) {
3971         TLOGE(WmsLogTag::DMS, "screenId invalid");
3972         return DMError::DM_ERROR_INVALID_PARAM;
3973     }
3974     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3975     if (screenSession == nullptr) {
3976         return DMError::DM_ERROR_INVALID_PARAM;
3977     }
3978     return screenSession->SetScreenHDRFormat(modeIdx);
3979 #else
3980     return DMError::DM_OK;
3981 #endif
3982 }
3983 
GetSupportedColorSpaces(ScreenId screenId,std::vector<GraphicCM_ColorSpaceType> & colorSpaces)3984 DMError ScreenSessionManager::GetSupportedColorSpaces(ScreenId screenId,
3985     std::vector<GraphicCM_ColorSpaceType>& colorSpaces)
3986 {
3987 #ifdef WM_SCREEN_COLOR_SPACE_ENABLE
3988     TLOGI(WmsLogTag::DMS, "start %{public}" PRIu64, screenId);
3989     if (screenId == SCREEN_ID_INVALID) {
3990         TLOGE(WmsLogTag::DMS, "screenId invalid");
3991         return DMError::DM_ERROR_INVALID_PARAM;
3992     }
3993     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3994     if (screenSession == nullptr) {
3995         TLOGE(WmsLogTag::DMS, "nullptr");
3996         return DMError::DM_ERROR_INVALID_PARAM;
3997     }
3998     return screenSession->GetSupportedColorSpaces(colorSpaces);
3999 #else
4000     return DMError::DM_OK;
4001 #endif
4002 }
4003 
GetScreenColorSpace(ScreenId screenId,GraphicCM_ColorSpaceType & colorSpace)4004 DMError ScreenSessionManager::GetScreenColorSpace(ScreenId screenId, GraphicCM_ColorSpaceType& colorSpace)
4005 {
4006 #ifdef WM_SCREEN_COLOR_SPACE_ENABLE
4007     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64, screenId);
4008     if (screenId == SCREEN_ID_INVALID) {
4009         TLOGE(WmsLogTag::DMS, "screenId invalid");
4010         return DMError::DM_ERROR_INVALID_PARAM;
4011     }
4012     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4013     if (screenSession == nullptr) {
4014         return DMError::DM_ERROR_INVALID_PARAM;
4015     }
4016     return screenSession->GetScreenColorSpace(colorSpace);
4017 #else
4018     return DMError::DM_OK;
4019 #endif
4020 }
4021 
SetScreenColorSpace(ScreenId screenId,GraphicCM_ColorSpaceType colorSpace)4022 DMError ScreenSessionManager::SetScreenColorSpace(ScreenId screenId, GraphicCM_ColorSpaceType colorSpace)
4023 {
4024 #ifdef WM_SCREEN_COLOR_SPACE_ENABLE
4025     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4026         TLOGE(WmsLogTag::DMS, "permission denied!");
4027         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4028     }
4029 
4030     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", colorSpace %{public}d",
4031         screenId, colorSpace);
4032     if (screenId == SCREEN_ID_INVALID) {
4033         TLOGE(WmsLogTag::DMS, "screenId invalid");
4034         return DMError::DM_ERROR_INVALID_PARAM;
4035     }
4036     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4037     if (screenSession == nullptr) {
4038         return DMError::DM_ERROR_INVALID_PARAM;
4039     }
4040     return screenSession->SetScreenColorSpace(colorSpace);
4041 #else
4042     return DMError::DM_OK;
4043 #endif
4044 }
4045 
AddVirtualScreenDeathRecipient(const sptr<IRemoteObject> & displayManagerAgent,ScreenId smsScreenId)4046 void ScreenSessionManager::AddVirtualScreenDeathRecipient(const sptr<IRemoteObject>& displayManagerAgent,
4047     ScreenId smsScreenId)
4048 {
4049     if (deathRecipient_ == nullptr) {
4050         TLOGW(WmsLogTag::DMS, "Create deathRecipient");
4051         deathRecipient_ =
4052             new(std::nothrow) AgentDeathRecipient([this](const sptr<IRemoteObject>& agent) { OnRemoteDied(agent); });
4053     }
4054     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4055     if (deathRecipient_ != nullptr) {
4056         auto agIter = screenAgentMap_.find(displayManagerAgent);
4057         if (agIter == screenAgentMap_.end()) {
4058             displayManagerAgent->AddDeathRecipient(deathRecipient_);
4059         }
4060     }
4061     screenAgentMap_[displayManagerAgent].emplace_back(smsScreenId);
4062 }
4063 
CreateVirtualScreen(VirtualScreenOption option,const sptr<IRemoteObject> & displayManagerAgent)4064 ScreenId ScreenSessionManager::CreateVirtualScreen(VirtualScreenOption option,
4065                                                    const sptr<IRemoteObject>& displayManagerAgent)
4066 {
4067     if (!Permission::IsSystemCalling() && !SessionPermission::IsShellCall() &&
4068         !Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION)) {
4069         return ERROR_ID_NOT_SYSTEM_APP;
4070     }
4071     if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
4072         !SessionPermission::IsShellCall() && !Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION)) {
4073         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4074             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4075         return SCREEN_ID_INVALID;
4076     }
4077     if (option.virtualScreenType_ != VirtualScreenType::SCREEN_RECORDING) {
4078         ExitCoordination("CreateVirtualScreen(cast)");
4079     }
4080     TLOGI(WmsLogTag::DMS, "ENTER, virtualScreenType: %{public}u", static_cast<uint32_t>(option.virtualScreenType_));
4081     if (SessionPermission::IsBetaVersion()) {
4082         CheckAndSendHiSysEvent("CREATE_VIRTUAL_SCREEN", "hmos.screenrecorder");
4083     }
4084     if (clientProxy_ && option.missionIds_.size() > 0) {
4085         std::vector<uint64_t> surfaceNodeIds;
4086         clientProxy_->OnGetSurfaceNodeIdsFromMissionIdsChanged(option.missionIds_, surfaceNodeIds, true);
4087         option.missionIds_ = surfaceNodeIds;
4088     }
4089     ScreenId rsId = rsInterface_.CreateVirtualScreen(option.name_, option.width_,
4090         option.height_, option.surface_, SCREEN_ID_INVALID, option.flags_);
4091     if (rsId == SCREEN_ID_INVALID) {
4092         TLOGI(WmsLogTag::DMS, "rsId is invalid");
4093         return SCREEN_ID_INVALID;
4094     }
4095     TLOGW(WmsLogTag::DMS, "rsId: %{public}" PRIu64"", rsId);
4096     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CreateVirtualScreen(%s)", option.name_.c_str());
4097     ScreenId smsScreenId = SCREEN_ID_INVALID;
4098     if (!screenIdManager_.ConvertToSmsScreenId(rsId, smsScreenId)) {
4099         TLOGW(WmsLogTag::DMS, "!ConvertToSmsScreenId(rsId, smsScreenId)");
4100         smsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsId);
4101         auto screenSession = InitVirtualScreen(smsScreenId, rsId, option);
4102         if (screenSession == nullptr) {
4103             TLOGW(WmsLogTag::DMS, "screenSession is nullptr");
4104             screenIdManager_.DeleteScreenId(smsScreenId);
4105             return SCREEN_ID_INVALID;
4106         }
4107         screenSession->SetName(option.name_);
4108         screenSession->SetMirrorScreenType(MirrorScreenType::VIRTUAL_MIRROR);
4109         {
4110             std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4111             screenSessionMap_.insert(std::make_pair(smsScreenId, screenSession));
4112         }
4113         if (option.name_ == "CastEngine") {
4114             screenSession->SetVirtualScreenFlag(VirtualScreenFlag::CAST);
4115         }
4116         NotifyScreenConnected(screenSession->ConvertToScreenInfo());
4117         TLOGW(WmsLogTag::DMS, "create success. ScreenId: %{public}" PRIu64", rsId: %{public}" PRIu64"",
4118             smsScreenId, rsId);
4119         if (displayManagerAgent == nullptr) {
4120             virtualScreenCount_ = virtualScreenCount_ + 1;
4121             NotifyCaptureStatusChanged();
4122             return smsScreenId;
4123         }
4124         AddVirtualScreenDeathRecipient(displayManagerAgent, smsScreenId);
4125     }
4126     virtualScreenCount_ = virtualScreenCount_ + 1;
4127     NotifyCaptureStatusChanged();
4128     return smsScreenId;
4129 }
4130 
SetVirtualScreenSurface(ScreenId screenId,sptr<IBufferProducer> surface)4131 DMError ScreenSessionManager::SetVirtualScreenSurface(ScreenId screenId, sptr<IBufferProducer> surface)
4132 {
4133     bool isCallingByThirdParty = Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION);
4134     if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
4135         !SessionPermission::IsShellCall() && !isCallingByThirdParty) {
4136         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4137             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4138         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4139     }
4140     if (surface == nullptr) {
4141         TLOGE(WmsLogTag::DMS, "surface is null");
4142         return DMError::DM_ERROR_INVALID_PARAM;
4143     }
4144     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4145     if (screenSession == nullptr) {
4146         TLOGE(WmsLogTag::DMS, "No such screen.");
4147         return isCallingByThirdParty ? DMError::DM_ERROR_NULLPTR : DMError::DM_ERROR_INVALID_PARAM;
4148     }
4149     TLOGW(WmsLogTag::DMS, "enter set virtual screen surface");
4150     ScreenId rsScreenId;
4151     int32_t res = -1;
4152     if (screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4153         sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(surface);
4154         if (pSurface != nullptr) {
4155             res = rsInterface_.SetVirtualScreenSurface(rsScreenId, pSurface);
4156         }
4157     }
4158     if (res != 0) {
4159         TLOGE(WmsLogTag::DMS, "fail to set virtual screen surface in RenderService");
4160         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
4161     }
4162     return DMError::DM_OK;
4163 }
4164 
AddVirtualScreenBlockList(const std::vector<int32_t> & persistentIds)4165 DMError ScreenSessionManager::AddVirtualScreenBlockList(const std::vector<int32_t>& persistentIds)
4166 {
4167     if (!Permission::IsSystemCalling()) {
4168         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4169             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4170         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4171     }
4172     MockSessionManagerService::GetInstance().AddSkipSelfWhenShowOnVirtualScreenList(persistentIds);
4173     return DMError::DM_OK;
4174 }
4175 
RemoveVirtualScreenBlockList(const std::vector<int32_t> & persistentIds)4176 DMError ScreenSessionManager::RemoveVirtualScreenBlockList(const std::vector<int32_t>& persistentIds)
4177 {
4178     if (!Permission::IsSystemCalling()) {
4179         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4180             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4181         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4182     }
4183     MockSessionManagerService::GetInstance().RemoveSkipSelfWhenShowOnVirtualScreenList(persistentIds);
4184     return DMError::DM_OK;
4185 }
4186 
SetScreenPrivacyMaskImage(ScreenId screenId,const std::shared_ptr<Media::PixelMap> & privacyMaskImg)4187 DMError ScreenSessionManager::SetScreenPrivacyMaskImage(ScreenId screenId,
4188     const std::shared_ptr<Media::PixelMap>& privacyMaskImg)
4189 {
4190     if (!Permission::IsSystemCalling()) {
4191         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4192             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4193         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4194     }
4195     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4196     if (screenSession == nullptr) {
4197         TLOGE(WmsLogTag::DMS, "No such screen.");
4198         return DMError::DM_ERROR_NULLPTR;
4199     }
4200     ScreenId rsScreenId;
4201     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4202         TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
4203         return DMError::DM_ERROR_INVALID_PARAM;
4204     }
4205     int32_t res = -1;
4206     if (privacyMaskImg == nullptr) {
4207         TLOGI(WmsLogTag::DMS, "Clearing screen privacy mask image for screenId: %{public}" PRIu64"",
4208             static_cast<uint64_t>(screenId));
4209         res = rsInterface_.SetScreenSecurityMask(rsScreenId, nullptr);
4210         if (res != 0) {
4211             TLOGE(WmsLogTag::DMS, "Fail to set privacy mask image in RenderService");
4212             return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
4213         }
4214         return DMError::DM_OK;
4215     }
4216     TLOGI(WmsLogTag::DMS, "Setting screen privacy mask image for screenId: %{public}" PRIu64"",
4217         static_cast<uint64_t>(screenId));
4218     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetScreenSecurityMask(%" PRIu64")", screenId);
4219     res = rsInterface_.SetScreenSecurityMask(rsScreenId, privacyMaskImg);
4220     if (res != 0) {
4221         TLOGE(WmsLogTag::DMS, "Fail to set privacy mask image in RenderService");
4222         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
4223     }
4224     return DMError::DM_OK;
4225 }
4226 
SetVirtualMirrorScreenScaleMode(ScreenId screenId,ScreenScaleMode scaleMode)4227 DMError ScreenSessionManager::SetVirtualMirrorScreenScaleMode(ScreenId screenId, ScreenScaleMode scaleMode)
4228 {
4229     if (!SessionPermission::IsSystemCalling()) {
4230         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4231             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4232         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4233     }
4234     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4235     if (screenSession == nullptr) {
4236         TLOGE(WmsLogTag::DMS, "No such screen.");
4237         return DMError::DM_ERROR_INVALID_PARAM;
4238     }
4239     ScreenId rsScreenId;
4240     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4241         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
4242         return DMError::DM_ERROR_INVALID_PARAM;
4243     }
4244     bool res = rsInterface_.SetVirtualMirrorScreenScaleMode(rsScreenId, scaleMode);
4245     if (!res) {
4246         TLOGE(WmsLogTag::DMS, "failed in RenderService");
4247         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
4248     }
4249     return DMError::DM_OK;
4250 }
4251 
SetVirtualMirrorScreenCanvasRotation(ScreenId screenId,bool autoRotate)4252 DMError ScreenSessionManager::SetVirtualMirrorScreenCanvasRotation(ScreenId screenId, bool autoRotate)
4253 {
4254     if (!SessionPermission::IsSystemCalling()) {
4255         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4256             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4257         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4258     }
4259     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4260     if (screenSession == nullptr) {
4261         TLOGE(WmsLogTag::DMS, "No such screen.");
4262         return DMError::DM_ERROR_INVALID_PARAM;
4263     }
4264     TLOGW(WmsLogTag::DMS, "enter set virtual mirror screen canvas rotation");
4265     bool res = false;
4266     ScreenId rsScreenId;
4267     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4268         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
4269         return DMError::DM_ERROR_INVALID_PARAM;
4270     }
4271     res = rsInterface_.SetVirtualMirrorScreenCanvasRotation(rsScreenId, autoRotate);
4272     if (!res) {
4273         TLOGE(WmsLogTag::DMS, "failed in RenderService");
4274         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
4275     }
4276     TLOGW(WmsLogTag::DMS, "success");
4277     return DMError::DM_OK;
4278 }
4279 
ResizeVirtualScreen(ScreenId screenId,uint32_t width,uint32_t height)4280 DMError ScreenSessionManager::ResizeVirtualScreen(ScreenId screenId, uint32_t width, uint32_t height)
4281 {
4282     if (!SessionPermission::IsSystemCalling()) {
4283         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4284             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4285         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4286     }
4287     TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64", width: %{public}u, height: %{public}u.",
4288         screenId, width, height);
4289     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4290     if (screenSession == nullptr) {
4291         TLOGE(WmsLogTag::DMS, "No such screen.");
4292         return DMError::DM_ERROR_INVALID_PARAM;
4293     }
4294     ScreenId rsScreenId;
4295     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4296         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
4297         return DMError::DM_ERROR_INVALID_PARAM;
4298     }
4299     rsInterface_.ResizeVirtualScreen(rsScreenId, width, height);
4300     screenSession->Resize(width, height);
4301     screenSession->PropertyChange(screenSession->GetScreenProperty(),
4302         ScreenPropertyChangeReason::VIRTUAL_SCREEN_RESIZE);
4303     return DMError::DM_OK;
4304 }
4305 
DestroyVirtualScreen(ScreenId screenId)4306 DMError ScreenSessionManager::DestroyVirtualScreen(ScreenId screenId)
4307 {
4308     bool isCallingByThirdParty = Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION);
4309     if (!SessionPermission::IsSystemCalling() && !isCallingByThirdParty) {
4310         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4311             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4312         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4313     }
4314     if (static_cast<uint64_t>(screenId) < static_cast<uint64_t>(MINIMUM_VIRTUAL_SCREEN_ID)) {
4315         TLOGE(WmsLogTag::DMS, "virtual screenId is invalid, id: %{public}" PRIu64"", static_cast<uint64_t>(screenId));
4316         return DMError::DM_ERROR_INVALID_PARAM;
4317     }
4318     // virtual screen destroy callback to notify scb
4319     TLOGW(WmsLogTag::DMS, "start");
4320     OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED);
4321     ScreenId rsScreenId = SCREEN_ID_INVALID;
4322     {
4323         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4324         screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
4325         for (auto &agentIter : screenAgentMap_) {
4326             auto iter = std::find(agentIter.second.begin(), agentIter.second.end(), screenId);
4327             if (iter != agentIter.second.end()) {
4328                 iter = agentIter.second.erase(iter);
4329                 if (agentIter.first != nullptr && agentIter.second.empty()) {
4330                     screenAgentMap_.erase(agentIter.first);
4331                 }
4332                 break;
4333             }
4334         }
4335     }
4336     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyVirtualScreen(%" PRIu64")", screenId);
4337     auto screen = GetScreenSession(screenId);
4338     if (rsScreenId != SCREEN_ID_INVALID && screen != nullptr) {
4339         if (CheckScreenInScreenGroup(screen)) {
4340             NotifyDisplayDestroy(screenId);
4341         }
4342         {
4343             std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4344             auto screenGroup = RemoveFromGroupLocked(screen);
4345             if (screenGroup != nullptr) {
4346                 NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
4347             }
4348             screenSessionMap_.erase(screenId);
4349         }
4350         NotifyScreenDisconnected(screenId);
4351         TLOGW(WmsLogTag::DMS, "destroy success, id: %{public}" PRIu64, screenId);
4352     }
4353     screenIdManager_.DeleteScreenId(screenId);
4354     virtualScreenCount_ = virtualScreenCount_ > 0 ? virtualScreenCount_ - 1 : 0;
4355     NotifyCaptureStatusChanged();
4356     if (rsScreenId == SCREEN_ID_INVALID) {
4357         TLOGE(WmsLogTag::DMS, "No corresponding rsScreenId");
4358         return isCallingByThirdParty ? DMError::DM_ERROR_NULLPTR : DMError::DM_ERROR_INVALID_PARAM;
4359     }
4360     rsInterface_.RemoveVirtualScreen(rsScreenId);
4361     return DMError::DM_OK;
4362 }
4363 
DisableMirror(bool disableOrNot)4364 DMError ScreenSessionManager::DisableMirror(bool disableOrNot)
4365 {
4366     TLOGW(WmsLogTag::DMS, "start %{public}d", disableOrNot);
4367     if (!SessionPermission::IsSystemCalling()) {
4368         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4369             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4370         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4371     }
4372     TLOGI(WmsLogTag::DMS, "enter %{public}d", disableOrNot);
4373     if (disableOrNot) {
4374         std::vector<ScreenId> screenIds;
4375         auto allScreenIds = GetAllScreenIds();
4376         for (auto screenId : allScreenIds) {
4377             auto screen = GetScreenSession(screenId);
4378             if (screen && screen->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
4379                 screenIds.push_back(screenId);
4380             }
4381         }
4382         StopMirror(screenIds);
4383     }
4384     return DMError::DM_OK;
4385 }
4386 
MirrorSwitchNotify(ScreenId screenId)4387 void ScreenSessionManager::MirrorSwitchNotify(ScreenId screenId)
4388 {
4389     auto mirrorScreen = GetScreenSession(screenId);
4390     if (mirrorScreen != nullptr) {
4391         mirrorScreen->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
4392         NotifyScreenChanged(mirrorScreen->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE);
4393     }
4394 }
4395 
DoMakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,DMRect mainScreenRegion,ScreenId & screenGroupId)4396 DMError ScreenSessionManager::DoMakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
4397     DMRect mainScreenRegion, ScreenId& screenGroupId)
4398 {
4399 #ifdef WM_MULTI_SCREEN_ENABLE
4400     TLOGW(WmsLogTag::DMS, "enter!");
4401     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4402         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4403             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4404         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4405     }
4406     if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
4407         TLOGW(WmsLogTag::DMS, "disabled by edm!");
4408         return DMError::DM_ERROR_INVALID_PERMISSION;
4409     }
4410 
4411     TLOGW(WmsLogTag::DMS, "mainScreenId :%{public}" PRIu64"", mainScreenId);
4412     auto allMirrorScreenIds = GetAllValidScreenIds(mirrorScreenIds);
4413     auto iter = std::find(allMirrorScreenIds.begin(), allMirrorScreenIds.end(), mainScreenId);
4414     if (iter != allMirrorScreenIds.end()) {
4415         allMirrorScreenIds.erase(iter);
4416     }
4417     auto mainScreen = GetScreenSession(mainScreenId);
4418     if (mainScreen == nullptr || allMirrorScreenIds.empty()) {
4419         TLOGE(WmsLogTag::DMS, "MakeMirror fail. mainScreen :%{public}" PRIu64", screens size:%{public}u",
4420             mainScreenId, static_cast<uint32_t>(allMirrorScreenIds.size()));
4421         return DMError::DM_ERROR_NULLPTR;
4422     }
4423     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeMirror start");
4424     for (ScreenId screenId : allMirrorScreenIds) {
4425         OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED);
4426     }
4427 #ifdef FOLD_ABILITY_ENABLE
4428     if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
4429         foldScreenController_->SetMainScreenRegion(mainScreenRegion);
4430     }
4431 #endif
4432     DMError makeResult = MultiScreenManager::GetInstance().MirrorSwitch(mainScreenId,
4433         allMirrorScreenIds, mainScreenRegion, screenGroupId);
4434     if (makeResult != DMError::DM_OK) {
4435         TLOGE(WmsLogTag::DMS, "MakeMirror set mirror failed.");
4436         return makeResult;
4437     }
4438     for (ScreenId screenId : allMirrorScreenIds) {
4439         MirrorSwitchNotify(screenId);
4440     }
4441     RegisterCastObserver(allMirrorScreenIds);
4442     TLOGW(WmsLogTag::DMS, "make mirror notify scb end makeResult=%{public}d", makeResult);
4443     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeMirror end");
4444     return makeResult;
4445 #else
4446     return DMError::DM_OK;
4447 #endif
4448 }
4449 
MakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,ScreenId & screenGroupId)4450 DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
4451     ScreenId& screenGroupId)
4452 {
4453     return DoMakeMirror(mainScreenId, mirrorScreenIds, DMRect::NONE(), screenGroupId);
4454 }
4455 
MakeMirrorForRecord(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,ScreenId & screenGroupId)4456 DMError ScreenSessionManager::MakeMirrorForRecord(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
4457     ScreenId& screenGroupId)
4458 {
4459 #ifdef FOLD_ABILITY_ENABLE
4460     TLOGW(WmsLogTag::DMS, "start");
4461     ScreenId realScreenId = mainScreenId;
4462     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && mainScreenId == DISPLAY_ID_FAKE) {
4463         if (!SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
4464             TLOGE(WmsLogTag::DMS, "fake display is not exist!");
4465             return DMError::DM_ERROR_INVALID_PARAM;
4466         }
4467         realScreenId = 0;
4468     }
4469     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
4470         SuperFoldPolicy::GetInstance().IsNeedSetSnapshotRect(mainScreenId)) {
4471         DMRect mainScreenRect = SuperFoldPolicy::GetInstance().GetRecordRect(mainScreenId);
4472         return DoMakeMirror(realScreenId, mirrorScreenIds, mainScreenRect, screenGroupId);
4473     }
4474 #endif
4475     return DoMakeMirror(mainScreenId, mirrorScreenIds, DMRect::NONE(), screenGroupId);
4476 }
4477 
4478 
MakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,DMRect mainScreenRegion,ScreenId & screenGroupId)4479 DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
4480                                          DMRect mainScreenRegion, ScreenId& screenGroupId)
4481 {
4482     return DoMakeMirror(mainScreenId, mirrorScreenIds, mainScreenRegion, screenGroupId);
4483 }
4484 
RegisterCastObserver(std::vector<ScreenId> & mirrorScreenIds)4485 void ScreenSessionManager::RegisterCastObserver(std::vector<ScreenId>& mirrorScreenIds)
4486 {
4487     mirrorScreenIds_ = mirrorScreenIds;
4488     TLOGI(WmsLogTag::DMS, "Register Setting cast Observer");
4489     SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetCastFromSettingData(); };
4490     ScreenSettingHelper::RegisterSettingCastObserver(updateFunc);
4491 }
4492 
SetCastFromSettingData()4493 void ScreenSessionManager::SetCastFromSettingData()
4494 {
4495     bool enable;
4496     bool ret = ScreenSettingHelper::GetSettingCast(enable);
4497     if (!ret) {
4498         TLOGW(WmsLogTag::DMS, "get setting cast failed, default enable");
4499         enable = true;
4500     } else {
4501         TLOGI(WmsLogTag::DMS, "get setting cast success, enable: %{public}u", enable);
4502     }
4503     for (ScreenId screenId : mirrorScreenIds_) {
4504         ScreenId rsScreenId;
4505         if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4506             TLOGE(WmsLogTag::DMS, "No corresponding rsId");
4507             continue;
4508         }
4509         rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, enable);
4510     }
4511 }
4512 
RegisterSettingRotationObserver()4513 void ScreenSessionManager::RegisterSettingRotationObserver()
4514 {
4515     TLOGI(WmsLogTag::DMS, "start");
4516     SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) {
4517         int32_t rotation = -1;
4518         int32_t screenId = -1;
4519         if (ScreenSettingHelper::GetSettingRotation(rotation) &&
4520             ScreenSettingHelper::GetSettingRotationScreenID(screenId)) {
4521             TLOGNI(WmsLogTag::DMS, "current dms setting rotation:%{public}d, screenId:%{public}d",
4522                 rotation, screenId);
4523         } else {
4524             TLOGNI(WmsLogTag::DMS, "get current dms setting rotation and screenId failed");
4525         }
4526     };
4527     ScreenSettingHelper::RegisterSettingRotationObserver(updateFunc);
4528 }
4529 
RegisterSettingscreenSkipProtectedWindowObserver()4530 void ScreenSessionManager::RegisterSettingscreenSkipProtectedWindowObserver()
4531 {
4532     TLOGI(WmsLogTag::DMS, "start");
4533     SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetScreenSkipProtectedWindowInner(); };
4534     ScreenSettingHelper::RegisterSettingscreenSkipProtectedWindowObserver(updateFunc);
4535 }
4536 
StopMirror(const std::vector<ScreenId> & mirrorScreenIds)4537 DMError ScreenSessionManager::StopMirror(const std::vector<ScreenId>& mirrorScreenIds)
4538 {
4539     if (!SessionPermission::IsSystemCalling()) {
4540         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4541             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4542         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4543     }
4544     auto allMirrorScreenIds = GetAllValidScreenIds(mirrorScreenIds);
4545     if (allMirrorScreenIds.empty()) {
4546         TLOGW(WmsLogTag::DMS, "done. screens' size:%{public}u",
4547             static_cast<uint32_t>(allMirrorScreenIds.size()));
4548         return DMError::DM_OK;
4549     }
4550 
4551     DMError ret = StopScreens(allMirrorScreenIds, ScreenCombination::SCREEN_MIRROR);
4552     if (ret != DMError::DM_OK) {
4553         TLOGE(WmsLogTag::DMS, "failed.");
4554         return ret;
4555     }
4556     ScreenSettingHelper::UnregisterSettingCastObserver();
4557 
4558     return DMError::DM_OK;
4559 }
4560 
StopScreens(const std::vector<ScreenId> & screenIds,ScreenCombination stopCombination)4561 DMError ScreenSessionManager::StopScreens(const std::vector<ScreenId>& screenIds, ScreenCombination stopCombination)
4562 {
4563     for (ScreenId screenId : screenIds) {
4564         TLOGW(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64"", screenId);
4565         auto screen = GetScreenSession(screenId);
4566         if (screen == nullptr) {
4567             TLOGW(WmsLogTag::DMS, "screen:%{public}" PRIu64" is nullptr", screenId);
4568             continue;
4569         }
4570         sptr<ScreenSessionGroup> screenGroup = GetAbstractScreenGroup(screen->groupSmsId_);
4571         if (!screenGroup) {
4572             TLOGW(WmsLogTag::DMS, "groupDmsId:%{public}" PRIu64"is not in smsScreenGroupMap_",
4573                 screen->groupSmsId_);
4574             continue;
4575         }
4576         if (screenGroup->combination_ != stopCombination) {
4577             TLOGW(WmsLogTag::DMS, "try to stop screen in another combination");
4578             continue;
4579         }
4580         if (screenGroup->combination_ == ScreenCombination::SCREEN_MIRROR &&
4581             screen->screenId_ == screenGroup->mirrorScreenId_) {
4582             TLOGW(WmsLogTag::DMS, "try to stop main mirror screen");
4583             continue;
4584         }
4585         bool res = RemoveChildFromGroup(screen, screenGroup);
4586         if (res) {
4587             NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
4588         }
4589     }
4590     return DMError::DM_OK;
4591 }
4592 
GetVirtualScreenFlag(ScreenId screenId)4593 VirtualScreenFlag ScreenSessionManager::GetVirtualScreenFlag(ScreenId screenId)
4594 {
4595     if (!SessionPermission::IsSystemCalling()) {
4596         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4597             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4598         return VirtualScreenFlag::DEFAULT;
4599     }
4600     auto screen = GetScreenSession(screenId);
4601     if (screen == nullptr) {
4602         TLOGE(WmsLogTag::DMS, "screen session null");
4603         return VirtualScreenFlag::DEFAULT;
4604     }
4605     return screen->GetVirtualScreenFlag();
4606 }
4607 
SetVirtualScreenFlag(ScreenId screenId,VirtualScreenFlag screenFlag)4608 DMError ScreenSessionManager::SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag)
4609 {
4610     if (!SessionPermission::IsSystemCalling()) {
4611         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4612             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4613         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4614     }
4615     if (screenFlag < VirtualScreenFlag::DEFAULT || screenFlag >= VirtualScreenFlag::MAX) {
4616         TLOGE(WmsLogTag::DMS, "range error");
4617         return DMError::DM_ERROR_INVALID_PARAM;
4618     }
4619     auto screen = GetScreenSession(screenId);
4620     if (screen == nullptr) {
4621         TLOGE(WmsLogTag::DMS, "screen session null");
4622         return DMError::DM_ERROR_INVALID_PARAM;
4623     }
4624     screen->SetVirtualScreenFlag(screenFlag);
4625     return DMError::DM_OK;
4626 }
4627 
SetVirtualScreenRefreshRate(ScreenId screenId,uint32_t refreshInterval)4628 DMError ScreenSessionManager::SetVirtualScreenRefreshRate(ScreenId screenId, uint32_t refreshInterval)
4629 {
4630     if (!SessionPermission::IsSystemCalling()) {
4631         TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
4632             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4633         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4634     }
4635     TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64", refreshInterval:  %{public}u",
4636         screenId, refreshInterval);
4637     if (screenId == GetDefaultScreenId()) {
4638         TLOGE(WmsLogTag::DMS, "cannot set refresh rate of main screen id: %{public}" PRIu64, GetDefaultScreenId());
4639         return DMError::DM_ERROR_INVALID_PARAM;
4640     }
4641     if (refreshInterval == 0) {
4642         TLOGE(WmsLogTag::DMS, "refresh interval is 0.");
4643         return DMError::DM_ERROR_INVALID_PARAM;
4644     }
4645     auto screenSession = GetScreenSession(screenId);
4646     auto defaultScreenSession = GetDefaultScreenSession();
4647     if (screenSession == nullptr || defaultScreenSession == nullptr) {
4648         TLOGE(WmsLogTag::DMS, "screenSession is null.");
4649         return DMError::DM_ERROR_INVALID_PARAM;
4650     }
4651     ScreenId rsScreenId;
4652     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4653         TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
4654         return DMError::DM_ERROR_INVALID_PARAM;
4655     }
4656     int32_t res = rsInterface_.SetScreenSkipFrameInterval(rsScreenId, refreshInterval);
4657     if (res != StatusCode::SUCCESS) {
4658         TLOGE(WmsLogTag::DMS, "rsInterface error: %{public}d", res);
4659         return DMError::DM_ERROR_INVALID_PARAM;
4660     }
4661     // when skipFrameInterval > 10 means the skipFrameInterval is the virtual screen refresh rate
4662     if (refreshInterval > IRREGULAR_REFRESH_RATE_SKIP_THRETHOLD) {
4663         screenSession->UpdateRefreshRate(refreshInterval);
4664     } else {
4665         screenSession->UpdateRefreshRate(defaultScreenSession->GetRefreshRate() / refreshInterval);
4666     }
4667     TLOGW(WmsLogTag::DMS, "refreshInterval is %{public}d", refreshInterval);
4668     return DMError::DM_OK;
4669 }
4670 
VirtualScreenUniqueSwitch(const std::vector<ScreenId> & screenIds)4671 DMError ScreenSessionManager::VirtualScreenUniqueSwitch(const std::vector<ScreenId>& screenIds)
4672 {
4673 #ifdef WM_MULTI_SCREEN_ENABLE
4674     TLOGW(WmsLogTag::DMS, "enter");
4675     auto defaultScreen = GetDefaultScreenSession();
4676     if (!defaultScreen) {
4677         TLOGE(WmsLogTag::DMS, "default screen is nullptr");
4678         return DMError::DM_ERROR_NULLPTR;
4679     }
4680     defaultScreen->groupSmsId_ = 1;
4681     {
4682         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4683         auto iter = smsScreenGroupMap_.find(defaultScreen->groupSmsId_);
4684         if (iter != smsScreenGroupMap_.end()) {
4685             smsScreenGroupMap_.erase(iter);
4686         }
4687     }
4688     DMError uniqueSwitchRet = MultiScreenManager::GetInstance().VirtualScreenUniqueSwitch(defaultScreen, screenIds);
4689     TLOGW(WmsLogTag::DMS, "result: %{public}d", uniqueSwitchRet);
4690     return uniqueSwitchRet;
4691 #else
4692     return DMError::DM_OK;
4693 #endif
4694 }
4695 
MakeUniqueScreen(const std::vector<ScreenId> & screenIds,std::vector<DisplayId> & displayIds)4696 DMError ScreenSessionManager::MakeUniqueScreen(const std::vector<ScreenId>& screenIds,
4697     std::vector<DisplayId>& displayIds)
4698 {
4699 #ifdef WM_MULTI_SCREEN_ENABLE
4700     bool isCallingByThirdParty = Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION);
4701     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd() && !isCallingByThirdParty) {
4702         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4703             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4704         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4705     }
4706     TLOGW(WmsLogTag::DMS, "enter!");
4707     if (screenIds.empty()) {
4708         TLOGE(WmsLogTag::DMS, "screen is empty");
4709         return DMError::DM_ERROR_INVALID_PARAM;
4710     }
4711     std::vector<ScreenId> validScreenIds;
4712     for (auto screenId : screenIds) {
4713         if (!IsDefaultMirrorMode(screenId)) {
4714             continue;
4715         }
4716         validScreenIds.emplace_back(screenId);
4717     }
4718     const auto& allUniqueScreenIds = GetAllValidScreenIds(validScreenIds);
4719     if (allUniqueScreenIds.empty()) {
4720         TLOGE(WmsLogTag::DMS, "screenIds is invalid.");
4721         return DMError::DM_ERROR_NULLPTR;
4722     }
4723     ScreenId uniqueScreenId = validScreenIds[0];
4724     auto uniqueScreen = GetScreenSession(uniqueScreenId);
4725     if (uniqueScreen != nullptr) {
4726         if (uniqueScreen->GetSourceMode() == ScreenSourceMode::SCREEN_UNIQUE) {
4727             TLOGW(WmsLogTag::DMS, "make unique ignore");
4728             return DMError::DM_OK;
4729         }
4730         if (isCallingByThirdParty) {
4731             uniqueScreen->SetInnerName("CustomScbScreen");
4732         }
4733         return MultiScreenManager::GetInstance().UniqueSwitch(allUniqueScreenIds, displayIds);
4734     }
4735     return DoMakeUniqueScreenOld(allUniqueScreenIds, displayIds, isCallingByThirdParty);
4736 }
4737 
DoMakeUniqueScreenOld(const std::vector<ScreenId> & allUniqueScreenIds,std::vector<DisplayId> & displayIds,bool isCallingByThirdParty)4738 DMError ScreenSessionManager::DoMakeUniqueScreenOld(const std::vector<ScreenId>& allUniqueScreenIds,
4739     std::vector<DisplayId>& displayIds, bool isCallingByThirdParty)
4740 {
4741     for (auto screenId : allUniqueScreenIds) {
4742         ScreenId rsScreenId = SCREEN_ID_INVALID;
4743         bool res = ConvertScreenIdToRsScreenId(screenId, rsScreenId);
4744         TLOGI(WmsLogTag::DMS, "unique screenId: %{public}" PRIu64" rsScreenId: %{public}" PRIu64,
4745             screenId, rsScreenId);
4746         if (!res) {
4747             TLOGE(WmsLogTag::DMS, "convert screenId to rsScreenId failed");
4748             continue;
4749         }
4750         auto screenSession = GetScreenSession(screenId);
4751         if (!screenSession) {
4752             TLOGE(WmsLogTag::DMS, "screen session is nullptr");
4753             continue;
4754         }
4755         displayIds.emplace_back(static_cast<uint64_t>(screenId));
4756         Rosen::RSDisplayNodeConfig rsConfig;
4757         rsConfig.screenId = rsScreenId;
4758         screenSession->CreateDisplayNode(rsConfig);
4759         screenSession->SetDisplayNodeScreenId(rsScreenId);
4760         if (isCallingByThirdParty) {
4761             screenSession->SetInnerName("CustomScbScreen");
4762         }
4763         // notify scb to build Screen widget
4764         OnVirtualScreenChange(screenId, ScreenEvent::CONNECTED);
4765     }
4766     auto transactionProxy = RSTransactionProxy::GetInstance();
4767     if (transactionProxy != nullptr) {
4768         TLOGD(WmsLogTag::DMS, "flush data");
4769         transactionProxy->FlushImplicitTransaction();
4770     }
4771 #endif
4772     return DMError::DM_OK;
4773 }
4774 
MakeExpand(std::vector<ScreenId> screenId,std::vector<Point> startPoint,ScreenId & screenGroupId)4775 DMError ScreenSessionManager::MakeExpand(std::vector<ScreenId> screenId,
4776                                          std::vector<Point> startPoint,
4777                                          ScreenId& screenGroupId)
4778 {
4779     TLOGI(WmsLogTag::DMS, "enter!");
4780     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4781         TLOGE(WmsLogTag::DMS, "permission denied! pid: %{public}d", IPCSkeleton::GetCallingPid());
4782         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4783     }
4784     if (screenId.empty() || startPoint.empty() || screenId.size() != startPoint.size()) {
4785         TLOGE(WmsLogTag::DMS, "create expand fail, screenId size:%{public}ud,startPoint size:%{public}ud",
4786             static_cast<uint32_t>(screenId.size()), static_cast<uint32_t>(startPoint.size()));
4787         return DMError::DM_ERROR_INVALID_PARAM;
4788     }
4789     std::map<ScreenId, Point> pointsMap;
4790     uint32_t size = screenId.size();
4791     for (uint32_t i = 0; i < size; i++) {
4792         if (pointsMap.find(screenId[i]) != pointsMap.end()) {
4793             continue;
4794         }
4795         pointsMap[screenId[i]] = startPoint[i];
4796     }
4797     ScreenId defaultScreenId = GetDefaultScreenId();
4798     auto allExpandScreenIds = GetAllValidScreenIds(screenId);
4799     auto iter = std::find(allExpandScreenIds.begin(), allExpandScreenIds.end(), defaultScreenId);
4800     if (iter != allExpandScreenIds.end()) {
4801         allExpandScreenIds.erase(iter);
4802     }
4803     if (allExpandScreenIds.empty()) {
4804         TLOGE(WmsLogTag::DMS, "allExpandScreenIds is empty. make expand failed.");
4805         return DMError::DM_ERROR_NULLPTR;
4806     }
4807     std::shared_ptr<RSDisplayNode> rsDisplayNode;
4808     std::vector<Point> points;
4809     for (uint32_t i = 0; i < allExpandScreenIds.size(); i++) {
4810         rsDisplayNode = GetRSDisplayNodeByScreenId(allExpandScreenIds[i]);
4811         points.emplace_back(pointsMap[allExpandScreenIds[i]]);
4812         if (rsDisplayNode != nullptr) {
4813             rsDisplayNode->SetDisplayOffset(pointsMap[allExpandScreenIds[i]].posX_,
4814                 pointsMap[allExpandScreenIds[i]].posY_);
4815         }
4816     }
4817     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeExpand");
4818     if (!OnMakeExpand(allExpandScreenIds, points)) {
4819         return DMError::DM_ERROR_NULLPTR;
4820     }
4821     auto screen = GetScreenSession(allExpandScreenIds[0]);
4822     if (screen == nullptr || GetAbstractScreenGroup(screen->groupSmsId_) == nullptr) {
4823         return DMError::DM_ERROR_NULLPTR;
4824     }
4825     screenGroupId = screen->groupSmsId_;
4826     return DMError::DM_OK;
4827 }
4828 
OnMakeExpand(std::vector<ScreenId> screenId,std::vector<Point> startPoint)4829 bool ScreenSessionManager::OnMakeExpand(std::vector<ScreenId> screenId, std::vector<Point> startPoint)
4830 {
4831     ScreenId defaultScreenId = GetDefaultScreenId();
4832     TLOGI(WmsLogTag::DMS, "defaultScreenId:%{public}" PRIu64"", defaultScreenId);
4833     auto defaultScreen = GetScreenSession(defaultScreenId);
4834     if (defaultScreen == nullptr) {
4835         TLOGI(WmsLogTag::DMS, "failed.");
4836         return false;
4837     }
4838     auto group = GetAbstractScreenGroup(defaultScreen->groupSmsId_);
4839     if (group == nullptr) {
4840         group = AddToGroupLocked(defaultScreen);
4841         if (group == nullptr) {
4842             TLOGE(WmsLogTag::DMS, "group is nullptr");
4843             return false;
4844         }
4845         NotifyScreenGroupChanged(defaultScreen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
4846     }
4847     bool filterExpandScreen = group->combination_ == ScreenCombination::SCREEN_EXPAND;
4848     ChangeScreenGroup(group, screenId, startPoint, filterExpandScreen, ScreenCombination::SCREEN_EXPAND);
4849     TLOGI(WmsLogTag::DMS, "success");
4850     return true;
4851 }
4852 
StopExpand(const std::vector<ScreenId> & expandScreenIds)4853 DMError ScreenSessionManager::StopExpand(const std::vector<ScreenId>& expandScreenIds)
4854 {
4855     if (!SessionPermission::IsSystemCalling()) {
4856         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4857             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4858         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4859     }
4860     auto allExpandScreenIds = GetAllValidScreenIds(expandScreenIds);
4861     if (allExpandScreenIds.empty()) {
4862         TLOGI(WmsLogTag::DMS, "done. screens' size:%{public}u",
4863             static_cast<uint32_t>(allExpandScreenIds.size()));
4864         return DMError::DM_OK;
4865     }
4866 
4867     DMError ret = StopScreens(allExpandScreenIds, ScreenCombination::SCREEN_EXPAND);
4868     if (ret != DMError::DM_OK) {
4869         TLOGE(WmsLogTag::DMS, "stop expand failed.");
4870         return ret;
4871     }
4872 
4873     return DMError::DM_OK;
4874 }
4875 
ConvertToRsScreenId(ScreenId smsScreenId,ScreenId & rsScreenId) const4876 bool ScreenSessionManager::ScreenIdManager::ConvertToRsScreenId(ScreenId smsScreenId, ScreenId& rsScreenId) const
4877 {
4878     std::shared_lock lock(screenIdMapMutex_);
4879     auto iter = sms2RsScreenIdMap_.find(smsScreenId);
4880     if (iter == sms2RsScreenIdMap_.end()) {
4881         return false;
4882     }
4883     rsScreenId = iter->second;
4884     return true;
4885 }
4886 
ConvertToRsScreenId(ScreenId screenId) const4887 ScreenId ScreenSessionManager::ScreenIdManager::ConvertToRsScreenId(ScreenId screenId) const
4888 {
4889     ScreenId rsScreenId = SCREEN_ID_INVALID;
4890     ConvertToRsScreenId(screenId, rsScreenId);
4891     return rsScreenId;
4892 }
4893 
ConvertToSmsScreenId(ScreenId rsScreenId) const4894 ScreenId ScreenSessionManager::ScreenIdManager::ConvertToSmsScreenId(ScreenId rsScreenId) const
4895 {
4896     ScreenId smsScreenId = SCREEN_ID_INVALID;
4897     ConvertToSmsScreenId(rsScreenId, smsScreenId);
4898     return smsScreenId;
4899 }
4900 
ConvertToSmsScreenId(ScreenId rsScreenId,ScreenId & smsScreenId) const4901 bool ScreenSessionManager::ScreenIdManager::ConvertToSmsScreenId(ScreenId rsScreenId, ScreenId& smsScreenId) const
4902 {
4903     std::shared_lock lock(screenIdMapMutex_);
4904     auto iter = rs2SmsScreenIdMap_.find(rsScreenId);
4905     if (iter == rs2SmsScreenIdMap_.end()) {
4906         return false;
4907     }
4908     smsScreenId = iter->second;
4909     return true;
4910 }
4911 
CreateAndGetNewScreenId(ScreenId rsScreenId)4912 ScreenId ScreenSessionManager::ScreenIdManager::CreateAndGetNewScreenId(ScreenId rsScreenId)
4913 {
4914     std::unique_lock lock(screenIdMapMutex_);
4915     ScreenId smsScreenId = smsScreenCount_++;
4916     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64"", smsScreenId);
4917     if (sms2RsScreenIdMap_.find(smsScreenId) != sms2RsScreenIdMap_.end()) {
4918         TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64" exit", smsScreenId);
4919     }
4920     sms2RsScreenIdMap_[smsScreenId] = rsScreenId;
4921     if (rsScreenId == SCREEN_ID_INVALID) {
4922         return smsScreenId;
4923     }
4924     if (rs2SmsScreenIdMap_.find(rsScreenId) != rs2SmsScreenIdMap_.end()) {
4925         TLOGW(WmsLogTag::DMS, "rsScreenId: %{public}" PRIu64" exit", rsScreenId);
4926     }
4927     rs2SmsScreenIdMap_[rsScreenId] = smsScreenId;
4928     return smsScreenId;
4929 }
4930 
UpdateScreenId(ScreenId rsScreenId,ScreenId smsScreenId)4931 void ScreenSessionManager::ScreenIdManager::UpdateScreenId(ScreenId rsScreenId, ScreenId smsScreenId)
4932 {
4933     std::unique_lock lock(screenIdMapMutex_);
4934     rs2SmsScreenIdMap_[rsScreenId] = smsScreenId;
4935     sms2RsScreenIdMap_[smsScreenId] = rsScreenId;
4936 }
4937 
DeleteScreenId(ScreenId smsScreenId)4938 bool ScreenSessionManager::ScreenIdManager::DeleteScreenId(ScreenId smsScreenId)
4939 {
4940     std::unique_lock lock(screenIdMapMutex_);
4941     auto iter = sms2RsScreenIdMap_.find(smsScreenId);
4942     if (iter == sms2RsScreenIdMap_.end()) {
4943         return false;
4944     }
4945     ScreenId rsScreenId = iter->second;
4946     sms2RsScreenIdMap_.erase(smsScreenId);
4947     rs2SmsScreenIdMap_.erase(rsScreenId);
4948     return true;
4949 }
4950 
HasRsScreenId(ScreenId smsScreenId) const4951 bool ScreenSessionManager::ScreenIdManager::HasRsScreenId(ScreenId smsScreenId) const
4952 {
4953     std::shared_lock lock(screenIdMapMutex_);
4954     return rs2SmsScreenIdMap_.find(smsScreenId) != rs2SmsScreenIdMap_.end();
4955 }
4956 
InitVirtualScreen(ScreenId smsScreenId,ScreenId rsId,VirtualScreenOption option)4957 sptr<ScreenSession> ScreenSessionManager::InitVirtualScreen(ScreenId smsScreenId, ScreenId rsId,
4958     VirtualScreenOption option)
4959 {
4960     TLOGI(WmsLogTag::DMS, "Enter");
4961     ScreenSessionConfig config = {
4962         .screenId = smsScreenId,
4963         .rsId = rsId,
4964         .defaultScreenId = GetDefaultScreenId(),
4965         .name = option.name_,
4966     };
4967     sptr<ScreenSession> screenSession =
4968         new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
4969     sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
4970     if (screenSession == nullptr || info == nullptr) {
4971         TLOGI(WmsLogTag::DMS, "new screenSession or info failed");
4972         screenIdManager_.DeleteScreenId(smsScreenId);
4973         rsInterface_.RemoveVirtualScreen(rsId);
4974         return nullptr;
4975     }
4976     info->width_ = option.width_;
4977     info->height_ = option.height_;
4978     auto defaultScreen = GetScreenSession(GetDefaultScreenId());
4979     if (defaultScreen != nullptr && defaultScreen->GetActiveScreenMode() != nullptr) {
4980         info->refreshRate_ = defaultScreen->GetActiveScreenMode()->refreshRate_;
4981     }
4982     screenSession->modes_.emplace_back(info);
4983     screenSession->activeIdx_ = 0;
4984     screenSession->SetScreenType(ScreenType::VIRTUAL);
4985     screenSession->SetVirtualPixelRatio(option.density_);
4986     screenSession->SetIsPcUse(g_isPcDevice ? true : false);
4987     screenSession->SetDisplayBoundary(RectF(0, 0, option.width_, option.height_), 0);
4988     screenSession->RegisterScreenChangeListener(this);
4989     return screenSession;
4990 }
4991 
InitAbstractScreenModesInfo(sptr<ScreenSession> & screenSession)4992 bool ScreenSessionManager::InitAbstractScreenModesInfo(sptr<ScreenSession>& screenSession)
4993 {
4994     TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenSupportedModes");
4995     std::vector<RSScreenModeInfo> allModes = rsInterface_.GetScreenSupportedModes(
4996         screenIdManager_.ConvertToRsScreenId(screenSession->screenId_));
4997     if (allModes.size() == 0) {
4998         TLOGE(WmsLogTag::DMS, "allModes.size() == 0, screenId=%{public}" PRIu64"", screenSession->rsId_);
4999         return false;
5000     }
5001     for (const RSScreenModeInfo& rsScreenModeInfo : allModes) {
5002         sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
5003         if (info == nullptr) {
5004             TLOGE(WmsLogTag::DMS, "create SupportedScreenModes failed");
5005             return false;
5006         }
5007         info->id_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenModeId());
5008         info->width_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenWidth());
5009         info->height_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenHeight());
5010         info->refreshRate_ = rsScreenModeInfo.GetScreenRefreshRate();
5011         screenSession->modes_.push_back(info);
5012         TLOGW(WmsLogTag::DMS, "fill screen idx:%{public}d w/h:%{public}d/%{public}d",
5013             rsScreenModeInfo.GetScreenModeId(), info->width_, info->height_);
5014     }
5015     TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenActiveMode");
5016     int32_t activeModeId = rsInterface_.GetScreenActiveMode(screenSession->rsId_).GetScreenModeId();
5017     TLOGW(WmsLogTag::DMS, "fill screen activeModeId:%{public}d", activeModeId);
5018     if (static_cast<std::size_t>(activeModeId) >= allModes.size()) {
5019         TLOGE(WmsLogTag::DMS, "activeModeId exceed, screenId=%{public}" PRIu64", activeModeId:%{public}d/%{public}ud",
5020             screenSession->rsId_, activeModeId, static_cast<uint32_t>(allModes.size()));
5021         return false;
5022     }
5023     screenSession->activeIdx_ = activeModeId;
5024     return true;
5025 }
5026 
InitAndGetScreen(ScreenId rsScreenId)5027 sptr<ScreenSession> ScreenSessionManager::InitAndGetScreen(ScreenId rsScreenId)
5028 {
5029     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5030     ScreenId smsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsScreenId);
5031     RSScreenCapability screenCapability = rsInterface_.GetScreenCapability(rsScreenId);
5032     TLOGI(WmsLogTag::DMS, "Screen name is %{public}s, phyWidth is %{public}u, phyHeight is %{public}u",
5033         screenCapability.GetName().c_str(), screenCapability.GetPhyWidth(), screenCapability.GetPhyHeight());
5034     ScreenSessionConfig config = {
5035         .screenId = smsScreenId,
5036         .rsId = rsScreenId,
5037         .defaultScreenId = GetDefaultScreenId(),
5038         .name = screenCapability.GetName(),
5039     };
5040     sptr<ScreenSession> screenSession =
5041         new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_VIRTUAL);
5042     if (screenSession == nullptr) {
5043         TLOGE(WmsLogTag::DMS, "screenSession == nullptr.");
5044         screenIdManager_.DeleteScreenId(smsScreenId);
5045         return nullptr;
5046     }
5047     if (!InitAbstractScreenModesInfo(screenSession)) {
5048         screenIdManager_.DeleteScreenId(smsScreenId);
5049         TLOGE(WmsLogTag::DMS, "failed.");
5050         return nullptr;
5051     }
5052     TLOGI(WmsLogTag::DMS, "screenSessionMap_ add screenId=%{public}" PRIu64"", smsScreenId);
5053     screenSessionMap_.insert(std::make_pair(smsScreenId, screenSession));
5054     return screenSession;
5055 }
5056 
IsExtendMode()5057 bool ScreenSessionManager::IsExtendMode()
5058 {
5059     std::vector<ScreenId> mainVector;
5060     std::vector<ScreenId> extendVector;
5061     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5062     for (const auto& pair : screenSessionMap_) {
5063         sptr<ScreenSession> session = pair.second;
5064         if (!session) {
5065             TLOGE(WmsLogTag::DMS, "screenId=%{public}" PRIu64", session is null", pair.first);
5066             continue;
5067         }
5068         if (session->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
5069             extendVector.push_back(session->GetScreenId());
5070         }
5071         if (session->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
5072             mainVector.push_back(session->GetScreenId());
5073         }
5074     }
5075     std::ostringstream oss;
5076     oss << "main screenId:";
5077     for (const auto& screenId : mainVector) {
5078         oss << static_cast<uint64_t>(screenId);
5079     }
5080     oss << ", extend screenId:";
5081     for (const auto& screenId : extendVector) {
5082         oss << static_cast<uint64_t>(screenId);
5083     }
5084     oss << std::endl;
5085     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
5086     return mainVector.size() > 0 && extendVector.size() > 0;
5087 }
5088 
AddToGroupLocked(sptr<ScreenSession> newScreen,bool isUnique)5089 sptr<ScreenSessionGroup> ScreenSessionManager::AddToGroupLocked(sptr<ScreenSession> newScreen, bool isUnique)
5090 {
5091     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5092     sptr<ScreenSessionGroup> res;
5093     if (smsScreenGroupMap_.empty()) {
5094         TLOGI(WmsLogTag::DMS, "connect the first screen");
5095         res = AddAsFirstScreenLocked(newScreen, isUnique);
5096     } else {
5097         res = AddAsSuccedentScreenLocked(newScreen);
5098     }
5099     return res;
5100 }
5101 
AddAsFirstScreenLocked(sptr<ScreenSession> newScreen,bool isUnique)5102 sptr<ScreenSessionGroup> ScreenSessionManager::AddAsFirstScreenLocked(sptr<ScreenSession> newScreen, bool isUnique)
5103 {
5104     ScreenId smsGroupScreenId(1);
5105     std::ostringstream buffer;
5106     buffer << "ScreenGroup_" << smsGroupScreenId;
5107     std::string name = buffer.str();
5108     // default ScreenCombination is mirror
5109     isExpandCombination_ = system::GetParameter("persist.display.expand.enabled", "0") == "1";
5110     sptr<ScreenSessionGroup> screenGroup;
5111     if (isExpandCombination_) {
5112         screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
5113             SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_EXPAND);
5114     } else if (isUnique) {
5115         screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
5116             SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_UNIQUE);
5117     } else {
5118         screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
5119             SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_MIRROR);
5120     }
5121     if (screenGroup == nullptr) {
5122         TLOGE(WmsLogTag::DMS, "new ScreenSessionGroup failed");
5123         screenIdManager_.DeleteScreenId(smsGroupScreenId);
5124         return nullptr;
5125     }
5126     screenGroup->groupSmsId_ = 1;
5127     Point point;
5128     if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none") {
5129         if (IsExtendMode()) {
5130             point = {newScreen->GetScreenProperty().GetStartX(), newScreen->GetScreenProperty().GetStartY()};
5131         }
5132     }
5133     if (!screenGroup->AddChild(newScreen, point, GetScreenSession(GetDefaultScreenId()),
5134         IsExtendMode() && g_isPcDevice)) {
5135         TLOGE(WmsLogTag::DMS, "fail to add screen to group. screen=%{public}" PRIu64"", newScreen->screenId_);
5136         screenIdManager_.DeleteScreenId(smsGroupScreenId);
5137         return nullptr;
5138     }
5139     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5140     auto iter = smsScreenGroupMap_.find(smsGroupScreenId);
5141     if (iter != smsScreenGroupMap_.end()) {
5142         TLOGE(WmsLogTag::DMS, "group screen existed. id=%{public}" PRIu64"", smsGroupScreenId);
5143         smsScreenGroupMap_.erase(iter);
5144     }
5145     smsScreenGroupMap_.insert(std::make_pair(smsGroupScreenId, screenGroup));
5146     screenGroup->mirrorScreenId_ = newScreen->screenId_;
5147     TLOGI(WmsLogTag::DMS, "connect new group screen, screenId: %{public}" PRIu64", screenGroupId: %{public}" PRIu64", "
5148         "combination:%{public}u", newScreen->screenId_, smsGroupScreenId,
5149         newScreen->GetScreenProperty().GetScreenType());
5150     return screenGroup;
5151 }
5152 
AddAsSuccedentScreenLocked(sptr<ScreenSession> newScreen)5153 sptr<ScreenSessionGroup> ScreenSessionManager::AddAsSuccedentScreenLocked(sptr<ScreenSession> newScreen)
5154 {
5155     ScreenId defaultScreenId = GetDefaultScreenId();
5156     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5157     auto iter = screenSessionMap_.find(defaultScreenId);
5158     if (iter == screenSessionMap_.end()) {
5159         TLOGE(WmsLogTag::DMS, "defaultScreenId:%{public}" PRIu64" is not in screenSessionMap_.",
5160             defaultScreenId);
5161         return nullptr;
5162     }
5163     auto screen = iter->second;
5164     auto screenGroupIter = smsScreenGroupMap_.find(screen->groupSmsId_);
5165     if (screenGroupIter == smsScreenGroupMap_.end()) {
5166         TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64" is not in smsScreenGroupMap_.",
5167             screen->groupSmsId_);
5168         return nullptr;
5169     }
5170     auto screenGroup = screenGroupIter->second;
5171     Point point;
5172     if (screenGroup->combination_ == ScreenCombination::SCREEN_EXPAND) {
5173         point = {screen->GetActiveScreenMode()->width_, 0};
5174     }
5175     screenGroup->AddChild(newScreen, point, screen);
5176     return screenGroup;
5177 }
5178 
RemoveFromGroupLocked(sptr<ScreenSession> screen)5179 sptr<ScreenSessionGroup> ScreenSessionManager::RemoveFromGroupLocked(sptr<ScreenSession> screen)
5180 {
5181     TLOGI(WmsLogTag::DMS, "start");
5182     auto groupSmsId = screen->groupSmsId_;
5183     sptr<ScreenSessionGroup> screenGroup = GetAbstractScreenGroup(groupSmsId);
5184     if (!screenGroup) {
5185         TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64"is not in smsScreenGroupMap_.",
5186             groupSmsId);
5187         return nullptr;
5188     }
5189     if (!RemoveChildFromGroup(screen, screenGroup)) {
5190         return nullptr;
5191     }
5192     return screenGroup;
5193 }
5194 
RemoveChildFromGroup(sptr<ScreenSession> screen,sptr<ScreenSessionGroup> screenGroup)5195 bool ScreenSessionManager::RemoveChildFromGroup(sptr<ScreenSession> screen, sptr<ScreenSessionGroup> screenGroup)
5196 {
5197     bool res = screenGroup->RemoveChild(screen);
5198     auto transactionProxy = RSTransactionProxy::GetInstance();
5199     if (transactionProxy != nullptr) {
5200         transactionProxy->FlushImplicitTransaction();
5201         TLOGI(WmsLogTag::DMS, "remove child and call flush.");
5202     }
5203     if (!res) {
5204         TLOGE(WmsLogTag::DMS, "remove screen:%{public}" PRIu64" failed from screenGroup:%{public}" PRIu64".",
5205             screen->screenId_, screen->groupSmsId_);
5206         return false;
5207     }
5208     if (screenGroup->GetChildCount() == 0) {
5209         // Group removed, need to do something.
5210         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5211         smsScreenGroupMap_.erase(screenGroup->screenId_);
5212         screenSessionMap_.erase(screenGroup->screenId_);
5213         TLOGE(WmsLogTag::DMS, "screenSessionMap_ remove screen:%{public}" PRIu64, screenGroup->screenId_);
5214     }
5215     return true;
5216 }
5217 
SetMirror(ScreenId screenId,std::vector<ScreenId> screens,DMRect mainScreenRegion)5218 DMError ScreenSessionManager::SetMirror(ScreenId screenId, std::vector<ScreenId> screens, DMRect mainScreenRegion)
5219 {
5220     TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64"", screenId);
5221     sptr<ScreenSession> screen = GetScreenSession(screenId);
5222     if (screen == nullptr || screen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
5223         TLOGE(WmsLogTag::DMS, "screen is nullptr, or screenCommbination is mirror.");
5224         return DMError::DM_ERROR_NULLPTR;
5225     }
5226     screen->groupSmsId_ = 1;
5227     auto group = GetAbstractScreenGroup(screen->groupSmsId_);
5228     if (group == nullptr) {
5229         group = AddToGroupLocked(screen);
5230         if (group == nullptr) {
5231             TLOGE(WmsLogTag::DMS, "group is nullptr");
5232             return DMError::DM_ERROR_NULLPTR;
5233         }
5234         NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
5235     }
5236     Point point;
5237     std::vector<Point> startPoints;
5238     startPoints.insert(startPoints.begin(), screens.size(), point);
5239     bool filterMirroredScreen =
5240         group->combination_ == ScreenCombination::SCREEN_MIRROR && group->mirrorScreenId_ == screen->screenId_;
5241     group->mirrorScreenId_ = screen->screenId_;
5242     ChangeScreenGroup(group, screens, startPoints, filterMirroredScreen, ScreenCombination::SCREEN_MIRROR,
5243         mainScreenRegion);
5244     TLOGI(WmsLogTag::DMS, "success");
5245     return DMError::DM_OK;
5246 }
5247 
GetAbstractScreenGroup(ScreenId smsScreenId)5248 sptr<ScreenSessionGroup> ScreenSessionManager::GetAbstractScreenGroup(ScreenId smsScreenId)
5249 {
5250     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5251     auto iter = smsScreenGroupMap_.find(smsScreenId);
5252     if (iter == smsScreenGroupMap_.end()) {
5253         TLOGE(WmsLogTag::DMS, "did not find screen:%{public}" PRIu64"", smsScreenId);
5254         return nullptr;
5255     }
5256     return iter->second;
5257 }
5258 
CheckScreenInScreenGroup(sptr<ScreenSession> screen) const5259 bool ScreenSessionManager::CheckScreenInScreenGroup(sptr<ScreenSession> screen) const
5260 {
5261     if (screen == nullptr) {
5262         TLOGE(WmsLogTag::DMS, "screen is nullptr");
5263         return false;
5264     }
5265     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5266     auto groupSmsId = screen->groupSmsId_;
5267     auto iter = smsScreenGroupMap_.find(groupSmsId);
5268     if (iter == smsScreenGroupMap_.end()) {
5269         TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64"is not in smsScreenGroupMap_.", groupSmsId);
5270         return false;
5271     }
5272     sptr<ScreenSessionGroup> screenGroup = iter->second;
5273     return screenGroup->HasChild(screen->screenId_);
5274 }
5275 
ChangeScreenGroup(sptr<ScreenSessionGroup> group,const std::vector<ScreenId> & screens,const std::vector<Point> & startPoints,bool filterScreen,ScreenCombination combination,DMRect mainScreenRegion)5276 void ScreenSessionManager::ChangeScreenGroup(sptr<ScreenSessionGroup> group, const std::vector<ScreenId>& screens,
5277     const std::vector<Point>& startPoints, bool filterScreen, ScreenCombination combination, DMRect mainScreenRegion)
5278 {
5279     std::map<ScreenId, bool> removeChildResMap;
5280     std::vector<ScreenId> addScreens;
5281     std::vector<Point> addChildPos;
5282     for (uint64_t i = 0; i != screens.size(); i++) {
5283         ScreenId screenId = screens[i];
5284         TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64"", screenId);
5285         auto screen = GetScreenSession(screenId);
5286         if (screen == nullptr) {
5287             TLOGE(WmsLogTag::DMS, "screen:%{public}" PRIu64" is nullptr", screenId);
5288             continue;
5289         }
5290         TLOGI(WmsLogTag::DMS, "Screen->groupSmsId_: %{public}" PRIu64"", screen->groupSmsId_);
5291         screen->groupSmsId_ = 1;
5292         if (filterScreen && screen->groupSmsId_ == group->screenId_ && group->HasChild(screen->screenId_)) {
5293             // screen already in group
5294             if (combination != ScreenCombination::SCREEN_MIRROR ||
5295                 (screen->GetMirrorScreenRegion().second == mainScreenRegion &&
5296                  screen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR)) {
5297                 continue;
5298             }
5299             // mirror mode and mirror area change
5300             TLOGI(WmsLogTag::DMS, "Screen: %{public}" PRIu64
5301                 ", apply new region, x:%{public}d y:%{public}d w:%{public}u h:%{public}u",
5302                 screenId, mainScreenRegion.posX_, mainScreenRegion.posY_,
5303                 mainScreenRegion.width_, mainScreenRegion.height_);
5304         }
5305         if (CheckScreenInScreenGroup(screen)) {
5306             NotifyDisplayDestroy(screenId);
5307         }
5308         auto originGroup = RemoveFromGroupLocked(screen);
5309         addChildPos.emplace_back(startPoints[i]);
5310         removeChildResMap[screenId] = originGroup != nullptr;
5311         addScreens.emplace_back(screenId);
5312         if (combination == ScreenCombination::SCREEN_MIRROR) {
5313             auto mirrorScreenId = group->mirrorScreenId_;
5314             ScreenId rsScreenId = SCREEN_ID_INVALID;
5315             if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
5316                 TLOGE(WmsLogTag::DMS, "Screen: %{public}" PRIu64" convert to rs id failed", mirrorScreenId);
5317             } else {
5318                 screen->SetMirrorScreenRegion(rsScreenId, mainScreenRegion);
5319                 screen->SetIsPhysicalMirrorSwitch(false);
5320                 TLOGI(WmsLogTag::DMS, "Screen: %{public}" PRIu64" mirror to %{public}"
5321                     PRIu64" with region, x:%{public}d y:%{public}d w:%{public}u h:%{public}u",
5322                     screenId, mirrorScreenId, mainScreenRegion.posX_, mainScreenRegion.posY_,
5323                     mainScreenRegion.width_, mainScreenRegion.height_);
5324             }
5325         }
5326     }
5327     group->combination_ = combination;
5328     AddScreenToGroup(group, addScreens, addChildPos, removeChildResMap);
5329 }
5330 
AddScreenToGroup(sptr<ScreenSessionGroup> group,const std::vector<ScreenId> & addScreens,const std::vector<Point> & addChildPos,std::map<ScreenId,bool> & removeChildResMap)5331 void ScreenSessionManager::AddScreenToGroup(sptr<ScreenSessionGroup> group,
5332     const std::vector<ScreenId>& addScreens, const std::vector<Point>& addChildPos,
5333     std::map<ScreenId, bool>& removeChildResMap)
5334 {
5335     std::vector<sptr<ScreenInfo>> addToGroup;
5336     std::vector<sptr<ScreenInfo>> removeFromGroup;
5337     std::vector<sptr<ScreenInfo>> changeGroup;
5338     for (uint64_t i = 0; i != addScreens.size(); i++) {
5339         ScreenId screenId = addScreens[i];
5340         sptr<ScreenSession> screen = GetScreenSession(screenId);
5341         if (screen == nullptr) {
5342             continue;
5343         }
5344         Point expandPoint = addChildPos[i];
5345         TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64", Point: %{public}d, %{public}d",
5346             screen->screenId_, expandPoint.posX_, expandPoint.posY_);
5347         bool addChildRes = group->AddChild(screen, expandPoint, GetScreenSession(group->mirrorScreenId_));
5348         if (removeChildResMap[screenId] && addChildRes) {
5349             changeGroup.emplace_back(screen->ConvertToScreenInfo());
5350             TLOGD(WmsLogTag::DMS, "changeGroup");
5351         } else if (removeChildResMap[screenId]) {
5352             TLOGD(WmsLogTag::DMS, "removeChild");
5353             removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
5354         } else if (addChildRes) {
5355             TLOGD(WmsLogTag::DMS, "AddChild");
5356             addToGroup.emplace_back(screen->ConvertToScreenInfo());
5357         } else {
5358             TLOGD(WmsLogTag::DMS, "default, AddChild failed");
5359         }
5360         NotifyDisplayCreate(screen->ConvertToDisplayInfo());
5361     }
5362 
5363     NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
5364     NotifyScreenGroupChanged(changeGroup, ScreenGroupChangeEvent::CHANGE_GROUP);
5365     NotifyScreenGroupChanged(addToGroup, ScreenGroupChangeEvent::ADD_TO_GROUP);
5366 }
5367 
RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)5368 void ScreenSessionManager::RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)
5369 {
5370     TLOGW(WmsLogTag::DMS, "enter!");
5371     if (!SessionPermission::IsSystemCalling()) {
5372         TLOGE(WmsLogTag::DMS, "permission denied calling: %{public}s, pid: %{public}d",
5373             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5374         return;
5375     }
5376     if (screens.empty()) {
5377         return;
5378     }
5379     std::vector<sptr<ScreenInfo>> removeFromGroup;
5380     for (ScreenId screenId : screens) {
5381         auto screen = GetScreenSession(screenId);
5382         if (screen == nullptr || screen->GetScreenProperty().GetScreenType() != ScreenType::VIRTUAL) {
5383             continue;
5384         }
5385         auto originGroup = GetAbstractScreenGroup(screen->groupSmsId_);
5386         if (originGroup == nullptr) {
5387             continue;
5388         }
5389         if (!originGroup->HasChild(screenId)) {
5390             continue;
5391         }
5392         RemoveFromGroupLocked(screen);
5393         removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
5394     }
5395     NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
5396 }
5397 
GetRSDisplayNodeByScreenId(ScreenId smsScreenId) const5398 const std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetRSDisplayNodeByScreenId(ScreenId smsScreenId) const
5399 {
5400     static std::shared_ptr<RSDisplayNode> notFound = nullptr;
5401     sptr<ScreenSession> screen = GetScreenSession(smsScreenId);
5402     if (screen == nullptr) {
5403         TLOGE(WmsLogTag::DMS, "screen == nullptr!");
5404         return notFound;
5405     }
5406     if (screen->GetDisplayNode() == nullptr) {
5407         TLOGE(WmsLogTag::DMS, "displayNode_ == nullptr!");
5408         return notFound;
5409     }
5410     TLOGI(WmsLogTag::DMS, "screen: %{public}" PRIu64", nodeId: %{public}" PRIu64" ",
5411         screen->screenId_, screen->GetDisplayNode()->GetId());
5412     return screen->GetDisplayNode();
5413 }
5414 
GetDisplayNodeByDisplayId(DisplayId displayId)5415 std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetDisplayNodeByDisplayId(DisplayId displayId)
5416 {
5417     std::shared_ptr<RSDisplayNode> displayNode = nullptr;
5418     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5419     for (auto sessionIt : screenSessionMap_) {
5420         auto screenSession = sessionIt.second;
5421         if (screenSession == nullptr) {
5422             TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
5423             continue;
5424         }
5425         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
5426         if (displayInfo == nullptr) {
5427             TLOGE(WmsLogTag::DMS, "displayInfo is nullptr!");
5428             continue;
5429         }
5430         if (displayId == displayInfo->GetDisplayId()) {
5431             if (sessionIt.first == SCREEN_ID_INVALID) {
5432                 TLOGE(WmsLogTag::DMS, "screenId is invalid!");
5433                 continue;
5434             }
5435             displayNode = screenSession->GetDisplayNode();
5436             break;
5437         }
5438     }
5439     return displayNode;
5440 }
5441 
IsFakeDisplayExist()5442 bool ScreenSessionManager::IsFakeDisplayExist()
5443 {
5444     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
5445         SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
5446         return true;
5447     }
5448     return false;
5449 }
5450 
GetScreenSnapshot(DisplayId displayId,bool isUseDma)5451 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetScreenSnapshot(DisplayId displayId, bool isUseDma)
5452 {
5453     DisplayId realDisplayId = displayId;
5454     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && displayId == DISPLAY_ID_FAKE) {
5455         if (!SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
5456             TLOGE(WmsLogTag::DMS, "fake display is not exist!");
5457             return nullptr;
5458         }
5459         realDisplayId = 0;
5460     }
5461     std::shared_ptr<RSDisplayNode> displayNode = GetDisplayNodeByDisplayId(realDisplayId);
5462     if (displayNode == nullptr) {
5463         TLOGE(WmsLogTag::DMS, "displayNode is null!");
5464         return nullptr;
5465     }
5466     std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
5467     RSSurfaceCaptureConfig config;
5468     config.useDma = isUseDma;
5469     TLOGW(WmsLogTag::DMS, "take surface capture with dma=%{public}d", isUseDma);
5470 #ifdef FOLD_ABILITY_ENABLE
5471     if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
5472         config.mainScreenRect = foldScreenController_->GetScreenSnapshotRect();
5473     }
5474     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
5475         SuperFoldPolicy::GetInstance().IsNeedSetSnapshotRect(displayId)) {
5476         config.mainScreenRect = SuperFoldPolicy::GetInstance().GetSnapshotRect(displayId);
5477     }
5478 #endif
5479     bool ret = rsInterface_.TakeSurfaceCapture(displayNode, callback, config);
5480     if (!ret) {
5481         TLOGE(WmsLogTag::DMS, "TakeSurfaceCapture failed");
5482         return nullptr;
5483     }
5484     std::shared_ptr<Media::PixelMap> screenshot = callback->GetResult(2000);  // wait for <= 2000ms
5485     if (screenshot == nullptr) {
5486         TLOGE(WmsLogTag::DMS, "Failed to get pixelmap from RS, return nullptr!");
5487     } else {
5488         TLOGD(WmsLogTag::DMS, "Sucess to get pixelmap from RS!");
5489     }
5490     // notify dm listener
5491     sptr<ScreenshotInfo> snapshotInfo = new ScreenshotInfo();
5492     snapshotInfo->SetTrigger(SysCapUtil::GetClientName());
5493     snapshotInfo->SetDisplayId(displayId);
5494     OnScreenshot(snapshotInfo);
5495     return screenshot;
5496 }
5497 
GetDisplaySnapshot(DisplayId displayId,DmErrorCode * errorCode,bool isUseDma)5498 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetDisplaySnapshot(DisplayId displayId,
5499     DmErrorCode* errorCode, bool isUseDma)
5500 {
5501     TLOGD(WmsLogTag::DMS, "enter!");
5502     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall() && errorCode) {
5503         *errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
5504         return nullptr;
5505     }
5506     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false) && errorCode) {
5507         TLOGI(WmsLogTag::DMS, "snapshot disabled by edm!");
5508         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
5509         return nullptr;
5510     }
5511     if (displayId == DISPLAY_ID_FAKE && !IsFakeDisplayExist() && errorCode) {
5512         *errorCode = DmErrorCode::DM_ERROR_INVALID_SCREEN;
5513         TLOGE(WmsLogTag::DMS, "fake display not exist!");
5514         return nullptr;
5515     }
5516     if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
5517         SessionPermission::IsShellCall()) {
5518         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplaySnapshot(%" PRIu64")", displayId);
5519         auto res = GetScreenSnapshot(displayId, isUseDma);
5520         if (res != nullptr) {
5521             NotifyScreenshot(displayId);
5522             if (SessionPermission::IsBetaVersion()) {
5523                 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
5524             }
5525         }
5526         isScreenShot_ = true;
5527         NotifyCaptureStatusChanged();
5528         return res;
5529     } else if (errorCode) {
5530         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
5531     }
5532     return nullptr;
5533 }
5534 
GetDisplaySnapshotWithOption(const CaptureOption & option,DmErrorCode * errorCode)5535 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetDisplaySnapshotWithOption(const CaptureOption& option,
5536     DmErrorCode* errorCode)
5537 {
5538     TLOGD(WmsLogTag::DMS, "enter!");
5539     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall() && errorCode) {
5540         *errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
5541         return nullptr;
5542     }
5543     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
5544         TLOGI(WmsLogTag::DMS, "snapshot was disabled by edm!");
5545         return nullptr;
5546     }
5547     if (option.displayId_ == DISPLAY_ID_FAKE && !IsFakeDisplayExist() && errorCode) {
5548         TLOGE(WmsLogTag::DMS, "fake display not exist!");
5549         *errorCode = DmErrorCode::DM_ERROR_INVALID_SCREEN;
5550         return nullptr;
5551     }
5552     if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
5553         SessionPermission::IsShellCall()) {
5554         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplaySnapshot(%" PRIu64")", option.displayId_);
5555         auto res = GetScreenSnapshot(option.displayId_, true);
5556         if (res != nullptr) {
5557             if (SessionPermission::IsBetaVersion()) {
5558                 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
5559             }
5560             TLOGI(WmsLogTag::DMS, "isNeedNotify_:%{public}d", option.isNeedNotify_);
5561             if (option.isNeedNotify_) {
5562                 isScreenShot_ = true;
5563                 NotifyScreenshot(option.displayId_);
5564                 NotifyCaptureStatusChanged();
5565             }
5566         }
5567         return res;
5568     } else if (errorCode) {
5569         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
5570     }
5571     return nullptr;
5572 }
5573 
GetSnapshotByPicker(Media::Rect & rect,DmErrorCode * errorCode)5574 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetSnapshotByPicker(Media::Rect &rect, DmErrorCode* errorCode)
5575 {
5576     TLOGD(WmsLogTag::DMS, "ENTER!");
5577     *errorCode = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
5578     std::lock_guard<std::mutex> lock(snapBypickerMutex_);
5579 
5580     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
5581         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
5582         TLOGI(WmsLogTag::DMS, "snapshot was disabled by edm!");
5583         return nullptr;
5584     }
5585     ScreenId screenId = SCREEN_ID_INVALID;
5586     // get snapshot area frome Screenshot extension
5587     if (!GetSnapshotArea(rect, errorCode, screenId)) {
5588         return nullptr;
5589     }
5590     auto screenSession = GetScreenSession(screenId);
5591     if (screenSession == nullptr) {
5592         TLOGE(WmsLogTag::DMS, "can not get screen session");
5593         return nullptr;
5594     }
5595     sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
5596     if (displayInfo == nullptr) {
5597         TLOGE(WmsLogTag::DMS, "can not get default display");
5598         return nullptr;
5599     }
5600     DisplayId displayId = displayInfo->GetDisplayId();
5601     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSnapshotByPicker(%" PRIu64")", displayId);
5602     auto pixelMap = GetScreenSnapshot(displayId, false);
5603     if (pixelMap != nullptr && SessionPermission::IsBetaVersion()) {
5604         CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
5605     }
5606     isScreenShot_ = true;
5607     NotifyCaptureStatusChanged();
5608     *errorCode = DmErrorCode::DM_OK;
5609     return pixelMap;
5610 }
5611 
GetSnapshotArea(Media::Rect & rect,DmErrorCode * errorCode,ScreenId & screenId)5612 bool ScreenSessionManager::GetSnapshotArea(Media::Rect &rect, DmErrorCode* errorCode, ScreenId &screenId)
5613 {
5614     ConfigureScreenSnapshotParams();
5615     if (ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerConnectExtension()) {
5616         int32_t ret = ScreenSnapshotPickerConnection::GetInstance().GetScreenSnapshotInfo(rect, screenId);
5617         if (ret != 0) {
5618             TLOGE(WmsLogTag::DMS, "GetScreenSnapshotInfo failed");
5619             ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerDisconnectExtension();
5620             if (ret == RES_FAILURE_FOR_PRIVACY_WINDOW) {
5621                 *errorCode = DmErrorCode::DM_ERROR_INVALID_CALLING;
5622             } else {
5623                 *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
5624             }
5625             return false;
5626         }
5627         ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerDisconnectExtension();
5628     } else {
5629         *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
5630         TLOGE(WmsLogTag::DMS, "SnapshotPickerConnectExtension failed");
5631         return false;
5632     }
5633     return true;
5634 }
5635 
OnRemoteDied(const sptr<IRemoteObject> & agent)5636 bool ScreenSessionManager::OnRemoteDied(const sptr<IRemoteObject>& agent)
5637 {
5638     if (agent == nullptr) {
5639         return false;
5640     }
5641     auto agentIter = screenAgentMap_.find(agent);
5642     if (agentIter != screenAgentMap_.end()) {
5643         while (screenAgentMap_[agent].size() > 0) {
5644             auto diedId = screenAgentMap_[agent][0];
5645             TLOGI(WmsLogTag::DMS, "destroy screenId in OnRemoteDied: %{public}" PRIu64"", diedId);
5646             DMError res = DestroyVirtualScreen(diedId);
5647             if (res != DMError::DM_OK) {
5648                 TLOGE(WmsLogTag::DMS, "destroy failed in OnRemoteDied: %{public}" PRIu64"", diedId);
5649             }
5650         }
5651         screenAgentMap_.erase(agent);
5652     }
5653     return true;
5654 }
5655 
GetAllValidScreenIds(const std::vector<ScreenId> & screenIds) const5656 std::vector<ScreenId> ScreenSessionManager::GetAllValidScreenIds(const std::vector<ScreenId>& screenIds) const
5657 {
5658     std::vector<ScreenId> validScreenIds;
5659     for (ScreenId screenId : screenIds) {
5660         auto screenIdIter = std::find(validScreenIds.begin(), validScreenIds.end(), screenId);
5661         if (screenIdIter != validScreenIds.end()) {
5662             continue;
5663         }
5664         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5665         auto iter = screenSessionMap_.find(screenId);
5666         if (iter != screenSessionMap_.end() && iter->second != nullptr &&
5667                 iter->second->GetScreenProperty().GetScreenType() != ScreenType::UNDEFINED) {
5668             validScreenIds.emplace_back(screenId);
5669         }
5670     }
5671     return validScreenIds;
5672 }
5673 
GetScreenGroupInfoById(ScreenId screenId)5674 sptr<ScreenGroupInfo> ScreenSessionManager::GetScreenGroupInfoById(ScreenId screenId)
5675 {
5676     if (!SessionPermission::IsSystemCalling()) {
5677         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5678             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5679         return nullptr;
5680     }
5681     auto screenSessionGroup = GetAbstractScreenGroup(screenId);
5682     if (screenSessionGroup == nullptr) {
5683         TLOGE(WmsLogTag::DMS, "cannot find screenGroupInfo: %{public}" PRIu64"", screenId);
5684         return nullptr;
5685     }
5686     return screenSessionGroup->ConvertToScreenGroupInfo();
5687 }
5688 
NotifyScreenConnected(sptr<ScreenInfo> screenInfo)5689 void ScreenSessionManager::NotifyScreenConnected(sptr<ScreenInfo> screenInfo)
5690 {
5691     if (screenInfo == nullptr) {
5692         TLOGE(WmsLogTag::DMS, "error, screenInfo is nullptr.");
5693         return;
5694     }
5695     auto task = [=] {
5696         TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64"", screenInfo->GetScreenId());
5697         OnScreenConnect(screenInfo);
5698     };
5699     taskScheduler_->PostAsyncTask(task, "NotifyScreenConnected");
5700 }
5701 
NotifyScreenDisconnected(ScreenId screenId)5702 void ScreenSessionManager::NotifyScreenDisconnected(ScreenId screenId)
5703 {
5704     auto task = [=] {
5705         TLOGNI(WmsLogTag::DMS, "notify screenId:%{public}" PRIu64"", screenId);
5706         OnScreenDisconnect(screenId);
5707     };
5708     taskScheduler_->PostAsyncTask(task, "NotifyScreenDisconnected");
5709 }
5710 
NotifyDisplayCreate(sptr<DisplayInfo> displayInfo)5711 void ScreenSessionManager::NotifyDisplayCreate(sptr<DisplayInfo> displayInfo)
5712 {
5713     if (displayInfo == nullptr) {
5714         return;
5715     }
5716     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
5717     TLOGI(WmsLogTag::DMS, "start, agent size: %{public}u", static_cast<uint32_t>(agents.size()));
5718     if (agents.empty()) {
5719         return;
5720     }
5721     for (auto& agent : agents) {
5722         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
5723         if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
5724             agent->OnDisplayCreate(displayInfo);
5725         }
5726     }
5727 }
5728 
NotifyDisplayDestroy(DisplayId displayId)5729 void ScreenSessionManager::NotifyDisplayDestroy(DisplayId displayId)
5730 {
5731     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
5732     TLOGI(WmsLogTag::DMS, "agent size: %{public}u", static_cast<uint32_t>(agents.size()));
5733     if (agents.empty()) {
5734         return;
5735     }
5736     for (auto& agent : agents) {
5737         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
5738         if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
5739             agent->OnDisplayDestroy(displayId);
5740         }
5741     }
5742 }
5743 
NotifyScreenGroupChanged(const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent event)5744 void ScreenSessionManager::NotifyScreenGroupChanged(
5745     const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent event)
5746 {
5747     if (screenInfo == nullptr) {
5748         TLOGE(WmsLogTag::DMS, "screenInfo is nullptr.");
5749         return;
5750     }
5751     std::string trigger = SysCapUtil::GetClientName();
5752     auto task = [=] {
5753         TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", trigger:[%{public}s]",
5754             screenInfo->GetScreenId(), trigger.c_str());
5755         OnScreenGroupChange(trigger, screenInfo, event);
5756     };
5757     taskScheduler_->PostAsyncTask(task, "NotifyScreenGroupChanged:PID");
5758 }
5759 
NotifyScreenGroupChanged(const std::vector<sptr<ScreenInfo>> & screenInfo,ScreenGroupChangeEvent event)5760 void ScreenSessionManager::NotifyScreenGroupChanged(
5761     const std::vector<sptr<ScreenInfo>>& screenInfo, ScreenGroupChangeEvent event)
5762 {
5763     if (screenInfo.empty()) {
5764         return;
5765     }
5766     std::string trigger = SysCapUtil::GetClientName();
5767     auto task = [=] {
5768         TLOGNI(WmsLogTag::DMS, "trigger:[%{public}s]", trigger.c_str());
5769         OnScreenGroupChange(trigger, screenInfo, event);
5770     };
5771     taskScheduler_->PostAsyncTask(task, "NotifyScreenGroupChanged");
5772 }
5773 
NotifyPrivateSessionStateChanged(bool hasPrivate)5774 void ScreenSessionManager::NotifyPrivateSessionStateChanged(bool hasPrivate)
5775 {
5776     if (hasPrivate == screenPrivacyStates) {
5777         TLOGD(WmsLogTag::DMS, "screen session state is not changed, return");
5778         return;
5779     }
5780     TLOGI(WmsLogTag::DMS, "PrivateSession status : %{public}u", hasPrivate);
5781     screenPrivacyStates = hasPrivate;
5782     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::PRIVATE_WINDOW_LISTENER);
5783     if (agents.empty()) {
5784         return;
5785     }
5786     for (auto& agent : agents) {
5787         agent->NotifyPrivateWindowStateChanged(hasPrivate);
5788     }
5789 }
5790 
SetScreenPrivacyState(bool hasPrivate)5791 void ScreenSessionManager::SetScreenPrivacyState(bool hasPrivate)
5792 {
5793     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5794         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5795             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5796         return;
5797     }
5798     TLOGI(WmsLogTag::DMS, "enter, hasPrivate: %{public}d", hasPrivate);
5799     ScreenId id = GetDefaultScreenId();
5800     auto screenSession = GetScreenSession(id);
5801     if (screenSession == nullptr) {
5802         TLOGE(WmsLogTag::DMS, "can not get default screen now");
5803         return;
5804     }
5805     screenSession->SetPrivateSessionForeground(hasPrivate);
5806     NotifyPrivateSessionStateChanged(hasPrivate);
5807 }
5808 
SetPrivacyStateByDisplayId(DisplayId id,bool hasPrivate)5809 void ScreenSessionManager::SetPrivacyStateByDisplayId(DisplayId id, bool hasPrivate)
5810 {
5811     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5812         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5813             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5814         return;
5815     }
5816     TLOGI(WmsLogTag::DMS, "enter, hasPrivate: %{public}d", hasPrivate);
5817     std::vector<ScreenId> screenIds = GetAllScreenIds();
5818     auto iter = std::find(screenIds.begin(), screenIds.end(), id);
5819     if (iter == screenIds.end()) {
5820         TLOGE(WmsLogTag::DMS, "invalid displayId");
5821         return;
5822     }
5823     auto screenSession = GetScreenSession(id);
5824     if (screenSession == nullptr) {
5825         TLOGE(WmsLogTag::DMS, "can not get id: %{public}" PRIu64" screen now", id);
5826         return;
5827     }
5828     screenSession->SetPrivateSessionForeground(hasPrivate);
5829     NotifyPrivateSessionStateChanged(hasPrivate);
5830 }
5831 
SetScreenPrivacyWindowList(DisplayId id,std::vector<std::string> privacyWindowList)5832 void ScreenSessionManager::SetScreenPrivacyWindowList(DisplayId id, std::vector<std::string> privacyWindowList)
5833 {
5834     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5835         TLOGE(WmsLogTag::DMS, "Permmission Denied! calling: %{public}s, pid: %{public}d",
5836             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5837         return;
5838     }
5839     TLOGW(WmsLogTag::DMS, "enter");
5840     std::vector<ScreenId> screenIds = GetAllScreenIds();
5841     auto iter = std::find(screenIds.begin(), screenIds.end(), id);
5842     if (iter == screenIds.end()) {
5843         TLOGE(WmsLogTag::DMS, "invalid displayId");
5844         return;
5845     }
5846     auto screenSession = GetScreenSession(id);
5847     if (screenSession == nullptr) {
5848         TLOGE(WmsLogTag::DMS, "can not get id: %{public}" PRIu64" screen now", id);
5849         return;
5850     }
5851     NotifyPrivateWindowListChanged(id, privacyWindowList);
5852 }
5853 
NotifyPrivateWindowListChanged(DisplayId id,std::vector<std::string> privacyWindowList)5854 void ScreenSessionManager::NotifyPrivateWindowListChanged(DisplayId id, std::vector<std::string> privacyWindowList)
5855 {
5856     TLOGI(WmsLogTag::DMS, "Notify displayid: %{public}" PRIu64"", id);
5857     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::PRIVATE_WINDOW_LIST_LISTENER);
5858     if (agents.empty()) {
5859         return;
5860     }
5861     for (auto& agent : agents) {
5862         agent->NotifyPrivateStateWindowListChanged(id, privacyWindowList);
5863     }
5864 }
5865 
HasPrivateWindow(DisplayId id,bool & hasPrivateWindow)5866 DMError ScreenSessionManager::HasPrivateWindow(DisplayId id, bool& hasPrivateWindow)
5867 {
5868     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5869         TLOGE(WmsLogTag::DMS, "Permmision Denied! calling: %{public}s, pid: %{public}d",
5870             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5871         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5872     }
5873     if (id == DISPLAY_ID_FAKE) {
5874         auto displayInfo = GetDefaultDisplayInfo();
5875         if (displayInfo) {
5876             id = displayInfo->GetDisplayId();
5877             TLOGI(WmsLogTag::DMS, "change displayId: %{public}" PRIu64" to displayId: %{public}" PRIu64,
5878                 DISPLAY_ID_FAKE, id);
5879         }
5880     }
5881     std::vector<ScreenId> screenIds = GetAllScreenIds();
5882     auto iter = std::find(screenIds.begin(), screenIds.end(), id);
5883     if (iter == screenIds.end()) {
5884         TLOGE(WmsLogTag::DMS, "invalid displayId");
5885         return DMError::DM_ERROR_INVALID_PARAM;
5886     }
5887     auto screenSession = GetScreenSession(id);
5888     if (screenSession == nullptr) {
5889         return DMError::DM_ERROR_NULLPTR;
5890     }
5891     hasPrivateWindow = screenSession->HasPrivateSessionForeground();
5892     TLOGI(WmsLogTag::DMS, "id: %{public}" PRIu64" has private window: %{public}u",
5893         id, static_cast<uint32_t>(hasPrivateWindow));
5894     return DMError::DM_OK;
5895 }
5896 
OnScreenGroupChange(const std::string & trigger,const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent groupEvent)5897 void ScreenSessionManager::OnScreenGroupChange(const std::string& trigger,
5898     const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent groupEvent)
5899 {
5900     if (screenInfo == nullptr) {
5901         return;
5902     }
5903     std::vector<sptr<ScreenInfo>> screenInfos;
5904     screenInfos.push_back(screenInfo);
5905     OnScreenGroupChange(trigger, screenInfos, groupEvent);
5906 }
5907 
OnScreenGroupChange(const std::string & trigger,const std::vector<sptr<ScreenInfo>> & screenInfos,ScreenGroupChangeEvent groupEvent)5908 void ScreenSessionManager::OnScreenGroupChange(const std::string& trigger,
5909     const std::vector<sptr<ScreenInfo>>& screenInfos, ScreenGroupChangeEvent groupEvent)
5910 {
5911     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
5912     std::vector<sptr<ScreenInfo>> infos;
5913     for (auto& screenInfo : screenInfos) {
5914         if (screenInfo != nullptr) {
5915             infos.emplace_back(screenInfo);
5916         }
5917     }
5918     if (agents.empty() || infos.empty()) {
5919         return;
5920     }
5921     for (auto& agent : agents) {
5922         agent->OnScreenGroupChange(trigger, infos, groupEvent);
5923     }
5924 }
5925 
OnScreenConnect(const sptr<ScreenInfo> screenInfo)5926 void ScreenSessionManager::OnScreenConnect(const sptr<ScreenInfo> screenInfo)
5927 {
5928     if (screenInfo == nullptr) {
5929         TLOGE(WmsLogTag::DMS, "screenInfo nullptr");
5930         return;
5931     }
5932     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
5933     if (agents.empty()) {
5934         TLOGI(WmsLogTag::DMS, "agents empty");
5935         return;
5936     }
5937     TLOGI(WmsLogTag::DMS, "start");
5938     for (auto& agent : agents) {
5939         agent->OnScreenConnect(screenInfo);
5940     }
5941     NotifyScreenModeChange();
5942 }
5943 
OnScreenDisconnect(ScreenId screenId)5944 void ScreenSessionManager::OnScreenDisconnect(ScreenId screenId)
5945 {
5946     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
5947     if (agents.empty()) {
5948         TLOGI(WmsLogTag::DMS, "agents empty");
5949         return;
5950     }
5951     TLOGI(WmsLogTag::DMS, "start");
5952     for (auto& agent : agents) {
5953         agent->OnScreenDisconnect(screenId);
5954     }
5955     NotifyScreenModeChange(screenId);
5956 }
5957 
OnScreenshot(sptr<ScreenshotInfo> info)5958 void ScreenSessionManager::OnScreenshot(sptr<ScreenshotInfo> info)
5959 {
5960     if (info == nullptr) {
5961         TLOGE(WmsLogTag::DMS, "info is null");
5962         return;
5963     }
5964     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREENSHOT_EVENT_LISTENER);
5965     if (agents.empty()) {
5966         TLOGD(WmsLogTag::DMS, "agents empty");
5967         return;
5968     }
5969     TLOGI(WmsLogTag::DMS, "start");
5970     for (auto& agent : agents) {
5971         agent->OnScreenshot(info);
5972     }
5973 }
5974 
GetCutoutInfo(DisplayId displayId)5975 sptr<CutoutInfo> ScreenSessionManager::GetCutoutInfo(DisplayId displayId)
5976 {
5977     DmsXcollie dmsXcollie("DMS:GetCutoutInfo", XCOLLIE_TIMEOUT_10S);
5978     return screenCutoutController_ ? screenCutoutController_->GetScreenCutoutInfo(displayId) : nullptr;
5979 }
5980 
HasImmersiveWindow(ScreenId screenId,bool & immersive)5981 DMError ScreenSessionManager::HasImmersiveWindow(ScreenId screenId, bool& immersive)
5982 {
5983     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5984         TLOGE(WmsLogTag::DMS, "permission denied!");
5985         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5986     }
5987     if (!clientProxy_) {
5988         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
5989         return DMError::DM_ERROR_NULLPTR;
5990     }
5991     clientProxy_->OnImmersiveStateChanged(screenId, immersive);
5992     return DMError::DM_OK;
5993 }
5994 
SetDisplayBoundary(const sptr<ScreenSession> screenSession)5995 void ScreenSessionManager::SetDisplayBoundary(const sptr<ScreenSession> screenSession)
5996 {
5997     if (screenSession && screenCutoutController_) {
5998         RectF rect =
5999             screenCutoutController_->CalculateCurvedCompression(screenSession->GetScreenProperty());
6000         if (!rect.IsEmpty()) {
6001             screenSession->SetDisplayBoundary(rect, screenCutoutController_->GetOffsetY());
6002         }
6003     } else {
6004         TLOGW(WmsLogTag::DMS, "screenSession or screenCutoutController_ is null");
6005     }
6006 }
6007 
TransferTypeToString(ScreenType type) const6008 std::string ScreenSessionManager::TransferTypeToString(ScreenType type) const
6009 {
6010     std::string screenType;
6011     switch (type) {
6012         case ScreenType::REAL:
6013             screenType = "REAL";
6014             break;
6015         case ScreenType::VIRTUAL:
6016             screenType = "VIRTUAL";
6017             break;
6018         default:
6019             screenType = "UNDEFINED";
6020             break;
6021     }
6022     return screenType;
6023 }
6024 
TransferPropertyChangeTypeToString(ScreenPropertyChangeType type) const6025 std::string ScreenSessionManager::TransferPropertyChangeTypeToString(ScreenPropertyChangeType type) const
6026 {
6027     std::string screenType;
6028     switch (type) {
6029         case ScreenPropertyChangeType::UNSPECIFIED:
6030             screenType = "UNSPECIFIED";
6031             break;
6032         case ScreenPropertyChangeType::ROTATION_BEGIN:
6033             screenType = "ROTATION_BEGIN";
6034             break;
6035         case ScreenPropertyChangeType::ROTATION_END:
6036             screenType = "ROTATION_END";
6037             break;
6038         case ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY:
6039             screenType = "ROTATION_UPDATE_PROPERTY_ONLY";
6040             break;
6041         case ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY:
6042             screenType = "ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY";
6043             break;
6044         default:
6045             screenType = "UNDEFINED";
6046             break;
6047     }
6048     return screenType;
6049 }
6050 
DumpAllScreensInfo(std::string & dumpInfo)6051 void ScreenSessionManager::DumpAllScreensInfo(std::string& dumpInfo)
6052 {
6053     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
6054         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
6055             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6056         return;
6057     }
6058     std::ostringstream oss;
6059     oss << "--------------------------------------Free Screen"
6060         << "--------------------------------------"
6061         << std::endl;
6062     oss << "ScreenName           Type     IsGroup DmsId RsId                 ActiveIdx VPR Rotation Orientation "
6063         << "RequestOrientation NodeId               "
6064         << std::endl;
6065     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6066     for (auto sessionIt : screenSessionMap_) {
6067         auto screenSession = sessionIt.second;
6068         if (screenSession == nullptr) {
6069             continue;
6070         }
6071         sptr<ScreenInfo> screenInfo = screenSession->ConvertToScreenInfo();
6072         if (screenInfo == nullptr) {
6073             continue;
6074         }
6075         std::string screenType = TransferTypeToString(screenInfo->GetType());
6076         NodeId nodeId = (screenSession->GetDisplayNode() == nullptr) ?
6077             SCREEN_ID_INVALID : screenSession->GetDisplayNode()->GetId();
6078         oss << std::left << std::setw(21) << screenInfo->GetName()  // 21 is width
6079             << std::left << std::setw(9) << screenType  // 9 is width
6080             << std::left << std::setw(8) << (screenSession->isScreenGroup_ ? "true" : "false")  // 8 is width
6081             << std::left << std::setw(6) << screenSession->screenId_  // 6 is width
6082             << std::left << std::setw(21) << screenSession->rsId_  // 21 is width
6083             << std::left << std::setw(10) << screenSession->activeIdx_  // 10 is width
6084             << std::left << std::setw(4) << screenInfo->GetVirtualPixelRatio()  // 4 is width
6085             << std::left << std::setw(9) << static_cast<uint32_t>(screenInfo->GetRotation())  // 9 is width
6086             << std::left << std::setw(12) << static_cast<uint32_t>(screenInfo->GetOrientation())  // 12 is width
6087             << std::left << std::setw(19)  // 19 is width
6088                 << static_cast<uint32_t>(screenSession->GetScreenRequestedOrientation())
6089             << std::left << std::setw(21) << nodeId  // 21 is width
6090             << std::endl;
6091     }
6092     oss << "total screen num: " << screenSessionMap_.size() << std::endl;
6093     dumpInfo.append(oss.str());
6094 }
6095 
DumpSpecialScreenInfo(ScreenId id,std::string & dumpInfo)6096 void ScreenSessionManager::DumpSpecialScreenInfo(ScreenId id, std::string& dumpInfo)
6097 {
6098     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
6099         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
6100             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6101         return;
6102     }
6103     std::ostringstream oss;
6104     sptr<ScreenSession> session = GetScreenSession(id);
6105     if (!session) {
6106         TLOGE(WmsLogTag::DMS, "Get screen session failed.");
6107         oss << "This screen id is invalid.";
6108         dumpInfo.append(oss.str());
6109         return;
6110     }
6111     sptr<ScreenInfo> screenInfo = GetScreenInfoById(id);
6112     if (screenInfo == nullptr) {
6113         return;
6114     }
6115     std::string screenType = TransferTypeToString(screenInfo->GetType());
6116     NodeId nodeId = (session->GetDisplayNode() == nullptr) ?
6117         SCREEN_ID_INVALID : session->GetDisplayNode()->GetId();
6118     oss << "ScreenName: " << screenInfo->GetName() << std::endl;
6119     oss << "Type: " << screenType << std::endl;
6120     oss << "IsGroup: " << (session->isScreenGroup_ ? "true" : "false") << std::endl;
6121     oss << "DmsId: " << id << std::endl;
6122     oss << "RsId: " << session->rsId_ << std::endl;
6123     oss << "ActiveIdx: " << session->activeIdx_ << std::endl;
6124     oss << "VPR: " << screenInfo->GetVirtualPixelRatio() << std::endl;
6125     oss << "Rotation: " << static_cast<uint32_t>(screenInfo->GetRotation()) << std::endl;
6126     oss << "Orientation: " << static_cast<uint32_t>(screenInfo->GetOrientation()) << std::endl;
6127     oss << "RequestOrientation: " << static_cast<uint32_t>(session->GetScreenRequestedOrientation()) << std::endl;
6128     oss << "NodeId: " << nodeId << std::endl;
6129     dumpInfo.append(oss.str());
6130 }
6131 
6132 // --- Fold Screen ---
GetPhyScreenProperty(ScreenId screenId)6133 ScreenProperty ScreenSessionManager::GetPhyScreenProperty(ScreenId screenId)
6134 {
6135     std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
6136     ScreenProperty property;
6137     auto iter = phyScreenPropMap_.find(screenId);
6138     if (iter == phyScreenPropMap_.end()) {
6139         TLOGI(WmsLogTag::DMS, "Error found physic screen config with id: %{public}" PRIu64, screenId);
6140         return property;
6141     }
6142     return iter->second;
6143 }
6144 
UpdateCameraBackSelfie(bool isCameraBackSelfie)6145 void ScreenSessionManager::UpdateCameraBackSelfie(bool isCameraBackSelfie)
6146 {
6147     if (isCameraBackSelfie_ == isCameraBackSelfie) {
6148         return;
6149     }
6150     isCameraBackSelfie_ = isCameraBackSelfie;
6151 
6152     auto screenSession = GetDefaultScreenSession();
6153     if (!screenSession) {
6154         TLOGW(WmsLogTag::DMS, "screenSession is null, notify camera back selfie failed");
6155         return;
6156     }
6157     screenSession->HandleCameraBackSelfieChange(isCameraBackSelfie);
6158 
6159     if (isCameraBackSelfie) {
6160         TLOGI(WmsLogTag::DMS, "isBackSelfie, SetScreenCorrection MAIN to 270");
6161         rsInterface_.SetScreenCorrection(SCREEN_ID_MAIN, static_cast<ScreenRotation>(ROTATION_270));
6162     } else {
6163         TLOGI(WmsLogTag::DMS, "exit BackSelfie, SetScreenCorrection MAIN to 90");
6164         SetScreenCorrection();
6165     }
6166 }
6167 
SetFoldDisplayMode(const FoldDisplayMode displayMode)6168 void ScreenSessionManager::SetFoldDisplayMode(const FoldDisplayMode displayMode)
6169 {
6170     SetFoldDisplayModeInner(displayMode);
6171 }
6172 
SetFoldDisplayModeInner(const FoldDisplayMode displayMode,std::string reason)6173 DMError ScreenSessionManager::SetFoldDisplayModeInner(const FoldDisplayMode displayMode, std::string reason)
6174 {
6175 #ifdef FOLD_ABILITY_ENABLE
6176     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6177         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d, reason: %{public}s",
6178             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid(), reason.c_str());
6179         return DMError::DM_ERROR_NOT_SYSTEM_APP;
6180     }
6181     if (!g_foldScreenFlag) {
6182         return DMError::DM_ERROR_INVALID_MODE_ID;
6183     }
6184     if (foldScreenController_ == nullptr) {
6185         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6186         return DMError::DM_ERROR_INVALID_MODE_ID;
6187     }
6188     if (!SessionPermission::IsSystemCalling()) {
6189         TLOGE(WmsLogTag::DMS, "permission denied!");
6190         return DMError::DM_ERROR_NOT_SYSTEM_APP;
6191     }
6192     TLOGI(WmsLogTag::DMS, "calling clientName: %{public}s, calling pid: %{public}d, setmode: %{public}d",
6193         SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid(), displayMode);
6194     if (foldScreenController_->GetTentMode() &&
6195         (displayMode == FoldDisplayMode::FULL || displayMode == FoldDisplayMode::COORDINATION)) {
6196         TLOGW(WmsLogTag::DMS, "in TentMode, SetFoldDisplayMode to %{public}d failed", displayMode);
6197         return DMError::DM_ERROR_INVALID_MODE_ID;
6198     } else if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() &&
6199         IsScreenCasting() && displayMode == FoldDisplayMode::COORDINATION) {
6200         TLOGW(WmsLogTag::DMS, "is phone casting, SetFoldDisplayMode to %{public}d is not allowed", displayMode);
6201         return DMError::DM_ERROR_INVALID_MODE_ID;
6202     }
6203     if (reason.compare("backSelfie") == 0) {
6204         UpdateCameraBackSelfie(true);
6205     }
6206     foldScreenController_->SetDisplayMode(displayMode);
6207     NotifyClientProxyUpdateFoldDisplayMode(displayMode);
6208 #endif
6209     return DMError::DM_OK;
6210 }
6211 
SetFoldDisplayModeFromJs(const FoldDisplayMode displayMode,std::string reason)6212 DMError ScreenSessionManager::SetFoldDisplayModeFromJs(const FoldDisplayMode displayMode, std::string reason)
6213 {
6214     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6215         TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
6216             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6217         return DMError::DM_ERROR_NOT_SYSTEM_APP;
6218     }
6219     return SetFoldDisplayModeInner(displayMode, reason);
6220 }
6221 
UpdateDisplayScaleState(ScreenId screenId)6222 void ScreenSessionManager::UpdateDisplayScaleState(ScreenId screenId)
6223 {
6224     auto session = GetScreenSession(screenId);
6225     if (session == nullptr) {
6226         TLOGE(WmsLogTag::DMS, "session is null");
6227         return;
6228     }
6229     const ScreenProperty& property = session->GetScreenProperty();
6230     if (std::fabs(property.GetScaleX() - DEFAULT_SCALE) < FLT_EPSILON &&
6231         std::fabs(property.GetScaleY() - DEFAULT_SCALE) < FLT_EPSILON &&
6232         std::fabs(property.GetPivotX() - DEFAULT_PIVOT) < FLT_EPSILON &&
6233         std::fabs(property.GetPivotY() - DEFAULT_PIVOT) < FLT_EPSILON) {
6234         TLOGD(WmsLogTag::DMS, "The scale and pivot is default value now. There is no need to update");
6235         return;
6236     }
6237     SetDisplayScaleInner(screenId, property.GetScaleX(), property.GetScaleY(), property.GetPivotX(),
6238                          property.GetPivotY());
6239 }
6240 
SetDisplayScaleInner(ScreenId screenId,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY)6241 void ScreenSessionManager::SetDisplayScaleInner(ScreenId screenId, const float& scaleX, const float& scaleY,
6242                                                 const float& pivotX, const float& pivotY)
6243 {
6244     auto session = GetScreenSession(screenId);
6245     if (session == nullptr) {
6246         TLOGE(WmsLogTag::DMS, "session is null");
6247         return;
6248     }
6249     if (pivotX > 1.0f || pivotX < 0.0f || pivotY > 1.0f || pivotY < 0.0f) {
6250         TLOGE(WmsLogTag::DMS, "pivotX [%{public}f] and pivotY [%{public}f] should be in [0.0~1.0f]", pivotX, pivotY);
6251         return;
6252     }
6253     float translateX = 0.0f;
6254     float translateY = 0.0f;
6255     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
6256         CalcDisplayNodeTranslateOnPocketFoldRotation(session, scaleX, scaleY, pivotX, pivotY,
6257             translateX, translateY);
6258     } else if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
6259         if (FoldDisplayMode::MAIN == GetFoldDisplayMode()) {
6260             CalcDisplayNodeTranslateOnPocketFoldRotation(session, scaleX, scaleY, pivotX, pivotY,
6261                 translateX, translateY);
6262         } else {
6263             CalcDisplayNodeTranslateOnRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
6264         }
6265     } else if (ROTATE_POLICY == FOLDABLE_DEVICE && FoldDisplayMode::FULL == GetFoldDisplayMode()) {
6266         CalcDisplayNodeTranslateOnFoldableRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
6267     } else {
6268         CalcDisplayNodeTranslateOnRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
6269     }
6270     TLOGD(WmsLogTag::DMS,
6271           "screenId %{public}" PRIu64 ", scale [%{public}f, %{public}f], "
6272           "pivot [%{public}f, %{public}f], translate [%{public}f, %{public}f]",
6273           screenId, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
6274     session->SetScreenScale(scaleX, scaleY, pivotX, pivotY, translateX, translateY);
6275     NotifyDisplayStateChange(GetDefaultScreenId(), session->ConvertToDisplayInfo(), {},
6276                              DisplayStateChangeType::UPDATE_SCALE);
6277 }
6278 
CalcDisplayNodeTranslateOnFoldableRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)6279 void ScreenSessionManager::CalcDisplayNodeTranslateOnFoldableRotation(sptr<ScreenSession>& session, const float& scaleX,
6280                                                                       const float& scaleY, const float& pivotX,
6281                                                                       const float& pivotY, float& translateX,
6282                                                                       float& translateY)
6283 {
6284     if (session == nullptr) {
6285         TLOGE(WmsLogTag::DMS, "session is nullptr");
6286         return;
6287     }
6288     const ScreenProperty& screenProperty = session->GetScreenProperty();
6289     auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
6290     auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
6291     Rotation rotation = session->GetRotation();
6292     float rotatedPivotX = DEFAULT_PIVOT;
6293     float rotatedPivotY = DEFAULT_PIVOT;
6294     float width = 0.0f;
6295     float height = 0.0f;
6296     switch (rotation) {
6297         case Rotation::ROTATION_0:
6298             rotatedPivotX = pivotY;
6299             rotatedPivotY = 1.0f - pivotX;
6300             width = screenHeight;
6301             height = screenWidth;
6302             break;
6303         case Rotation::ROTATION_90:
6304             rotatedPivotX = 1.0f - pivotX;
6305             rotatedPivotY = 1.0f - pivotY;
6306             width = screenWidth;
6307             height = screenHeight;
6308             break;
6309         case Rotation::ROTATION_180:
6310             rotatedPivotX = 1.0f - pivotY;
6311             rotatedPivotY = pivotX;
6312             width = screenHeight;
6313             height = screenWidth;
6314             break;
6315         case Rotation::ROTATION_270:
6316             rotatedPivotX = pivotX;
6317             rotatedPivotY = pivotY;
6318             width = screenWidth;
6319             height = screenHeight;
6320             break;
6321         default:
6322             TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
6323             break;
6324     }
6325     translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
6326     translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
6327 }
6328 
CalcDisplayNodeTranslateOnPocketFoldRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)6329 void ScreenSessionManager::CalcDisplayNodeTranslateOnPocketFoldRotation(sptr<ScreenSession>& session,
6330                                                                         const float& scaleX, const float& scaleY,
6331                                                                         const float& pivotX, const float& pivotY,
6332                                                                         float& translateX, float& translateY)
6333 {
6334     if (session == nullptr) {
6335         TLOGE(WmsLogTag::DMS, "session is nullptr");
6336         return;
6337     }
6338     const ScreenProperty& screenProperty = session->GetScreenProperty();
6339     auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
6340     auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
6341     Rotation rotation = session->GetRotation();
6342     float rotatedPivotX = DEFAULT_PIVOT;
6343     float rotatedPivotY = DEFAULT_PIVOT;
6344     float width = 0.0f;
6345     float height = 0.0f;
6346     switch (rotation) {
6347         case Rotation::ROTATION_0:
6348             rotatedPivotX = 1.0f - pivotY;
6349             rotatedPivotY = pivotX;
6350             width = screenHeight;
6351             height = screenWidth;
6352             break;
6353         case Rotation::ROTATION_90:
6354             rotatedPivotX = pivotX;
6355             rotatedPivotY = pivotY;
6356             width = screenWidth;
6357             height = screenHeight;
6358             break;
6359         case Rotation::ROTATION_180:
6360             rotatedPivotX = pivotY;
6361             rotatedPivotY = 1.0f - pivotX;
6362             width = screenHeight;
6363             height = screenWidth;
6364             break;
6365         case Rotation::ROTATION_270:
6366             rotatedPivotX = 1.0f - pivotX;
6367             rotatedPivotY = 1.0f - pivotY;
6368             width = screenWidth;
6369             height = screenHeight;
6370             break;
6371         default:
6372             TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
6373             break;
6374     }
6375     translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
6376     translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
6377 }
6378 
CalcDisplayNodeTranslateOnRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)6379 void ScreenSessionManager::CalcDisplayNodeTranslateOnRotation(sptr<ScreenSession>& session, const float& scaleX,
6380                                                               const float& scaleY, const float& pivotX,
6381                                                               const float& pivotY, float& translateX, float& translateY)
6382 {
6383     if (session == nullptr) {
6384         TLOGE(WmsLogTag::DMS, "session is nullptr");
6385         return;
6386     }
6387     const ScreenProperty& screenProperty = session->GetScreenProperty();
6388     auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
6389     auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
6390     Rotation rotation = session->GetRotation();
6391     float rotatedPivotX = DEFAULT_PIVOT;
6392     float rotatedPivotY = DEFAULT_PIVOT;
6393     float width = 0.0f;
6394     float height = 0.0f;
6395     switch (rotation) {
6396         case Rotation::ROTATION_0:
6397             rotatedPivotX = pivotX;
6398             rotatedPivotY = pivotY;
6399             width = screenWidth;
6400             height = screenHeight;
6401             break;
6402         case Rotation::ROTATION_90:
6403             rotatedPivotX = pivotY;
6404             rotatedPivotY = 1.0f - pivotX;
6405             width = screenHeight;
6406             height = screenWidth;
6407             break;
6408         case Rotation::ROTATION_180:
6409             rotatedPivotX = 1.0f - pivotX;
6410             rotatedPivotY = 1.0f - pivotY;
6411             width = screenWidth;
6412             height = screenHeight;
6413             break;
6414         case Rotation::ROTATION_270:
6415             rotatedPivotX = 1.0f - pivotY;
6416             rotatedPivotY = pivotX;
6417             width = screenHeight;
6418             height = screenWidth;
6419             break;
6420         default:
6421             TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
6422             break;
6423     }
6424     translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
6425     translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
6426 }
6427 
SetDisplayScale(ScreenId screenId,float scaleX,float scaleY,float pivotX,float pivotY)6428 void ScreenSessionManager::SetDisplayScale(ScreenId screenId, float scaleX, float scaleY, float pivotX,
6429     float pivotY)
6430 {
6431     if (!SessionPermission::IsSACalling()) {
6432         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
6433             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6434         return;
6435     }
6436     SetDisplayScaleInner(screenId, scaleX, scaleY, pivotX, pivotY);
6437 }
6438 
SetFoldStatusLocked(bool locked)6439 void ScreenSessionManager::SetFoldStatusLocked(bool locked)
6440 {
6441 #ifdef FOLD_ABILITY_ENABLE
6442     if (!g_foldScreenFlag) {
6443         return;
6444     }
6445     if (foldScreenController_ == nullptr) {
6446         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6447         return;
6448     }
6449     if (!SessionPermission::IsSystemCalling()) {
6450         TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
6451             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6452         return;
6453     }
6454     foldScreenController_->LockDisplayStatus(locked);
6455 #endif
6456 }
6457 
SetFoldStatusLockedFromJs(bool locked)6458 DMError ScreenSessionManager::SetFoldStatusLockedFromJs(bool locked)
6459 {
6460     if (!SessionPermission::IsSystemCalling()) {
6461         TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
6462             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6463         return DMError::DM_ERROR_NOT_SYSTEM_APP;
6464     }
6465     SetFoldStatusLocked(locked);
6466     return DMError::DM_OK;
6467 }
6468 
GetFoldDisplayMode()6469 FoldDisplayMode ScreenSessionManager::GetFoldDisplayMode()
6470 {
6471 #ifdef FOLD_ABILITY_ENABLE
6472     DmsXcollie dmsXcollie("DMS:GetFoldDisplayMode", XCOLLIE_TIMEOUT_10S);
6473     if (!g_foldScreenFlag) {
6474         return FoldDisplayMode::UNKNOWN;
6475     }
6476     if (foldScreenController_ == nullptr) {
6477         TLOGD(WmsLogTag::DMS, "foldScreenController_ is null");
6478         return FoldDisplayMode::UNKNOWN;
6479     }
6480     return foldScreenController_->GetDisplayMode();
6481 #else
6482     return FoldDisplayMode::UNKNOWN;
6483 #endif
6484 }
6485 
IsFoldable()6486 bool ScreenSessionManager::IsFoldable()
6487 {
6488 #ifdef FOLD_ABILITY_ENABLE
6489     // Most applications do not adapt to Lem rotation and are temporarily treated as non fold device
6490     if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
6491         return false;
6492     }
6493 
6494     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
6495         return true;
6496     }
6497 
6498     if (!g_foldScreenFlag) {
6499         return false;
6500     }
6501     if (foldScreenController_ == nullptr) {
6502         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6503         return false;
6504     }
6505     return foldScreenController_->IsFoldable();
6506 #else
6507     return false;
6508 #endif
6509 }
6510 
IsCaptured()6511 bool ScreenSessionManager::IsCaptured()
6512 {
6513     if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none") {
6514         // 如果当前是PC拓展模式,非截屏,录屏,投屏,则返回false
6515         return isScreenShot_ || virtualScreenCount_ > 0 || (hdmiScreenCount_ > 0 && !IsExtendMode());
6516     } else {
6517         return isScreenShot_ || virtualScreenCount_ > 0 || hdmiScreenCount_ > 0;
6518     }
6519 }
6520 
IsMultiScreenCollaboration()6521 bool ScreenSessionManager::IsMultiScreenCollaboration()
6522 {
6523     return isMultiScreenCollaboration_;
6524 }
6525 
HasCastEngineOrPhyMirror(const std::vector<ScreenId> & screenIdsToExclude)6526 bool ScreenSessionManager::HasCastEngineOrPhyMirror(const std::vector<ScreenId>& screenIdsToExclude)
6527 {
6528     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6529     for (auto sessionItem : screenSessionMap_) {
6530         auto screenId = sessionItem.first;
6531         auto screenSession = sessionItem.second;
6532         if (screenSession == nullptr) {
6533             TLOGI(WmsLogTag::DMS, "screenSession is null");
6534             continue;
6535         }
6536         if (std::find(screenIdsToExclude.begin(), screenIdsToExclude.end(), screenId) != screenIdsToExclude.end()) {
6537             continue;
6538         }
6539         auto screenType = screenSession->GetScreenProperty().GetScreenType();
6540         if (screenType == ScreenType::VIRTUAL
6541             && screenSession->GetName() == "CastEngine") {
6542             return true;
6543         }
6544 
6545         if (IsDefaultMirrorMode(screenId) && screenType == ScreenType::REAL &&
6546             screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
6547             return true;
6548         }
6549     }
6550     return false;
6551 }
6552 
GetFoldStatus()6553 FoldStatus ScreenSessionManager::GetFoldStatus()
6554 {
6555 #ifdef FOLD_ABILITY_ENABLE
6556     DmsXcollie dmsXcollie("DMS:GetFoldStatus", XCOLLIE_TIMEOUT_10S);
6557     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
6558         SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
6559         return SuperFoldStateManager::GetInstance().MatchSuperFoldStatusToFoldStatus(status);
6560     }
6561     if (!g_foldScreenFlag) {
6562         return FoldStatus::UNKNOWN;
6563     }
6564     if (foldScreenController_ == nullptr) {
6565         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6566         return FoldStatus::UNKNOWN;
6567     }
6568     return foldScreenController_->GetFoldStatus();
6569 #else
6570     return FoldStatus::UNKNOWN;
6571 #endif
6572 }
6573 
GetSuperFoldStatus()6574 SuperFoldStatus ScreenSessionManager::GetSuperFoldStatus()
6575 {
6576 #ifdef FOLD_ABILITY_ENABLE
6577     DmsXcollie dmsXcollie("DMS:GetSuperFoldStatus", XCOLLIE_TIMEOUT_10S);
6578     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
6579         return SuperFoldStatus::UNKNOWN;
6580     }
6581     SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
6582     return status;
6583 #else
6584     return SuperFoldStatus::UNKNOWN;
6585 #endif
6586 }
6587 
SetLandscapeLockStatus(bool isLocked)6588 void ScreenSessionManager::SetLandscapeLockStatus(bool isLocked)
6589 {
6590 #ifdef FOLD_ABILITY_ENABLE
6591     if (isLocked) {
6592         SetIsExtendScreenConnected(true);
6593     } else {
6594         SetIsExtendScreenConnected(false);
6595         SuperFoldSensorManager::GetInstance().HandleScreenDisconnectChange();
6596     }
6597 #endif
6598 }
6599 
GetExtendScreenConnectStatus()6600 ExtendScreenConnectStatus ScreenSessionManager::GetExtendScreenConnectStatus()
6601 {
6602 #ifdef WM_MULTI_SCREEN_ENABLE
6603     DmsXcollie dmsXcollie("DMS:GetExtendScreenConnectStatus", XCOLLIE_TIMEOUT_10S);
6604     return extendScreenConnectStatus_.load();
6605 #else
6606     return ExtendScreenConnectStatus::UNKNOWN;
6607 #endif
6608 }
6609 
GetIsExtendScreenConnected()6610 bool ScreenSessionManager::GetIsExtendScreenConnected()
6611 {
6612     return isExtendScreenConnected_;
6613 }
6614 
SetIsExtendScreenConnected(bool isExtendScreenConnected)6615 void ScreenSessionManager::SetIsExtendScreenConnected(bool isExtendScreenConnected)
6616 {
6617     isExtendScreenConnected_ = isExtendScreenConnected;
6618 }
6619 
HandleExtendScreenConnect(ScreenId screenId)6620 void ScreenSessionManager::HandleExtendScreenConnect(ScreenId screenId)
6621 {
6622 #ifdef FOLD_ABILITY_ENABLE
6623     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
6624         TLOGI(WmsLogTag::DMS, "not super fold display device.");
6625         return;
6626     }
6627     SetIsExtendScreenConnected(true);
6628     SuperFoldSensorManager::GetInstance().HandleScreenConnectChange();
6629     OnExtendScreenConnectStatusChange(screenId, ExtendScreenConnectStatus::CONNECT);
6630     extendScreenConnectStatus_.store(ExtendScreenConnectStatus::CONNECT);
6631 #endif
6632 }
6633 
HandleExtendScreenDisconnect(ScreenId screenId)6634 void ScreenSessionManager::HandleExtendScreenDisconnect(ScreenId screenId)
6635 {
6636 #ifdef FOLD_ABILITY_ENABLE
6637     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
6638         TLOGI(WmsLogTag::DMS, "not super fold display device.");
6639         return;
6640     }
6641     SetIsExtendScreenConnected(false);
6642     SuperFoldSensorManager::GetInstance().HandleScreenDisconnectChange();
6643     OnExtendScreenConnectStatusChange(screenId, ExtendScreenConnectStatus::DISCONNECT);
6644     extendScreenConnectStatus_.store(ExtendScreenConnectStatus::DISCONNECT);
6645 #endif
6646 }
6647 
GetTentMode()6648 bool ScreenSessionManager::GetTentMode()
6649 {
6650 #ifdef FOLD_ABILITY_ENABLE
6651     if (!g_foldScreenFlag) {
6652         return false;
6653     }
6654     if (foldScreenController_ == nullptr) {
6655         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6656         return false;
6657     }
6658     return foldScreenController_->GetTentMode();
6659 #else
6660     return false;
6661 #endif
6662 }
6663 
GetCameraMode()6664 bool ScreenSessionManager::GetCameraMode()
6665 {
6666     if (!g_foldScreenFlag) {
6667         return false;
6668     }
6669     if (foldScreenController_ == nullptr) {
6670         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6671         return false;
6672     }
6673     return foldScreenController_->GetCameraMode();
6674 }
6675 
GetCurrentFoldCreaseRegion()6676 sptr<FoldCreaseRegion> ScreenSessionManager::GetCurrentFoldCreaseRegion()
6677 {
6678 #ifdef FOLD_ABILITY_ENABLE
6679     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
6680         return SuperFoldStateManager::GetInstance().GetCurrentFoldCreaseRegion();
6681     }
6682     if (!g_foldScreenFlag) {
6683         return nullptr;
6684     }
6685     if (foldScreenController_ == nullptr) {
6686         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6687         return nullptr;
6688     }
6689     return foldScreenController_->GetCurrentFoldCreaseRegion();
6690 #else
6691     return nullptr;
6692 #endif
6693 }
6694 
GetCurvedCompressionArea()6695 uint32_t ScreenSessionManager::GetCurvedCompressionArea()
6696 {
6697     return ScreenSceneConfig::GetCurvedCompressionAreaInLandscape();
6698 }
6699 
NotifyFoldStatusChanged(FoldStatus foldStatus)6700 void ScreenSessionManager::NotifyFoldStatusChanged(FoldStatus foldStatus)
6701 {
6702 #ifdef FOLD_ABILITY_ENABLE
6703     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
6704     if (screenSession != nullptr) {
6705         if (foldStatus == FoldStatus::FOLDED && !FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
6706             screenSession->SetDefaultDeviceRotationOffset(0);
6707         } else {
6708             screenSession->SetDefaultDeviceRotationOffset(defaultDeviceRotationOffset_);
6709         }
6710     }
6711     if (screenSession != nullptr && FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() &&
6712         foldStatus == FoldStatus::FOLDED) {
6713             // sub screen default rotation offset is 270
6714             screenSession->SetDefaultDeviceRotationOffset(270);
6715     }
6716     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER);
6717     TLOGI(WmsLogTag::DMS, "foldStatus:%{public}d, agent size: %{public}u",
6718         foldStatus, static_cast<uint32_t>(agents.size()));
6719     if (agents.empty()) {
6720         return;
6721     }
6722     for (auto& agent : agents) {
6723         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6724         if (!IsFreezed(agentPid, DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER)) {
6725             agent->NotifyFoldStatusChanged(foldStatus);
6726         }
6727     }
6728     if (lowTemp_ == LowTempMode::LOW_TEMP_ON) {
6729         ScreenSessionPublish::GetInstance().PublishSmartNotificationEvent(FAULT_DESCRIPTION, FAULT_SUGGESTION);
6730     }
6731 #endif
6732 }
6733 
SetLowTemp(LowTempMode lowTemp)6734 void ScreenSessionManager::SetLowTemp(LowTempMode lowTemp)
6735 {
6736     std::lock_guard<std::mutex> lock(lowTempMutex_);
6737     if (lowTemp == LowTempMode::LOW_TEMP_ON && lowTemp_ != lowTemp) {
6738         TLOGI(WmsLogTag::DMS, "device enter low temperature mode.");
6739         ScreenSessionPublish::GetInstance().PublishSmartNotificationEvent(FAULT_DESCRIPTION, FAULT_SUGGESTION);
6740     }
6741     if (lowTemp == LowTempMode::LOW_TEMP_OFF) {
6742         TLOGI(WmsLogTag::DMS, "device exit low temperature mode.");
6743     }
6744     lowTemp_ = lowTemp;
6745 }
6746 
NotifyFoldAngleChanged(std::vector<float> foldAngles)6747 void ScreenSessionManager::NotifyFoldAngleChanged(std::vector<float> foldAngles)
6748 {
6749     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER);
6750     if (agents.empty()) {
6751         TLOGI(WmsLogTag::DMS, "agents is empty");
6752         return;
6753     }
6754     {
6755         std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
6756         lastFoldAngles_ = foldAngles;
6757     }
6758     for (auto& agent : agents) {
6759         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6760         if (!IsFreezed(agentPid, DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER)) {
6761             agent->NotifyFoldAngleChanged(foldAngles);
6762         }
6763     }
6764 }
6765 
NotifyCaptureStatusChanged()6766 void ScreenSessionManager::NotifyCaptureStatusChanged()
6767 {
6768     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER);
6769     bool isCapture = IsCaptured();
6770     isScreenShot_ = false;
6771     if (agents.empty()) {
6772         return;
6773     }
6774     for (auto& agent : agents) {
6775         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6776         if (!IsFreezed(agentPid, DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER)) {
6777             agent->NotifyCaptureStatusChanged(isCapture);
6778         }
6779     }
6780 }
6781 
NotifyCaptureStatusChanged(bool isCapture)6782 void ScreenSessionManager::NotifyCaptureStatusChanged(bool isCapture)
6783 {
6784     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER);
6785     if (agents.empty()) {
6786         return;
6787     }
6788     for (auto& agent : agents) {
6789         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6790         if (!IsFreezed(agentPid, DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER)) {
6791             agent->NotifyCaptureStatusChanged(isCapture);
6792         }
6793     }
6794 }
6795 
NotifyDisplayChangeInfoChanged(const sptr<DisplayChangeInfo> & info)6796 void ScreenSessionManager::NotifyDisplayChangeInfoChanged(const sptr<DisplayChangeInfo>& info)
6797 {
6798     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER);
6799     if (agents.empty()) {
6800         return;
6801     }
6802     {
6803         std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
6804         lastDisplayChangeInfo_ = info;
6805     }
6806     for (auto& agent : agents) {
6807         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6808         if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER)) {
6809             agent->NotifyDisplayChangeInfoChanged(info);
6810         }
6811     }
6812 }
6813 
RefreshMirrorScreenRegion(ScreenId screenId)6814 void ScreenSessionManager::RefreshMirrorScreenRegion(ScreenId screenId)
6815 {
6816 #if defined(FOLD_ABILITY_ENABLE) && defined(WM_MULTI_SCREEN_ENABLE)
6817     auto screenSession = GetScreenSession(screenId);
6818     if (screenSession == nullptr) {
6819         TLOGE(WmsLogTag::DMS, "can not get screen session");
6820         return;
6821     }
6822     if (screenSession->GetName() == "CastEngine" || screenSession->GetName() == "Cooperation") {
6823         DMRect mainScreenRegion = {0, 0, 0, 0};
6824         foldScreenController_->SetMainScreenRegion(mainScreenRegion);
6825         ScreenId rsScreenId = SCREEN_ID_INVALID;
6826         if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
6827             TLOGE(WmsLogTag::DMS, "Screen: %{public}" PRIu64" convert to rs id failed", screenId);
6828         } else {
6829             screenSession->SetMirrorScreenRegion(rsScreenId, mainScreenRegion);
6830             screenSession->EnableMirrorScreenRegion();
6831         }
6832     }
6833 #endif
6834 }
6835 
NotifyDisplayModeChanged(FoldDisplayMode displayMode)6836 void ScreenSessionManager::NotifyDisplayModeChanged(FoldDisplayMode displayMode)
6837 {
6838     NotifyClientProxyUpdateFoldDisplayMode(displayMode);
6839     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER);
6840     TLOGI(WmsLogTag::DMS, "DisplayMode:%{public}d, agent size: %{public}u",
6841         displayMode, static_cast<uint32_t>(agents.size()));
6842     if (agents.empty()) {
6843         return;
6844     }
6845     for (auto& agent : agents) {
6846         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6847         if (!IsFreezed(agentPid,
6848             DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER)) {
6849             agent->NotifyDisplayModeChanged(displayMode);
6850         }
6851     }
6852 #ifdef FOLD_ABILITY_ENABLE
6853     if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
6854         auto screenIds = GetAllScreenIds();
6855         for (auto screenId : screenIds) {
6856             RefreshMirrorScreenRegion(screenId);
6857         }
6858     }
6859 #endif
6860 }
6861 
NotifyScreenMagneticStateChanged(bool isMagneticState)6862 void ScreenSessionManager::NotifyScreenMagneticStateChanged(bool isMagneticState)
6863 {
6864     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_MAGNETIC_STATE_CHANGED_LISTENER);
6865     TLOGI(WmsLogTag::DMS, "IsScreenMagneticState:%{public}u, agent size: %{public}u",
6866         static_cast<uint32_t>(isMagneticState), static_cast<uint32_t>(agents.size()));
6867     if (agents.empty()) {
6868         return;
6869     }
6870     for (auto& agent : agents) {
6871         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6872         if (!IsFreezed(agentPid,
6873             DisplayManagerAgentType::SCREEN_MAGNETIC_STATE_CHANGED_LISTENER)) {
6874             agent->NotifyScreenMagneticStateChanged(isMagneticState);
6875         }
6876     }
6877 }
6878 
SetDisplayNodeScreenId(ScreenId screenId,ScreenId displayNodeScreenId)6879 void ScreenSessionManager::SetDisplayNodeScreenId(ScreenId screenId, ScreenId displayNodeScreenId)
6880 {
6881     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " displayNodeScreenId: %{public}" PRIu64,
6882         screenId, displayNodeScreenId);
6883     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetDisplayNodeScreenId");
6884     if (!clientProxy_) {
6885         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
6886         return;
6887     }
6888     clientProxy_->SetDisplayNodeScreenId(screenId, displayNodeScreenId);
6889 #ifdef DEVICE_STATUS_ENABLE
6890     SetDragWindowScreenId(screenId, displayNodeScreenId);
6891 #endif // DEVICE_STATUS_ENABLE
6892     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SetMultiWindowScreenId");
6893     MMI::InputManager::GetInstance()->SetMultiWindowScreenId(screenId, displayNodeScreenId);
6894 }
6895 
6896 #ifdef DEVICE_STATUS_ENABLE
SetDragWindowScreenId(ScreenId screenId,ScreenId displayNodeScreenId)6897 void ScreenSessionManager::SetDragWindowScreenId(ScreenId screenId, ScreenId displayNodeScreenId)
6898 {
6899     auto interactionManager = Msdp::DeviceStatus::InteractionManager::GetInstance();
6900     if (interactionManager != nullptr) {
6901         interactionManager->SetDragWindowScreenId(screenId, displayNodeScreenId);
6902     }
6903 }
6904 #endif // DEVICE_STATUS_ENABLE
6905 
OnPropertyChange(const ScreenProperty & newProperty,ScreenPropertyChangeReason reason,ScreenId screenId)6906 void ScreenSessionManager::OnPropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason,
6907     ScreenId screenId)
6908 {
6909     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " reason: %{public}d", screenId, static_cast<int>(reason));
6910     if (!clientProxy_) {
6911         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
6912         if (foldScreenController_ != nullptr) {
6913             foldScreenController_->SetdisplayModeChangeStatus(false);
6914         }
6915         return;
6916     }
6917     clientProxy_->OnPropertyChanged(screenId, newProperty, reason);
6918 }
6919 
OnPowerStatusChange(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)6920 void ScreenSessionManager::OnPowerStatusChange(DisplayPowerEvent event, EventStatus status,
6921     PowerStateChangeReason reason)
6922 {
6923     TLOGI(WmsLogTag::DMS, "[UL_POWER]event: %{public}d, status: %{public}d, reason: %{public}d",
6924         static_cast<int>(event),
6925         static_cast<int>(status), static_cast<int>(reason));
6926     if (!clientProxy_) {
6927         TLOGI(WmsLogTag::DMS, "[UL_POWER] clientProxy_ is null");
6928         return;
6929     }
6930     clientProxy_->OnPowerStatusChanged(event, status, reason);
6931 }
6932 
OnSensorRotationChange(float sensorRotation,ScreenId screenId)6933 void ScreenSessionManager::OnSensorRotationChange(float sensorRotation, ScreenId screenId)
6934 {
6935     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " sensorRotation: %{public}f", screenId, sensorRotation);
6936     if (!clientProxy_) {
6937         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
6938         return;
6939     }
6940     clientProxy_->OnSensorRotationChanged(screenId, sensorRotation);
6941 }
6942 
OnHoverStatusChange(int32_t hoverStatus,bool needRotate,ScreenId screenId)6943 void ScreenSessionManager::OnHoverStatusChange(int32_t hoverStatus, bool needRotate, ScreenId screenId)
6944 {
6945     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " hoverStatus: %{public}d", screenId, hoverStatus);
6946     if (!clientProxy_) {
6947         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
6948         return;
6949     }
6950     clientProxy_->OnHoverStatusChanged(screenId, hoverStatus, needRotate);
6951 }
6952 
OnScreenOrientationChange(float screenOrientation,ScreenId screenId)6953 void ScreenSessionManager::OnScreenOrientationChange(float screenOrientation, ScreenId screenId)
6954 {
6955     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " screenOrientation: %{public}f", screenId, screenOrientation);
6956     if (!clientProxy_) {
6957         TLOGI(WmsLogTag::DMS, "ClientProxy_ is null");
6958         return;
6959     }
6960     clientProxy_->OnScreenOrientationChanged(screenId, screenOrientation);
6961 }
6962 
OnScreenRotationLockedChange(bool isLocked,ScreenId screenId)6963 void ScreenSessionManager::OnScreenRotationLockedChange(bool isLocked, ScreenId screenId)
6964 {
6965     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " isLocked: %{public}d", screenId, isLocked);
6966     if (!clientProxy_) {
6967         TLOGI(WmsLogTag::DMS, "ClientProxy_ is null");
6968         return;
6969     }
6970     clientProxy_->OnScreenRotationLockedChanged(screenId, isLocked);
6971 }
6972 
OnCameraBackSelfieChange(bool isCameraBackSelfie,ScreenId screenId)6973 void ScreenSessionManager::OnCameraBackSelfieChange(bool isCameraBackSelfie, ScreenId screenId)
6974 {
6975     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " isCameraBackSelfie: %{public}d", screenId, isCameraBackSelfie);
6976     if (!clientProxy_) {
6977         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
6978         return;
6979     }
6980     clientProxy_->OnCameraBackSelfieChanged(screenId, isCameraBackSelfie);
6981 }
6982 
NotifyClientProxyUpdateFoldDisplayMode(FoldDisplayMode displayMode)6983 void ScreenSessionManager::NotifyClientProxyUpdateFoldDisplayMode(FoldDisplayMode displayMode)
6984 {
6985     if (clientProxy_) {
6986         TLOGI(WmsLogTag::DMS, "displayMode = %{public}d",
6987             static_cast<int>(displayMode));
6988         clientProxy_->OnUpdateFoldDisplayMode(displayMode);
6989     }
6990 }
6991 
ScbClientDeathCallback(int32_t deathScbPid)6992 void ScreenSessionManager::ScbClientDeathCallback(int32_t deathScbPid)
6993 {
6994     std::unique_lock<std::mutex> lock(oldScbPidsMutex_);
6995     if (deathScbPid == currentScbPId_ || currentScbPId_ == INVALID_SCB_PID) {
6996         clientProxy_ = nullptr;
6997         TLOGE(WmsLogTag::DMS, "death callback and set clientProxy null");
6998     }
6999     if (scbSwitchCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_SCBSWITCH_MS))
7000         == std::cv_status::timeout) {
7001         TLOGE(WmsLogTag::DMS, "set client task deathScbPid:%{public}d, timeout: %{public}d",
7002             deathScbPid, CV_WAIT_SCBSWITCH_MS);
7003     }
7004     std::ostringstream oss;
7005     oss << "Scb client death: " << deathScbPid;
7006     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
7007     screenEventTracker_.RecordEvent(oss.str());
7008     oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), deathScbPid), oldScbPids_.end());
7009 }
7010 
AddScbClientDeathRecipient(const sptr<IScreenSessionManagerClient> & scbClient,int32_t scbPid)7011 void ScreenSessionManager::AddScbClientDeathRecipient(const sptr<IScreenSessionManagerClient>& scbClient,
7012     int32_t scbPid)
7013 {
7014     sptr<ScbClientListenerDeathRecipient> scbClientDeathListener =
7015         new (std::nothrow) ScbClientListenerDeathRecipient(scbPid);
7016     if (scbClientDeathListener == nullptr) {
7017         TLOGE(WmsLogTag::DMS, "add scb: %{public}d death listener failed", scbPid);
7018         return;
7019     }
7020     if (scbClient != nullptr && scbClient->AsObject() != nullptr) {
7021         TLOGI(WmsLogTag::DMS, "add scb: %{public}d death listener", scbPid);
7022         scbClient->AsObject()->AddDeathRecipient(scbClientDeathListener);
7023     }
7024 }
7025 
SwitchUser()7026 void ScreenSessionManager::SwitchUser()
7027 {
7028 #ifdef WM_MULTI_USR_ABILITY_ENABLE
7029     if (!SessionPermission::IsSystemCalling()) {
7030         TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
7031             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7032         return;
7033     }
7034     auto userId = GetUserIdByCallingUid();
7035     auto newScbPid = IPCSkeleton::GetCallingPid();
7036     currentUserIdForSettings_ = userId;
7037     SwitchScbNodeHandle(userId, newScbPid, false);
7038     MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, GetDefaultScreenId(), false);
7039 #endif
7040 }
7041 
ScbStatusRecoveryWhenSwitchUser(std::vector<int32_t> oldScbPids,int32_t newScbPid)7042 void ScreenSessionManager::ScbStatusRecoveryWhenSwitchUser(std::vector<int32_t> oldScbPids, int32_t newScbPid)
7043 {
7044 #ifdef WM_MULTI_USR_ABILITY_ENABLE
7045     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
7046     if (screenSession == nullptr) {
7047         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
7048         return;
7049     }
7050     if (g_foldScreenFlag) {
7051         NotifyFoldStatusChanged(GetFoldStatus());
7052         NotifyDisplayModeChanged(GetFoldDisplayMode());
7053     }
7054     int64_t delayTime = 0;
7055     if (g_foldScreenFlag && oldScbDisplayMode_ != GetFoldDisplayMode() &&
7056         !FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
7057         delayTime = SWITCH_USER_DISPLAYMODE_CHANGE_DELAY;
7058         auto foldStatus = GetFoldStatus();
7059         TLOGE(WmsLogTag::DMS, "old mode: %{public}u, cur mode: %{public}u", oldScbDisplayMode_, GetFoldDisplayMode());
7060         if (foldStatus == FoldStatus::EXPAND || foldStatus == FoldStatus::HALF_FOLD ||
7061             FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7062             if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7063                 screenSession->UpdatePropertyByFoldControl(screenSession->GetScreenProperty());
7064             } else {
7065                 screenSession->UpdatePropertyByFoldControl(GetPhyScreenProperty(SCREEN_ID_FULL));
7066             }
7067             screenSession->PropertyChange(screenSession->GetScreenProperty(),
7068                 ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
7069         } else if (foldStatus == FoldStatus::FOLDED) {
7070             screenSession->UpdatePropertyByFoldControl(GetPhyScreenProperty(SCREEN_ID_MAIN));
7071             screenSession->PropertyChange(screenSession->GetScreenProperty(),
7072                 ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING);
7073         } else {
7074             TLOGE(WmsLogTag::DMS, "unsupport foldStatus: %{public}u", foldStatus);
7075         }
7076     } else {
7077         screenSession->UpdateValidRotationToScb();
7078     }
7079     auto task = [=] {
7080         if (!clientProxy_) {
7081             TLOGE(WmsLogTag::DMS, "ScbStatusRecoveryWhenSwitchUser clientProxy_ is null");
7082             return;
7083         }
7084         clientProxy_->SwitchUserCallback(oldScbPids, newScbPid);
7085         RecoverMultiScreenModeWhenSwitchUser();
7086     };
7087     taskScheduler_->PostAsyncTask(task, "clientProxy_ SwitchUserCallback task", delayTime);
7088 #endif
7089 }
7090 
RecoverMultiScreenModeWhenSwitchUser()7091 void ScreenSessionManager::RecoverMultiScreenModeWhenSwitchUser()
7092 {
7093     std::map<std::string, MultiScreenInfo> multiScreenInfoMap = ScreenSettingHelper::GetMultiScreenInfo();
7094     if (multiScreenInfoMap.empty()) {
7095         TLOGE(WmsLogTag::DMS, "no restored screen, use default mode!");
7096         return;
7097     }
7098     {
7099         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
7100         for (auto sessionIt : screenSessionMap_) {
7101             auto screenSession = sessionIt.second;
7102             if (screenSession == nullptr) {
7103                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
7104                 continue;
7105             }
7106             if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
7107                 screenSession->GetIsExtend()) {
7108                 TLOGI(WmsLogTag::DMS, "recover extend screen, screenId = %{public}" PRIu64"",
7109                 sessionIt.first);
7110                 RecoverMultiScreenMode(screenSession);
7111             }
7112         }
7113     }
7114 }
7115 
SetClient(const sptr<IScreenSessionManagerClient> & client)7116 void ScreenSessionManager::SetClient(const sptr<IScreenSessionManagerClient>& client)
7117 {
7118     if (!SessionPermission::IsSystemCalling()) {
7119         TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
7120             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7121         return;
7122     }
7123     if (!client) {
7124         TLOGE(WmsLogTag::DMS, "SetClient client is null");
7125         return;
7126     }
7127     clientProxy_ = client;
7128     auto userId = GetUserIdByCallingUid();
7129     auto newScbPid = IPCSkeleton::GetCallingPid();
7130 
7131     std::ostringstream oss;
7132     oss << "set client userId: " << userId
7133         << " clientName: " << SysCapUtil::GetClientName();
7134     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
7135     screenEventTracker_.RecordEvent(oss.str());
7136     currentUserIdForSettings_ = userId;
7137     MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, GetDefaultScreenId(), true);
7138     NotifyClientProxyUpdateFoldDisplayMode(GetFoldDisplayMode());
7139     SetClientInner();
7140     SwitchScbNodeHandle(userId, newScbPid, true);
7141     AddScbClientDeathRecipient(client, newScbPid);
7142 }
7143 
SwitchScbNodeHandle(int32_t newUserId,int32_t newScbPid,bool coldBoot)7144 void ScreenSessionManager::SwitchScbNodeHandle(int32_t newUserId, int32_t newScbPid, bool coldBoot)
7145 {
7146 #ifdef WM_MULTI_USR_ABILITY_ENABLE
7147     std::ostringstream oss;
7148     oss << "currentUserId: " << currentUserId_
7149         << "  currentScbPId: " << currentScbPId_
7150         << "  newUserId: " << newUserId
7151         << "  newScbPid: " << newScbPid
7152         << "  coldBoot: " << static_cast<int32_t>(coldBoot);
7153     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
7154     screenEventTracker_.RecordEvent(oss.str());
7155 
7156     std::unique_lock<std::mutex> lock(oldScbPidsMutex_);
7157     if (currentScbPId_ != INVALID_SCB_PID) {
7158         auto pidIter = std::find(oldScbPids_.begin(), oldScbPids_.end(), currentScbPId_);
7159         if (pidIter == oldScbPids_.end() && currentScbPId_ > 0) {
7160             oldScbPids_.emplace_back(currentScbPId_);
7161         }
7162         oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), newScbPid), oldScbPids_.end());
7163         if (oldScbPids_.size() == 0) {
7164             TLOGE(WmsLogTag::DMS, "swicth user failed, oldScbPids is null");
7165             screenEventTracker_.RecordEvent("swicth user failed, oldScbPids is null");
7166         }
7167     }
7168     if (!clientProxy_) {
7169         TLOGE(WmsLogTag::DMS, "clientProxy is null");
7170         return;
7171     }
7172     if (coldBoot) {
7173         clientProxy_->SwitchUserCallback(oldScbPids_, newScbPid);
7174         clientProxyMap_[newUserId] = clientProxy_;
7175     } else {
7176         HotSwitch(newUserId, newScbPid);
7177     }
7178     UpdateDisplayScaleState(GetDefaultScreenId());
7179     currentUserId_ = newUserId;
7180     currentScbPId_ = newScbPid;
7181     scbSwitchCV_.notify_all();
7182     oldScbDisplayMode_ = GetFoldDisplayMode();
7183 #endif
7184 }
7185 
NotifyCastWhenSwitchScbNode()7186 void ScreenSessionManager::NotifyCastWhenSwitchScbNode()
7187 {
7188     std::map<ScreenId, sptr<ScreenSession>> screenSessionMapCopy;
7189     {
7190         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
7191         screenSessionMapCopy = screenSessionMap_;
7192     }
7193     for (const auto& sessionIt : screenSessionMapCopy) {
7194         auto screenSession = sessionIt.second;
7195         if (screenSession == nullptr) {
7196             TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first);
7197             continue;
7198         }
7199         if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL ||
7200             !IsDefaultMirrorMode(screenSession->GetScreenId())) {
7201             TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"", sessionIt.first);
7202             continue;
7203         }
7204         bool isScreenMirror = screenSession ->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR;
7205         NotifyCastWhenScreenConnectChange(isScreenMirror);
7206         return;
7207     }
7208 }
7209 
HotSwitch(int32_t newUserId,int32_t newScbPid)7210 void ScreenSessionManager::HotSwitch(int32_t newUserId, int32_t newScbPid)
7211 {
7212     // hot switch
7213     if (clientProxyMap_.count(newUserId) == 0) {
7214         TLOGE(WmsLogTag::DMS, "not found client proxy. userId:%{public}d.", newUserId);
7215         return;
7216     }
7217     if (newUserId == currentUserId_) {
7218         TLOGI(WmsLogTag::DMS, "switch user not change");
7219         return;
7220     }
7221     if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
7222         // Delete the screen whose ID is 5 generated by Coordination before switching the private space.
7223         SessionOption option = {
7224             .screenId_ = SCREEN_ID_MAIN,
7225         };
7226         clientProxy_->OnScreenConnectionChanged(option, ScreenEvent::DISCONNECTED);
7227     }
7228     clientProxy_ = clientProxyMap_[newUserId];
7229     ScbStatusRecoveryWhenSwitchUser(oldScbPids_, newScbPid);
7230 }
7231 
GetCurrentUserId()7232 int32_t ScreenSessionManager::GetCurrentUserId()
7233 {
7234     return currentUserIdForSettings_;
7235 }
7236 
SetClientInner()7237 void ScreenSessionManager::SetClientInner()
7238 {
7239     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
7240     for (const auto& iter : screenSessionMap_) {
7241         if (!iter.second) {
7242             continue;
7243         }
7244         // In the rotating state, after scb restarts, the screen information needs to be reset.
7245         float phyWidth = 0.0f;
7246         float phyHeight = 0.0f;
7247         bool isReset = true;
7248         GetCurrentScreenPhyBounds(phyWidth, phyHeight, isReset, iter.first);
7249         auto localRotation = iter.second->GetRotation();
7250         TLOGI(WmsLogTag::DMS, "phyWidth = :%{public}f, phyHeight = :%{public}f, localRotation = :%{public}u",
7251             phyWidth, phyHeight, localRotation);
7252         bool isModeChanged = localRotation != Rotation::ROTATION_0;
7253         if (isModeChanged && isReset) {
7254             TLOGI(WmsLogTag::DMS, "screen(id:%{public}" PRIu64 ") current is not default mode, reset it", iter.first);
7255             SetRotation(iter.first, Rotation::ROTATION_0, false);
7256             SetPhysicalRotationClientInner(iter.first, 0);
7257             iter.second->SetDisplayBoundary(RectF(0, 0, phyWidth, phyHeight), 0);
7258         }
7259         if (!clientProxy_) {
7260             TLOGE(WmsLogTag::DMS, "clientProxy is null");
7261             return;
7262         }
7263         if (iter.second->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
7264             TLOGI(WmsLogTag::DMS, "current screen is extend and mirror, return before OnScreenConnectionChanged");
7265             RecoverMultiScreenMode(iter.second);
7266             continue;
7267         }
7268         if (g_isPcDevice && g_outerOnly == ONLY_OUTER_SCREEN_VALUE && !iter.second->GetIsExtend()) {
7269             defaultScreenId_ = iter.first;
7270         }
7271         if (!g_isPcDevice) {
7272             clientProxy_->OnScreenConnectionChanged(GetSessionOption(iter.second, iter.first),
7273                 ScreenEvent::CONNECTED);
7274         } else {
7275             TLOGI(WmsLogTag::DMS, "recover screen, id: %{public}" PRIu64, iter.first);
7276             RecoverMultiScreenMode(iter.second);
7277         }
7278     }
7279 }
7280 
SetPhysicalRotationClientInner(ScreenId screenId,int rotation)7281 void ScreenSessionManager::SetPhysicalRotationClientInner(ScreenId screenId, int rotation)
7282 {
7283     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
7284     if (screenSession == nullptr) {
7285         TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"",
7286             screenId);
7287         return;
7288     }
7289     screenSession->SetPhysicalRotation(rotation);
7290     screenSession->SetScreenComponentRotation(rotation);
7291     TLOGI(WmsLogTag::DMS, "SetPhysicalRotationClientInner end");
7292 }
7293 
RecoverMultiScreenMode(sptr<ScreenSession> screenSession)7294 void ScreenSessionManager::RecoverMultiScreenMode(sptr<ScreenSession> screenSession)
7295 {
7296     ScreenId screenId = screenSession->GetScreenId();
7297     if (screenSession == nullptr) {
7298         TLOGE(WmsLogTag::DMS, "screenSession is null!");
7299         return;
7300     }
7301     SetExtendedScreenFallbackPlan(screenId);
7302     if (!RecoverRestoredMultiScreenMode(screenSession)) {
7303         clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), ScreenEvent::CONNECTED);
7304         SetMultiScreenDefaultRelativePosition();
7305         if (screenSession->GetScreenCombination() != ScreenCombination::SCREEN_MAIN) {
7306             ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_EXTEND);
7307         }
7308     }
7309     if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
7310         screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::UNDEFINED);
7311     }
7312 }
7313 
GetCurrentScreenPhyBounds(float & phyWidth,float & phyHeight,bool & isReset,const ScreenId & screenid)7314 void ScreenSessionManager::GetCurrentScreenPhyBounds(float& phyWidth, float& phyHeight,
7315                                                      bool& isReset, const ScreenId& screenid)
7316 {
7317 #ifdef FOLD_ABILITY_ENABLE
7318     if (foldScreenController_ != nullptr) {
7319         FoldDisplayMode displayMode = GetFoldDisplayMode();
7320         TLOGI(WmsLogTag::DMS, "fold screen with displayMode = %{public}u", displayMode);
7321         if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
7322             auto phyBounds = GetPhyScreenProperty(screenid).GetPhyBounds();
7323             phyWidth = phyBounds.rect_.width_;
7324             phyHeight = phyBounds.rect_.height_;
7325             if (displayMode == FoldDisplayMode::UNKNOWN) {
7326                 isReset = false;
7327             }
7328             return;
7329         }
7330         if (displayMode == FoldDisplayMode::MAIN) {
7331             auto phyBounds = GetPhyScreenProperty(SCREEN_ID_MAIN).GetPhyBounds();
7332             phyWidth = phyBounds.rect_.width_;
7333             phyHeight = phyBounds.rect_.height_;
7334         } else if (displayMode == FoldDisplayMode::FULL) {
7335             auto phyBounds = GetPhyScreenProperty(SCREEN_ID_FULL).GetPhyBounds();
7336             phyWidth = phyBounds.rect_.width_;
7337             phyHeight = phyBounds.rect_.height_;
7338             if (SCREEN_ROTATION_OFFSET == ROTATION_90 || SCREEN_ROTATION_OFFSET == ROTATION_270) {
7339                 std::swap(phyWidth, phyHeight);
7340             }
7341         } else {
7342             isReset = false;
7343         }
7344         return;
7345     }
7346 #endif
7347     int id = HiviewDFX::XCollie::GetInstance().SetTimer("GetCurrentScreenPhyBounds", XCOLLIE_TIMEOUT_10S, nullptr,
7348         nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
7349     auto remoteScreenMode = rsInterface_.GetScreenActiveMode(screenid);
7350     HiviewDFX::XCollie::GetInstance().CancelTimer(id);
7351     phyWidth = remoteScreenMode.GetScreenWidth();
7352     phyHeight = remoteScreenMode.GetScreenHeight();
7353 }
7354 
GetScreenProperty(ScreenId screenId)7355 ScreenProperty ScreenSessionManager::GetScreenProperty(ScreenId screenId)
7356 {
7357     DmsXcollie dmsXcollie("DMS:GetScreenProperty", XCOLLIE_TIMEOUT_10S);
7358     auto screenSession = GetScreenSession(screenId);
7359     if (!screenSession) {
7360         TLOGI(WmsLogTag::DMS, "screenSession is null");
7361         return {};
7362     }
7363     return screenSession->GetScreenProperty();
7364 }
7365 
GetDisplayNode(ScreenId screenId)7366 std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetDisplayNode(ScreenId screenId)
7367 {
7368     DmsXcollie dmsXcollie("DMS:GetDisplayNode", XCOLLIE_TIMEOUT_10S);
7369     auto screenSession = GetScreenSession(screenId);
7370     if (!screenSession) {
7371         TLOGE(WmsLogTag::DMS, "screenSession is null");
7372         return nullptr;
7373     }
7374     return screenSession->GetDisplayNode();
7375 }
7376 
GetScreenCombination(ScreenId screenId)7377 ScreenCombination ScreenSessionManager::GetScreenCombination(ScreenId screenId)
7378 {
7379     DmsXcollie dmsXcollie("DMS:GetScreenCombination", XCOLLIE_TIMEOUT_10S);
7380     auto screenSession = GetScreenSession(screenId);
7381     if (!screenSession) {
7382         TLOGI(WmsLogTag::DMS, "screenSession is null");
7383         return ScreenCombination::SCREEN_ALONE;
7384     }
7385     return screenSession->GetScreenCombination();
7386 }
7387 
Dump(int fd,const std::vector<std::u16string> & args)7388 int ScreenSessionManager::Dump(int fd, const std::vector<std::u16string>& args)
7389 {
7390     TLOGI(WmsLogTag::DMS, "Dump begin");
7391     sptr<ScreenSessionDumper> dumper = new ScreenSessionDumper(fd, args);
7392     if (dumper == nullptr) {
7393         TLOGE(WmsLogTag::DMS, "dumper is nullptr");
7394         return -1;
7395     }
7396     dumper->DumpFreezedPidList(freezedPidList_);
7397     dumper->DumpEventTracker(screenEventTracker_);
7398     dumper->DumpMultiUserInfo(oldScbPids_, currentUserId_, currentScbPId_);
7399     dumper->ExecuteDumpCmd();
7400     TLOGI(WmsLogTag::DMS, "dump end");
7401     return 0;
7402 }
7403 
TriggerFoldStatusChange(FoldStatus foldStatus)7404 void ScreenSessionManager::TriggerFoldStatusChange(FoldStatus foldStatus)
7405 {
7406 #ifdef FOLD_ABILITY_ENABLE
7407     TLOGI(WmsLogTag::DMS, "enter foldStatus = %{public}d.", foldStatus);
7408     if (foldScreenController_ == nullptr) {
7409         return;
7410     }
7411     foldScreenController_->SetFoldStatus(foldStatus);
7412     FoldDisplayMode displayMode = foldScreenController_->GetModeMatchStatus();
7413     SetFoldDisplayMode(displayMode);
7414     NotifyFoldStatusChanged(foldStatus);
7415 #endif
7416 }
7417 
NotifyFoldStatusChanged(const std::string & statusParam)7418 int ScreenSessionManager::NotifyFoldStatusChanged(const std::string& statusParam)
7419 {
7420 #ifdef FOLD_ABILITY_ENABLE
7421     TLOGI(WmsLogTag::DMS, "is dump log");
7422     if (statusParam.empty()) {
7423         return -1;
7424     }
7425     FoldStatus foldStatus = FoldStatus::UNKNOWN;
7426     FoldDisplayMode displayMode = FoldDisplayMode::UNKNOWN;
7427     if (statusParam == STATUS_FOLD_HALF) {
7428         foldStatus = FoldStatus::HALF_FOLD;
7429         displayMode = FoldDisplayMode::FULL;
7430     } else if (statusParam == STATUS_EXPAND) {
7431         foldStatus = FoldStatus::EXPAND;
7432         displayMode = FoldDisplayMode::FULL;
7433     } else if (statusParam == STATUS_FOLD) {
7434         foldStatus = FoldStatus::FOLDED;
7435         displayMode = FoldDisplayMode::MAIN;
7436     } else {
7437         TLOGW(WmsLogTag::DMS, "status not support");
7438         return -1;
7439     }
7440     SetFoldDisplayMode(displayMode);
7441     if (foldScreenController_ != nullptr) {
7442         foldScreenController_->SetFoldStatus(foldStatus);
7443     }
7444     NotifyFoldStatusChanged(foldStatus);
7445 #endif
7446     return 0;
7447 }
7448 
NotifyAvailableAreaChanged(DMRect area,DisplayId displayId)7449 void ScreenSessionManager::NotifyAvailableAreaChanged(DMRect area, DisplayId displayId)
7450 {
7451     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER);
7452     TLOGI(WmsLogTag::DMS, "entry, agent size: %{public}u", static_cast<uint32_t>(agents.size()));
7453     if (agents.empty()) {
7454         return;
7455     }
7456     TLOGI(WmsLogTag::DMS, "displayId: %{public}" PRIu64
7457         ", AvailableArea: [%{public}d, %{public}d, %{public}u, %{public}u]",
7458         static_cast<DisplayId>(displayId), area.posX_, area.posY_, area.width_, area.height_);
7459     for (auto& agent : agents) {
7460         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
7461         if (!IsFreezed(agentPid,
7462             DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER)) {
7463             agent->NotifyAvailableAreaChanged(area, displayId);
7464         }
7465     }
7466 }
7467 
GetAvailableArea(DisplayId displayId,DMRect & area)7468 DMError ScreenSessionManager::GetAvailableArea(DisplayId displayId, DMRect& area)
7469 {
7470     auto displayInfo = GetDisplayInfoById(displayId);
7471     if (displayInfo == nullptr) {
7472         TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
7473         return DMError::DM_ERROR_NULLPTR;
7474     }
7475     sptr<ScreenSession> screenSession;
7476     if (displayId == DISPLAY_ID_FAKE) {
7477         if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7478             return DMError::DM_ERROR_NULLPTR;
7479         }
7480         ScreenId internalScreenId = GetInternalScreenId();
7481         sptr<ScreenSession> internalScreenSession = GetScreenSession(internalScreenId);
7482         if (internalScreenSession == nullptr) {
7483             TLOGE(WmsLogTag::DMS, "internal session is nullptr.");
7484             return DMError::DM_ERROR_NULLPTR;
7485         }
7486         if (!internalScreenSession->GetScreenProperty().GetIsFakeInUse()) {
7487             return DMError::DM_ERROR_NULLPTR;
7488         }
7489         screenSession = internalScreenSession->GetFakeScreenSession();
7490     } else {
7491         screenSession = GetScreenSession(displayInfo->GetScreenId());
7492     }
7493     if (screenSession == nullptr) {
7494         TLOGE(WmsLogTag::DMS, "can not get screen now");
7495         return DMError::DM_ERROR_NULLPTR;
7496     }
7497     area = screenSession->GetAvailableArea();
7498     return DMError::DM_OK;
7499 }
7500 
GetExpandAvailableArea(DisplayId displayId,DMRect & area)7501 DMError ScreenSessionManager::GetExpandAvailableArea(DisplayId displayId, DMRect& area)
7502 {
7503     auto displayInfo = GetDisplayInfoById(displayId);
7504     if (displayInfo == nullptr) {
7505         TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
7506         return DMError::DM_ERROR_NULLPTR;
7507     }
7508     sptr<ScreenSession> screenSession;
7509     screenSession = GetScreenSession(displayInfo->GetScreenId());
7510     if (screenSession == nullptr) {
7511         TLOGE(WmsLogTag::DMS, "can not get screen now");
7512         return DMError::DM_ERROR_NULLPTR;
7513     }
7514     area = screenSession->GetExpandAvailableArea();
7515     return DMError::DM_OK;
7516 }
7517 
UpdateAvailableArea(ScreenId screenId,DMRect area)7518 void ScreenSessionManager::UpdateAvailableArea(ScreenId screenId, DMRect area)
7519 {
7520     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7521         TLOGE(WmsLogTag::DMS, "update available area permission denied!");
7522         return;
7523     }
7524 
7525     auto screenSession = GetScreenSession(screenId);
7526     if (screenSession == nullptr) {
7527         TLOGE(WmsLogTag::DMS, "can not get default screen now");
7528         return;
7529     }
7530     if (!screenSession->UpdateAvailableArea(area)) {
7531         return;
7532     }
7533     NotifyAvailableAreaChanged(area, screenId);
7534 }
7535 
UpdateSuperFoldAvailableArea(ScreenId screenId,DMRect bArea,DMRect cArea)7536 void ScreenSessionManager::UpdateSuperFoldAvailableArea(ScreenId screenId, DMRect bArea, DMRect cArea)
7537 {
7538     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7539         TLOGE(WmsLogTag::DMS, "update super fold available area permission denied!");
7540         return;
7541     }
7542 
7543     auto screenSession = GetScreenSession(screenId);
7544     if (screenSession == nullptr) {
7545         TLOGE(WmsLogTag::DMS, "can not get default screen now");
7546         return;
7547     }
7548     if (screenSession->UpdateAvailableArea(bArea)) {
7549         NotifyAvailableAreaChanged(bArea, screenId);
7550     }
7551     if (!screenSession->GetIsFakeInUse()) {
7552         TLOGE(WmsLogTag::DMS, "fake screen session is not in use");
7553         return;
7554     }
7555     auto fakeScreenSession = screenSession->GetFakeScreenSession();
7556     if (fakeScreenSession == nullptr) {
7557         TLOGE(WmsLogTag::DMS, "can not get fake screen now");
7558         return;
7559     }
7560     if (fakeScreenSession->UpdateAvailableArea(cArea) && cArea.width_ > 0) {
7561         NotifyAvailableAreaChanged(cArea, fakeScreenSession->GetScreenId());
7562     }
7563 }
7564 
UpdateSuperFoldExpandAvailableArea(ScreenId screenId,DMRect area)7565 void ScreenSessionManager::UpdateSuperFoldExpandAvailableArea(ScreenId screenId, DMRect area)
7566 {
7567     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7568         TLOGE(WmsLogTag::DMS, "update super fold available area permission denied!");
7569         return;
7570     }
7571 
7572     auto screenSession = GetScreenSession(screenId);
7573     if (screenSession == nullptr) {
7574         TLOGE(WmsLogTag::DMS, "can not get default screen now");
7575         return;
7576     }
7577     if (screenSession->UpdateExpandAvailableArea(area)) {
7578         TLOGI(WmsLogTag::DMS,
7579             "ExpandAvailableArea x: %{public}d, y: %{public}d, width: %{public}d, height: %{public}d",
7580             area.posX_, area.posY_, area.width_, area.height_);
7581     }
7582 }
7583 
NotifyFoldToExpandCompletion(bool foldToExpand)7584 void ScreenSessionManager::NotifyFoldToExpandCompletion(bool foldToExpand)
7585 {
7586 #ifdef FOLD_ABILITY_ENABLE
7587     TLOGI(WmsLogTag::DMS, "ENTER");
7588     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7589         TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
7590             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7591         return;
7592     }
7593     if (!FoldScreenStateInternel::IsDualDisplayFoldDevice() &&
7594         !FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
7595         !FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7596         SetDisplayNodeScreenId(SCREEN_ID_FULL, foldToExpand ? SCREEN_ID_FULL : SCREEN_ID_MAIN);
7597     }
7598     /* Avoid fold to expand process queues */
7599     if (foldScreenController_ != nullptr) {
7600         foldScreenController_->SetdisplayModeChangeStatus(false);
7601     }
7602     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
7603     if (screenSession == nullptr) {
7604         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
7605         return;
7606     }
7607     screenSession->UpdateRotationAfterBoot(foldToExpand);
7608 #endif
7609 }
7610 
RecordEventFromScb(std::string description,bool needRecordEvent)7611 void ScreenSessionManager::RecordEventFromScb(std::string description, bool needRecordEvent)
7612 {
7613     TLOGW(WmsLogTag::DMS, "%{public}s", description.c_str());
7614     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7615         TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
7616             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7617         return;
7618     }
7619     if (needRecordEvent) {
7620         screenEventTracker_.RecordEvent(description);
7621     }
7622 }
7623 
CheckAndSendHiSysEvent(const std::string & eventName,const std::string & bundleName) const7624 void ScreenSessionManager::CheckAndSendHiSysEvent(const std::string& eventName, const std::string& bundleName) const
7625 {
7626     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CheckAndSendHiSysEvent");
7627     if (eventName != "CREATE_VIRTUAL_SCREEN") {
7628         if (!Permission::CheckIsCallingBundleName(bundleName)) {
7629             TLOGD(WmsLogTag::DMS, "BundleName not in whitelist!");
7630             return;
7631         }
7632     }
7633     int32_t eventRet = HiSysEventWrite(
7634         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
7635         eventName, // CREATE_VIRTUAL_SCREEN, GET_DISPLAY_SNAPSHOT
7636         OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,
7637         "PID", getpid(),
7638         "UID", getuid());
7639     TLOGI(WmsLogTag::DMS, "%{public}s: Write HiSysEvent ret:%{public}d", eventName.c_str(), eventRet);
7640 }
7641 
ProxyForFreeze(const std::set<int32_t> & pidList,bool isProxy)7642 DMError ScreenSessionManager::ProxyForFreeze(const std::set<int32_t>& pidList, bool isProxy)
7643 {
7644     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7645         TLOGE(WmsLogTag::DMS, "permission denied!");
7646         return DMError::DM_ERROR_NOT_SYSTEM_APP;
7647     }
7648     {
7649         std::lock_guard<std::mutex> lock(freezedPidListMutex_);
7650         for (auto pid : pidList) {
7651             if (isProxy) {
7652                 freezedPidList_.insert(pid);
7653             } else {
7654                 freezedPidList_.erase(pid); // set删除不存在的元素不会引发异常
7655             }
7656         }
7657     }
7658     if (isProxy) {
7659         return DMError::DM_OK;
7660     }
7661 
7662     // 进程解冻时刷新一次displaychange
7663     sptr<ScreenSession> screenSession = GetScreenSession(GetDefaultScreenId());
7664     if (!screenSession) {
7665         return DMError::DM_ERROR_NULLPTR;
7666     }
7667     auto task = [=] {
7668         NotifyUnfreezed(pidList, screenSession);
7669     };
7670     taskScheduler_->PostAsyncTask(task, "ProxyForUnFreeze NotifyDisplayChanged");
7671     return DMError::DM_OK;
7672 }
7673 
NotifyUnfreezedAgents(const int32_t & pid,const std::set<int32_t> & unfreezedPidList,const std::set<DisplayManagerAgentType> & pidAgentTypes,const sptr<ScreenSession> & screenSession)7674 void ScreenSessionManager::NotifyUnfreezedAgents(const int32_t& pid, const std::set<int32_t>& unfreezedPidList,
7675     const std::set<DisplayManagerAgentType>& pidAgentTypes, const sptr<ScreenSession>& screenSession)
7676 {
7677     bool isAgentTypeNotify = false;
7678     for (auto agentType : pidAgentTypes) {
7679         auto agents = dmAgentContainer_.GetAgentsByType(agentType);
7680         for (auto agent : agents) {
7681             int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
7682             if (agentPid != pid || unfreezedPidList.count(pid) == 0) {
7683                 continue;
7684             }
7685             isAgentTypeNotify = true;
7686             if (agentType == DisplayManagerAgentType::DISPLAY_EVENT_LISTENER) {
7687                 agent->OnDisplayChange(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_UNFREEZED);
7688             } else if (agentType == DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER) {
7689                 FoldDisplayMode displayMode = GetFoldDisplayMode();
7690                 agent->NotifyDisplayModeChanged(displayMode);
7691             } else if (agentType == DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER) {
7692                 FoldStatus foldStatus = GetFoldStatus();
7693                 agent->NotifyFoldStatusChanged(foldStatus);
7694             } else if (agentType == DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER) {
7695                 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
7696                 agent->NotifyFoldAngleChanged(lastFoldAngles_);
7697             } else if (agentType == DisplayManagerAgentType::SCREEN_EVENT_LISTENER) {
7698                 auto displayInfo = screenSession->ConvertToDisplayInfo();
7699                 auto screenInfo = GetScreenInfoById(displayInfo->GetScreenId());
7700                 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
7701                 agent->OnScreenChange(screenInfo, lastScreenChangeEvent_);
7702             } else if (agentType ==  DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER) {
7703                 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
7704                 agent->NotifyDisplayChangeInfoChanged(lastDisplayChangeInfo_);
7705             } else if (agentType ==  DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER) {
7706                 auto area = screenSession->GetAvailableArea();
7707                 auto displayId = screenSession->ConvertToDisplayInfo()->GetDisplayId();
7708                 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
7709                 agent->NotifyAvailableAreaChanged(area, displayId);
7710             } else {
7711                 isAgentTypeNotify = false;
7712                 TLOGI(WmsLogTag::DMS, "Unknown agentType.");
7713             }
7714         }
7715         if (isAgentTypeNotify) {
7716             pidAgentTypeMap_[pid].erase(agentType);
7717         }
7718     }
7719 }
7720 
NotifyUnfreezed(const std::set<int32_t> & unfreezedPidList,const sptr<ScreenSession> & screenSession)7721 void ScreenSessionManager::NotifyUnfreezed(const std::set<int32_t>& unfreezedPidList,
7722     const sptr<ScreenSession>& screenSession)
7723 {
7724     std::lock_guard<std::mutex> lock(freezedPidListMutex_);
7725     for (auto iter = pidAgentTypeMap_.begin(); iter != pidAgentTypeMap_.end();) {
7726         int32_t pid = iter->first;
7727         auto pidAgentTypes = iter->second;
7728         NotifyUnfreezedAgents(pid, unfreezedPidList, pidAgentTypes, screenSession);
7729         if (pidAgentTypeMap_[pid].empty()) {
7730             iter = pidAgentTypeMap_.erase(iter);
7731         } else {
7732             iter++;
7733         }
7734     }
7735 }
7736 
ResetAllFreezeStatus()7737 DMError ScreenSessionManager::ResetAllFreezeStatus()
7738 {
7739     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7740         TLOGE(WmsLogTag::DMS, "permission denied!");
7741         return DMError::DM_ERROR_NOT_SYSTEM_APP;
7742     }
7743     std::lock_guard<std::mutex> lock(freezedPidListMutex_);
7744     freezedPidList_.clear();
7745     pidAgentTypeMap_.clear();
7746     TLOGI(WmsLogTag::DMS, "freezedPidList_ has been clear.");
7747     return DMError::DM_OK;
7748 }
7749 
GetDeviceScreenConfig()7750 DeviceScreenConfig ScreenSessionManager::GetDeviceScreenConfig()
7751 {
7752     DmsXcollie dmsXcollie("DMS:GetDeviceScreenConfig", XCOLLIE_TIMEOUT_10S);
7753     return deviceScreenConfig_;
7754 }
7755 
RegisterApplicationStateObserver()7756 void ScreenSessionManager::RegisterApplicationStateObserver()
7757 {
7758 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
7759     std::string identify = IPCSkeleton::ResetCallingIdentity();
7760     if (!FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7761         FoldScreenSensorManager::GetInstance().RegisterApplicationStateObserver();
7762     }
7763     IPCSkeleton::SetCallingIdentity(identify);
7764 #endif
7765 }
7766 
SetVirtualScreenBlackList(ScreenId screenId,std::vector<uint64_t> & windowIdList,std::vector<uint64_t> surfaceIdList)7767 void ScreenSessionManager::SetVirtualScreenBlackList(ScreenId screenId, std::vector<uint64_t>& windowIdList,
7768     std::vector<uint64_t> surfaceIdList)
7769 {
7770     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7771         TLOGE(WmsLogTag::DMS, "permission denied!");
7772         return;
7773     }
7774     TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64, screenId);
7775     ScreenId rsScreenId = SCREEN_ID_INVALID;
7776     if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
7777         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
7778         return;
7779     }
7780     if (windowIdList.empty()) {
7781         TLOGI(WmsLogTag::DMS, "WindowIdList is empty");
7782         rsInterface_.SetVirtualScreenBlackList(rsScreenId, surfaceIdList);
7783         return;
7784     }
7785     if (!clientProxy_) {
7786         TLOGE(WmsLogTag::DMS, "clientProxy_ is nullptr");
7787         return;
7788     }
7789     std::vector<uint64_t> surfaceNodeIdsToRS;
7790     clientProxy_->OnGetSurfaceNodeIdsFromMissionIdsChanged(windowIdList, surfaceNodeIdsToRS, true);
7791     if (!surfaceIdList.empty()) {
7792         for (auto surfaceId : surfaceIdList) {
7793             auto it = std::find(surfaceNodeIdsToRS.begin(), surfaceNodeIdsToRS.end(), surfaceId);
7794             if (it != surfaceNodeIdsToRS.end()) {
7795                 continue;
7796             }
7797             surfaceNodeIdsToRS.push_back(surfaceId);
7798         }
7799     }
7800     std::ostringstream oss;
7801     oss << "surfaceNodeIdsToRS: ";
7802     for (auto val : surfaceNodeIdsToRS) {
7803         oss << val << " ";
7804     }
7805     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
7806     rsInterface_.SetVirtualScreenBlackList(rsScreenId, surfaceNodeIdsToRS);
7807 }
7808 
SetVirtualDisplayMuteFlag(ScreenId screenId,bool muteFlag)7809 void ScreenSessionManager::SetVirtualDisplayMuteFlag(ScreenId screenId, bool muteFlag)
7810 {
7811     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7812         TLOGE(WmsLogTag::DMS, "permission denied!");
7813         return;
7814     }
7815     sptr<ScreenSession> virtualScreenSession = GetScreenSession(screenId);
7816     if (!virtualScreenSession) {
7817         TLOGE(WmsLogTag::DMS, "ScreenSession is null");
7818         return;
7819     }
7820     std::shared_ptr<RSDisplayNode> virtualDisplayNode = virtualScreenSession->GetDisplayNode();
7821     if (virtualDisplayNode) {
7822         virtualDisplayNode->SetVirtualScreenMuteStatus(muteFlag);
7823     } else {
7824         TLOGE(WmsLogTag::DMS, "DisplayNode is null");
7825         return;
7826     }
7827     auto transactionProxy = RSTransactionProxy::GetInstance();
7828     if (transactionProxy != nullptr) {
7829         TLOGI(WmsLogTag::DMS, "flush displayNode mute");
7830         transactionProxy->FlushImplicitTransaction();
7831     }
7832     TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " muteFlag: %{public}d", screenId, muteFlag);
7833 }
7834 
DisablePowerOffRenderControl(ScreenId screenId)7835 void ScreenSessionManager::DisablePowerOffRenderControl(ScreenId screenId)
7836 {
7837     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7838         TLOGE(WmsLogTag::DMS, "permission denied!");
7839         return;
7840     }
7841     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64, screenId);
7842     ScreenId rsScreenId = SCREEN_ID_INVALID;
7843     if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
7844         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
7845         return;
7846     }
7847     rsInterface_.DisablePowerOffRenderControl(rsScreenId);
7848 }
7849 
ReportFoldStatusToScb(std::vector<std::string> & screenFoldInfo)7850 void ScreenSessionManager::ReportFoldStatusToScb(std::vector<std::string>& screenFoldInfo)
7851 {
7852     if (clientProxy_) {
7853         auto screenInfo = GetDefaultScreenSession();
7854         int32_t rotation = -1;
7855         if (screenInfo != nullptr) {
7856             rotation = static_cast<int32_t>(screenInfo->GetRotation());
7857         }
7858         screenFoldInfo.emplace_back(std::to_string(rotation));
7859 
7860         clientProxy_->OnFoldStatusChangedReportUE(screenFoldInfo);
7861     }
7862 }
7863 
GetAllDisplayPhysicalResolution()7864 std::vector<DisplayPhysicalResolution> ScreenSessionManager::GetAllDisplayPhysicalResolution()
7865 {
7866     if (allDisplayPhysicalResolution_.empty()) {
7867         sptr<ScreenSession> defaultScreen = GetDefaultScreenSession();
7868         if (defaultScreen == nullptr) {
7869             TLOGE(WmsLogTag::DMS, "default screen null");
7870             return allDisplayPhysicalResolution_;
7871         }
7872         ScreenProperty defaultScreenProperty = defaultScreen->GetScreenProperty();
7873         DisplayPhysicalResolution defaultSize;
7874         defaultSize.foldDisplayMode_ = FoldDisplayMode::UNKNOWN;
7875         defaultSize.physicalWidth_ = defaultScreenProperty.GetPhyBounds().rect_.width_;
7876         defaultSize.physicalHeight_ = defaultScreenProperty.GetPhyBounds().rect_.height_;
7877         allDisplayPhysicalResolution_.emplace_back(defaultSize);
7878     }
7879     for (auto& info : allDisplayPhysicalResolution_) {
7880         if (info.foldDisplayMode_ == FoldDisplayMode::GLOBAL_FULL) {
7881             info.foldDisplayMode_ = FoldDisplayMode::FULL;
7882             break;
7883         }
7884     }
7885     return allDisplayPhysicalResolution_;
7886 }
7887 
GetCapabilityJson(FoldStatus foldStatus,FoldDisplayMode displayMode,std::vector<std::string> rotation,std::vector<std::string> orientation)7888 nlohmann::ordered_json ScreenSessionManager::GetCapabilityJson(FoldStatus foldStatus, FoldDisplayMode displayMode,
7889     std::vector<std::string> rotation, std::vector<std::string> orientation)
7890 {
7891     nlohmann::ordered_json capabilityInfo;
7892     capabilityInfo["foldStatus"] = std::to_string(static_cast<int32_t>(foldStatus));
7893     capabilityInfo["foldDisplayMode"] = std::to_string(static_cast<int32_t>(displayMode));
7894     capabilityInfo["rotation"] = rotation;
7895     capabilityInfo["orientation"] = orientation;
7896     return capabilityInfo;
7897 }
7898 
GetDisplayCapability(std::string & capabilitInfo)7899 DMError ScreenSessionManager::GetDisplayCapability(std::string& capabilitInfo)
7900 {
7901     if (g_foldScreenFlag) {
7902         if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7903             return GetSecondaryDisplayCapability(capabilitInfo);
7904         }
7905         return GetFoldableDeviceCapability(capabilitInfo);
7906     }
7907     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7908         return GetSuperFoldCapability(capabilitInfo);
7909     }
7910 
7911     std::vector<std::string> orientation = ORIENTATION_DEFAULT;
7912     if (g_isPcDevice && !FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7913         orientation = {"1", "0", "3", "2"};
7914     }
7915     nlohmann::ordered_json jsonDisplayCapabilityList;
7916     jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
7917     nlohmann::ordered_json capabilityInfo = GetCapabilityJson(FoldStatus::UNKNOWN, FoldDisplayMode::UNKNOWN,
7918         ROTATION_DEFAULT, orientation);
7919     jsonDisplayCapabilityList["capability"].push_back(std::move(capabilityInfo));
7920 
7921     capabilitInfo = jsonDisplayCapabilityList.dump();
7922     return DMError::DM_OK;
7923 }
7924 
GetSecondaryDisplayCapability(std::string & capabilitInfo)7925 DMError ScreenSessionManager::GetSecondaryDisplayCapability(std::string& capabilitInfo)
7926 {
7927     nlohmann::ordered_json jsonDisplayCapabilityList;
7928     jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
7929 
7930     nlohmann::ordered_json fCapabilityInfo = GetCapabilityJson(FoldStatus::FOLDED, FoldDisplayMode::MAIN,
7931         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7932     jsonDisplayCapabilityList["capability"].push_back(std::move(fCapabilityInfo));
7933     nlohmann::ordered_json nCapability = GetCapabilityJson(FoldStatus::FOLD_STATE_FOLDED_WITH_SECOND_EXPAND,
7934         FoldDisplayMode::MAIN, ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7935     jsonDisplayCapabilityList["capability"].push_back(std::move(nCapability));
7936     nlohmann::ordered_json mCapabilityInfo = GetCapabilityJson(FoldStatus::EXPAND, FoldDisplayMode::FULL,
7937         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7938     jsonDisplayCapabilityList["capability"].push_back(std::move(mCapabilityInfo));
7939     std::vector<std::string> orientation = {"3", "0", "1", "2"};
7940     nlohmann::ordered_json gCapability = GetCapabilityJson(FoldStatus::FOLD_STATE_EXPAND_WITH_SECOND_EXPAND,
7941         FoldDisplayMode::FULL, ROTATION_DEFAULT, orientation);
7942     jsonDisplayCapabilityList["capability"].push_back(std::move(gCapability));
7943 
7944     capabilitInfo = jsonDisplayCapabilityList.dump();
7945     return DMError::DM_OK;
7946 }
7947 
GetFoldableDeviceCapability(std::string & capabilitInfo)7948 DMError ScreenSessionManager::GetFoldableDeviceCapability(std::string& capabilitInfo)
7949 {
7950     nlohmann::ordered_json jsonDisplayCapabilityList;
7951     jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
7952     FoldStatus expandStatus = FoldStatus::EXPAND;
7953     FoldStatus foldStatus = FoldStatus::FOLDED;
7954     FoldDisplayMode expandDisplayMode = FoldDisplayMode::FULL;
7955     FoldDisplayMode foldDisplayMode = FoldDisplayMode::MAIN;
7956     if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
7957         expandDisplayMode = FoldDisplayMode::MAIN;
7958         foldDisplayMode = FoldDisplayMode::SUB;
7959     }
7960     nlohmann::ordered_json expandCapabilityInfo = GetCapabilityJson(expandStatus, expandDisplayMode,
7961         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7962     jsonDisplayCapabilityList["capability"].push_back(std::move(expandCapabilityInfo));
7963     nlohmann::ordered_json foldCapabilityInfo = GetCapabilityJson(foldStatus, foldDisplayMode,
7964         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7965     jsonDisplayCapabilityList["capability"].push_back(std::move(foldCapabilityInfo));
7966 
7967     capabilitInfo = jsonDisplayCapabilityList.dump();
7968     return DMError::DM_OK;
7969 }
7970 
GetSuperFoldCapability(std::string & capabilitInfo)7971 DMError ScreenSessionManager::GetSuperFoldCapability(std::string& capabilitInfo)
7972 {
7973     nlohmann::ordered_json jsonDisplayCapabilityList;
7974     jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
7975 
7976     nlohmann::ordered_json expandCapabilityInfo = GetCapabilityJson(FoldStatus::EXPAND, FoldDisplayMode::UNKNOWN,
7977         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7978     jsonDisplayCapabilityList["capability"].push_back(std::move(expandCapabilityInfo));
7979     nlohmann::ordered_json foldCapabilityInfo = GetCapabilityJson(FoldStatus::FOLDED, FoldDisplayMode::UNKNOWN,
7980         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7981     jsonDisplayCapabilityList["capability"].push_back(std::move(foldCapabilityInfo));
7982     nlohmann::ordered_json halfFoldCapabilityInfo = GetCapabilityJson(FoldStatus::HALF_FOLD, FoldDisplayMode::UNKNOWN,
7983         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7984     jsonDisplayCapabilityList["capability"].push_back(std::move(halfFoldCapabilityInfo));
7985 
7986     capabilitInfo = jsonDisplayCapabilityList.dump();
7987     return DMError::DM_OK;
7988 }
7989 
SetVirtualScreenStatus(ScreenId screenId,VirtualScreenStatus screenStatus)7990 bool ScreenSessionManager::SetVirtualScreenStatus(ScreenId screenId, VirtualScreenStatus screenStatus)
7991 {
7992     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7993         TLOGE(WmsLogTag::DMS, "permission denied!");
7994         return false;
7995     }
7996     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 " screenStatus: %{public}d",
7997         screenId, static_cast<int32_t>(screenStatus));
7998     ScreenId rsScreenId = SCREEN_ID_INVALID;
7999     if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
8000         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
8001         return false;
8002     }
8003 
8004     return rsInterface_.SetVirtualScreenStatus(rsScreenId, screenStatus);
8005 }
8006 
GetOrCreateFakeScreenSession(sptr<ScreenSession> screenSession)8007 sptr<ScreenSession> ScreenSessionManager::GetOrCreateFakeScreenSession(sptr<ScreenSession> screenSession)
8008 {
8009     sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
8010     if (fakeScreenSession != nullptr) {
8011         TLOGI(WmsLogTag::DMS, "fake screen session has exist");
8012         return fakeScreenSession;
8013     }
8014     ScreenProperty screenProperty = screenSession->GetScreenProperty();
8015     ScreenSessionConfig config = {
8016         .screenId = SCREEN_ID_FAKE,
8017         .defaultScreenId = SCREEN_ID_INVALID,
8018         .property = screenProperty,
8019     };
8020     fakeScreenSession =
8021         new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
8022     if (fakeScreenSession == nullptr) {
8023         return nullptr;
8024     }
8025     return fakeScreenSession;
8026 }
8027 
InitFakeScreenSession(sptr<ScreenSession> screenSession)8028 void ScreenSessionManager::InitFakeScreenSession(sptr<ScreenSession> screenSession)
8029 {
8030     if (screenSession == nullptr) {
8031         TLOGE(WmsLogTag::DMS, "screen session is null");
8032         return;
8033     }
8034     sptr<ScreenSession> fakeScreenSession = GetOrCreateFakeScreenSession(screenSession);
8035     if (fakeScreenSession == nullptr) {
8036         TLOGE(WmsLogTag::DMS, "get or create fake screen session failed");
8037         return;
8038     }
8039     ScreenProperty screenProperty = screenSession->GetScreenProperty();
8040     uint32_t screenWidth = screenProperty.GetBounds().rect_.GetWidth();
8041     uint32_t screenHeight = screenProperty.GetBounds().rect_.GetHeight();
8042     uint32_t fakeScreenHeight = screenHeight / HALF_SCREEN_PARAM;
8043     DMRect creaseRect = screenProperty.GetCreaseRect();
8044     if (creaseRect.height_ > 0) {
8045         fakeScreenHeight = screenHeight - (static_cast<uint32_t>(creaseRect.posY_) + creaseRect.height_);
8046     }
8047     fakeScreenSession->UpdatePropertyByResolution(screenWidth, fakeScreenHeight);
8048     fakeScreenSession->SetXYPosition(0, DISPLAY_B_HEIGHT);
8049     fakeScreenSession->SetScreenCombination(ScreenCombination::SCREEN_EXTEND);
8050     screenSession->UpdatePropertyByFakeBounds(screenWidth, fakeScreenHeight);
8051     screenSession->SetFakeScreenSession(fakeScreenSession);
8052     screenSession->SetIsFakeInUse(true);
8053 }
8054 
SetVirtualScreenSecurityExemption(ScreenId screenId,uint32_t pid,std::vector<uint64_t> & windowIdList)8055 DMError ScreenSessionManager::SetVirtualScreenSecurityExemption(ScreenId screenId, uint32_t pid,
8056     std::vector<uint64_t>& windowIdList)
8057 {
8058     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8059         TLOGE(WmsLogTag::DMS, "permission denied!");
8060         return DMError::DM_ERROR_INVALID_CALLING;
8061     }
8062     std::vector<uint64_t> surfaceNodeIds;
8063     if (!windowIdList.empty()) {
8064         MockSessionManagerService::GetInstance().GetProcessSurfaceNodeIdByPersistentId(
8065             pid, windowIdList, surfaceNodeIds);
8066     }
8067     auto rsId = screenIdManager_.ConvertToRsScreenId(screenId);
8068     auto ret = rsInterface_.SetVirtualScreenSecurityExemptionList(rsId, surfaceNodeIds);
8069 
8070     std::ostringstream oss;
8071     oss << "screenId:" << screenId << ", rsID: " << rsId << ", pid: " << pid
8072         << ", winListSize:[ ";
8073     for (auto val : windowIdList) {
8074         oss << val << " ";
8075     }
8076     oss << "]" << ", surfaceListSize:[ ";
8077     for (auto val : surfaceNodeIds) {
8078         oss << val << " ";
8079     }
8080     oss << "]" << ", ret: " << ret;
8081     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
8082     return ret == 0 ? DMError::DM_OK : DMError::DM_ERROR_UNKNOWN;
8083 }
8084 
SetDefaultScreenId(ScreenId defaultScreenId)8085 void ScreenSessionManager::SetDefaultScreenId(ScreenId defaultScreenId)
8086 {
8087     defaultScreenId_ = defaultScreenId;
8088 }
8089 
GetClientProxy()8090 sptr<IScreenSessionManagerClient> ScreenSessionManager::GetClientProxy()
8091 {
8092     return clientProxy_;
8093 }
8094 
SetMultiScreenMode(ScreenId mainScreenId,ScreenId secondaryScreenId,MultiScreenMode screenMode)8095 DMError ScreenSessionManager::SetMultiScreenMode(ScreenId mainScreenId, ScreenId secondaryScreenId,
8096     MultiScreenMode screenMode)
8097 {
8098 #ifdef WM_MULTI_SCREEN_ENABLE
8099     TLOGW(WmsLogTag::DMS, "mainScreenId:%{public}" PRIu64",secondaryScreenId:%{public}" PRIu64",Mode:%{public}u",
8100         mainScreenId, secondaryScreenId, screenMode);
8101     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8102         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
8103             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8104         return DMError::DM_ERROR_NOT_SYSTEM_APP;
8105     }
8106     if (screenMode == MultiScreenMode::SCREEN_MIRROR) {
8107         MultiScreenModeChange(mainScreenId, secondaryScreenId, "mirror");
8108         SetExtendedScreenFallbackPlan(secondaryScreenId);
8109         sptr<ScreenSession> screenSession = GetScreenSession(secondaryScreenId);
8110         if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
8111             MultiScreenPositionOptions defaultOptions = { GetDefaultScreenId(), 0, 0 };
8112             SetRelativePositionForDisconnect(defaultOptions);
8113             NotifyCaptureStatusChanged(true);
8114         }
8115     } else if (screenMode == MultiScreenMode::SCREEN_EXTEND) {
8116         bool lastScreenMirror = false;
8117         sptr<ScreenSession> screenSession = GetScreenSession(secondaryScreenId);
8118         if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
8119             lastScreenMirror = true;
8120         }
8121         MultiScreenModeChange(mainScreenId, secondaryScreenId, "extend");
8122         SetExtendedScreenFallbackPlan(secondaryScreenId);
8123         if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND &&
8124             lastScreenMirror) {
8125             NotifyCaptureStatusChanged(false);
8126         }
8127     } else {
8128         TLOGE(WmsLogTag::DMS, "operate mode error");
8129     }
8130     NotifyScreenModeChange();
8131 #endif
8132     return DMError::DM_OK;
8133 }
8134 
SetMultiScreenRelativePosition(MultiScreenPositionOptions mainScreenOptions,MultiScreenPositionOptions secondScreenOption)8135 DMError ScreenSessionManager::SetMultiScreenRelativePosition(MultiScreenPositionOptions mainScreenOptions,
8136     MultiScreenPositionOptions secondScreenOption)
8137 {
8138 #ifdef WM_MULTI_SCREEN_ENABLE
8139     TLOGI(WmsLogTag::DMS,
8140         "mID:%{public}" PRIu64", X:%{public}u, Y:%{public}u,sID:%{public}" PRIu64", X:%{public}u, Y:%{public}u",
8141         mainScreenOptions.screenId_, mainScreenOptions.startX_, mainScreenOptions.startY_,
8142         secondScreenOption.screenId_, secondScreenOption.startX_, secondScreenOption.startY_);
8143     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8144         TLOGE(WmsLogTag::DMS, "permission denied! clientName: %{public}s, pid: %{public}d",
8145             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8146         return DMError::DM_ERROR_NOT_SYSTEM_APP;
8147     }
8148     sptr<ScreenSession> firstScreenSession = GetScreenSession(mainScreenOptions.screenId_);
8149     sptr<ScreenSession> secondScreenSession = GetScreenSession(secondScreenOption.screenId_);
8150     if (!firstScreenSession || !secondScreenSession) {
8151         TLOGE(WmsLogTag::DMS, "ScreenSession is null");
8152         return DMError::DM_ERROR_NULLPTR;
8153     }
8154     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
8155         !MultiScreenManager::GetInstance().AreScreensTouching(firstScreenSession, secondScreenSession,
8156         mainScreenOptions, secondScreenOption)) {
8157         TLOGE(WmsLogTag::DMS, "Options incorrect!");
8158         return DMError::DM_ERROR_INVALID_PARAM;
8159     }
8160     firstScreenSession->SetStartPosition(mainScreenOptions.startX_, mainScreenOptions.startY_);
8161     CalculateXYPosition(firstScreenSession);
8162     firstScreenSession->PropertyChange(firstScreenSession->GetScreenProperty(),
8163         ScreenPropertyChangeReason::RELATIVE_POSITION_CHANGE);
8164     secondScreenSession->SetStartPosition(secondScreenOption.startX_, secondScreenOption.startY_);
8165     CalculateXYPosition(secondScreenSession);
8166     secondScreenSession->PropertyChange(secondScreenSession->GetScreenProperty(),
8167         ScreenPropertyChangeReason::RELATIVE_POSITION_CHANGE);
8168     std::shared_ptr<RSDisplayNode> firstDisplayNode = firstScreenSession->GetDisplayNode();
8169     std::shared_ptr<RSDisplayNode> secondDisplayNode = secondScreenSession->GetDisplayNode();
8170     if (firstDisplayNode && secondDisplayNode) {
8171         firstDisplayNode->SetDisplayOffset(mainScreenOptions.startX_, mainScreenOptions.startY_);
8172         secondDisplayNode->SetDisplayOffset(secondScreenOption.startX_, secondScreenOption.startY_);
8173     } else {
8174         TLOGW(WmsLogTag::DMS, "DisplayNode is null");
8175     }
8176     auto transactionProxy = RSTransactionProxy::GetInstance();
8177     if (transactionProxy != nullptr) {
8178         TLOGI(WmsLogTag::DMS, "free displayNode");
8179         transactionProxy->FlushImplicitTransaction();
8180     }
8181 #endif
8182     return DMError::DM_OK;
8183 }
8184 
SetRelativePositionForDisconnect(MultiScreenPositionOptions defaultScreenOptions)8185 void ScreenSessionManager::SetRelativePositionForDisconnect(MultiScreenPositionOptions defaultScreenOptions)
8186 {
8187 #ifdef WM_MULTI_SCREEN_ENABLE
8188     TLOGI(WmsLogTag::DMS, "mID:%{public}" PRIu64", X:%{public}u, Y:%{public}u",
8189         defaultScreenOptions.screenId_, defaultScreenOptions.startX_, defaultScreenOptions.startY_);
8190     sptr<ScreenSession> defaultScreenSession = GetScreenSession(defaultScreenOptions.screenId_);
8191     if (!defaultScreenSession) {
8192         TLOGE(WmsLogTag::DMS, "ScreenSession is null");
8193         return;
8194     }
8195     defaultScreenSession->SetStartPosition(defaultScreenOptions.startX_, defaultScreenOptions.startY_);
8196     CalculateXYPosition(defaultScreenSession);
8197     defaultScreenSession->PropertyChange(defaultScreenSession->GetScreenProperty(),
8198         ScreenPropertyChangeReason::RELATIVE_POSITION_CHANGE);
8199     std::shared_ptr<RSDisplayNode> defaultDisplayNode = defaultScreenSession->GetDisplayNode();
8200     if (defaultDisplayNode) {
8201         defaultDisplayNode->SetDisplayOffset(defaultScreenOptions.startX_, defaultScreenOptions.startY_);
8202     } else {
8203         TLOGW(WmsLogTag::DMS, "DisplayNode is null");
8204     }
8205     auto transactionProxy = RSTransactionProxy::GetInstance();
8206     if (transactionProxy != nullptr) {
8207         TLOGI(WmsLogTag::DMS, "free displayNode");
8208         transactionProxy->FlushImplicitTransaction();
8209     }
8210 #endif
8211 }
8212 
MultiScreenModeChange(ScreenId mainScreenId,ScreenId secondaryScreenId,const std::string & operateMode)8213 void ScreenSessionManager::MultiScreenModeChange(ScreenId mainScreenId, ScreenId secondaryScreenId,
8214     const std::string& operateMode)
8215 {
8216 #ifdef WM_MULTI_SCREEN_ENABLE
8217     TLOGW(WmsLogTag::DMS, "mainId=%{public}" PRIu64" secondId=%{public}" PRIu64" operateType: %{public}s",
8218         mainScreenId, secondaryScreenId, operateMode.c_str());
8219     sptr<ScreenSession> firstSession = nullptr;
8220     sptr<ScreenSession> secondarySession = nullptr;
8221     {
8222         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8223         for (auto sessionIt : screenSessionMap_) {
8224             auto screenSession = sessionIt.second;
8225             if (screenSession == nullptr) {
8226                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
8227                 continue;
8228             }
8229             if (!screenSession->GetIsCurrentInUse()) {
8230                 TLOGE(WmsLogTag::DMS, "current screen: %{public}" PRIu64" is not in user!", sessionIt.first);
8231                 continue;
8232             }
8233             if (sessionIt.first == mainScreenId) {
8234                 firstSession = screenSession;
8235             }
8236             if (sessionIt.first == secondaryScreenId) {
8237                 secondarySession = screenSession;
8238             }
8239         }
8240     }
8241 
8242     if (firstSession != nullptr && secondarySession != nullptr) {
8243         ScreenCombination firstCombination = firstSession->GetScreenCombination();
8244         ScreenCombination secondaryCombination = secondarySession->GetScreenCombination();
8245         MultiScreenManager::GetInstance().MultiScreenModeChange(firstSession, secondarySession, operateMode);
8246         if ((firstCombination == ScreenCombination::SCREEN_MIRROR ||
8247             secondaryCombination == ScreenCombination::SCREEN_MIRROR) &&
8248             operateMode == SCREEN_EXTEND) {
8249             MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_MIRROR, MULTI_SCREEN_EXIT_STR);
8250             MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_ENTER_STR);
8251         } else if ((firstCombination == ScreenCombination::SCREEN_EXTEND ||
8252             secondaryCombination == ScreenCombination::SCREEN_EXTEND) &&
8253             operateMode == SCREEN_MIRROR) {
8254             MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_EXIT_STR);
8255             MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_MIRROR, MULTI_SCREEN_ENTER_STR);
8256         }
8257     } else {
8258         TLOGE(WmsLogTag::DMS, "params error");
8259     }
8260 #endif
8261 }
8262 
SwitchScrollParam(FoldDisplayMode displayMode)8263 void ScreenSessionManager::SwitchScrollParam(FoldDisplayMode displayMode)
8264 {
8265     auto task = [=]() {
8266         std::map<FoldDisplayMode, ScrollableParam> scrollableParams = ScreenSceneConfig::GetAllScrollableParam();
8267         std::string scrollVelocityScale = scrollableParams.count(displayMode) != 0 ?
8268             scrollableParams[displayMode].velocityScale_ : "0";
8269         std::string scrollFriction = scrollableParams.count(displayMode) != 0 ?
8270             scrollableParams[displayMode].friction_ : "0";
8271         system::SetParameter("persist.scrollable.velocityScale", scrollVelocityScale);
8272         system::SetParameter("persist.scrollable.friction", scrollFriction);
8273     };
8274     taskScheduler_->PostAsyncTask(task, "SwitchScrollParam");
8275 }
8276 
MultiScreenModeChange(const std::string & firstScreenIdStr,const std::string & secondaryScreenIdStr,const std::string & secondaryChandeMode)8277 void ScreenSessionManager::MultiScreenModeChange(const std::string& firstScreenIdStr,
8278     const std::string& secondaryScreenIdStr, const std::string& secondaryChandeMode)
8279 {
8280 #ifdef WM_MULTI_SCREEN_ENABLE
8281     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8282         TLOGE(WmsLogTag::DMS, "permission denied! clientName: %{public}s, pid: %{public}d",
8283             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8284         return;
8285     }
8286     ScreenId firstScreenId = static_cast<ScreenId>(std::stoi(firstScreenIdStr));
8287     ScreenId secondaryScreenId = static_cast<ScreenId>(std::stoi(secondaryScreenIdStr));
8288     if (secondaryChandeMode == "mirror" || secondaryChandeMode == "extend") {
8289         MultiScreenModeChange(firstScreenId, secondaryScreenId, secondaryChandeMode);
8290     } else {
8291         TLOGE(WmsLogTag::DMS, "dumper params error");
8292     }
8293 #endif
8294 }
8295 
OnScreenExtendChange(ScreenId mainScreenId,ScreenId extendScreenId)8296 void ScreenSessionManager::OnScreenExtendChange(ScreenId mainScreenId, ScreenId extendScreenId)
8297 {
8298     if (!clientProxy_) {
8299         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8300         return;
8301     }
8302     clientProxy_->OnScreenExtendChanged(mainScreenId, extendScreenId);
8303 }
8304 
OnTentModeChanged(int tentType,int32_t hall)8305 void ScreenSessionManager::OnTentModeChanged(int tentType, int32_t hall)
8306 {
8307 #ifdef FOLD_ABILITY_ENABLE
8308     if (!foldScreenController_) {
8309         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
8310         return;
8311     }
8312     foldScreenController_->OnTentModeChanged(tentType, hall);
8313 #endif
8314 }
8315 
SetCoordinationFlag(bool isCoordinationFlag)8316 void ScreenSessionManager::SetCoordinationFlag(bool isCoordinationFlag)
8317 {
8318     TLOGI(WmsLogTag::DMS, "set coordination flag %{public}d", isCoordinationFlag);
8319     isCoordinationFlag_ = isCoordinationFlag;
8320 }
8321 
SetVirtualScreenMaxRefreshRate(ScreenId id,uint32_t refreshRate,uint32_t & actualRefreshRate)8322 DMError ScreenSessionManager::SetVirtualScreenMaxRefreshRate(ScreenId id, uint32_t refreshRate,
8323     uint32_t& actualRefreshRate)
8324 {
8325     if (!SessionPermission::IsSystemCalling()) {
8326         TLOGE(WmsLogTag::DMS, "permission denied! clientName: %{public}s, pid: %{public}d",
8327             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8328         return DMError::DM_ERROR_NOT_SYSTEM_APP;
8329     }
8330     TLOGI(WmsLogTag::DMS, "ID:%{public}" PRIu64", refreshRate:%{public}u, actualRefreshRate:%{public}u",
8331         id, refreshRate, actualRefreshRate);
8332     if (id == GetDefaultScreenId()) {
8333         TLOGE(WmsLogTag::DMS, "cannot set refresh main screen id: %{public}" PRIu64".", GetDefaultScreenId());
8334         return DMError::DM_ERROR_INVALID_PARAM;
8335     }
8336     auto screenSession = GetScreenSession(id);
8337     if (screenSession == nullptr) {
8338         TLOGE(WmsLogTag::DMS, "screenSession is null.");
8339         return DMError::DM_ERROR_INVALID_PARAM;
8340     }
8341     ScreenId rsScreenId;
8342     if (!screenIdManager_.ConvertToRsScreenId(id, rsScreenId)) {
8343         TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
8344         return DMError::DM_ERROR_INVALID_PARAM;
8345     }
8346     int32_t res = rsInterface_.SetVirtualScreenRefreshRate(rsScreenId, refreshRate, actualRefreshRate);
8347     TLOGI(WmsLogTag::DMS, "refreshRate:%{public}u, actualRefreshRate:%{public}u", refreshRate, actualRefreshRate);
8348     if (res != StatusCode::SUCCESS) {
8349         TLOGE(WmsLogTag::DMS, "rsInterface error: %{public}d", res);
8350         return DMError::DM_ERROR_INVALID_PARAM;
8351     }
8352     screenSession->UpdateRefreshRate(actualRefreshRate);
8353     return DMError::DM_OK;
8354 }
8355 
OnScreenCaptureNotify(ScreenId mainScreenId,int32_t uid,const std::string & clientName)8356 void ScreenSessionManager::OnScreenCaptureNotify(ScreenId mainScreenId, int32_t uid, const std::string& clientName)
8357 {
8358     if (!clientProxy_) {
8359         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8360         return;
8361     }
8362     clientProxy_->ScreenCaptureNotify(mainScreenId, uid, clientName);
8363 }
8364 
AddPermissionUsedRecord(const std::string & permission,int32_t successCount,int32_t failCount)8365 void ScreenSessionManager::AddPermissionUsedRecord(const std::string& permission, int32_t successCount,
8366     int32_t failCount)
8367 {
8368     int32_t ret = Security::AccessToken::PrivacyKit::AddPermissionUsedRecord(IPCSkeleton::GetCallingTokenID(),
8369         permission, successCount, failCount);
8370     if (ret != 0) {
8371         TLOGW(WmsLogTag::DMS, "permission:%{public}s, successCount %{public}d, failedCount %{public}d",
8372             permission.c_str(), successCount, failCount);
8373     }
8374 }
8375 
GetScreenCapture(const CaptureOption & captureOption,DmErrorCode * errorCode)8376 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetScreenCapture(const CaptureOption& captureOption,
8377     DmErrorCode* errorCode)
8378 {
8379     TLOGI(WmsLogTag::DMS, "enter!");
8380     if (errorCode == nullptr) {
8381         TLOGE(WmsLogTag::DMS, "param is null.");
8382         return nullptr;
8383     }
8384     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
8385         TLOGW(WmsLogTag::DMS, "capture disabled by edm!");
8386         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
8387         return nullptr;
8388     }
8389     if (!ScreenSceneConfig::IsSupportCapture()) {
8390         TLOGW(WmsLogTag::DMS, "device not support capture.");
8391         *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
8392         return nullptr;
8393     }
8394     if (!Permission::CheckCallingPermission(CUSTOM_SCREEN_CAPTURE_PERMISSION) && !SessionPermission::IsShellCall()) {
8395         TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d.",
8396             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingRealPid());
8397         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
8398         return nullptr;
8399     }
8400     if (captureOption.displayId_ == DISPLAY_ID_INVALID ||
8401         (captureOption.displayId_ == DISPLAY_ID_FAKE && !IsFakeDisplayExist())) {
8402         TLOGE(WmsLogTag::DMS, "display id invalid.");
8403         *errorCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
8404         return nullptr;
8405     }
8406     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetScreenCapture(%" PRIu64")", captureOption.displayId_);
8407     auto res = GetScreenSnapshot(captureOption.displayId_, false);
8408     AddPermissionUsedRecord(CUSTOM_SCREEN_CAPTURE_PERMISSION,
8409         static_cast<int32_t>(res != nullptr), static_cast<int32_t>(res == nullptr));
8410     if (res == nullptr) {
8411         TLOGE(WmsLogTag::DMS, "get capture null.");
8412         *errorCode = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
8413         return nullptr;
8414     }
8415     NotifyScreenshot(captureOption.displayId_);
8416     if (SessionPermission::IsBetaVersion()) {
8417         CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
8418     }
8419     *errorCode = DmErrorCode::DM_OK;
8420     isScreenShot_ = true;
8421     /* notify scb to do toast */
8422     OnScreenCaptureNotify(GetDefaultScreenId(), IPCSkeleton::GetCallingUid(), SysCapUtil::GetClientName());
8423     /* notify application capture happend */
8424     NotifyCaptureStatusChanged();
8425     return res;
8426 }
8427 
GetPrimaryDisplayInfo()8428 sptr<DisplayInfo> ScreenSessionManager::GetPrimaryDisplayInfo()
8429 {
8430     sptr<ScreenSession> screenSession = nullptr;
8431     {
8432         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8433         for (auto sessionIt : screenSessionMap_) {
8434             screenSession = sessionIt.second;
8435             if (screenSession == nullptr) {
8436                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
8437                 continue;
8438             }
8439             if (!screenSession->GetIsExtend()) {
8440                 TLOGE(WmsLogTag::DMS, "find primary %{public}" PRIu64, screenSession->screenId_);
8441                 break;
8442             }
8443         }
8444     }
8445     if (screenSession == nullptr) {
8446         TLOGW(WmsLogTag::DMS, "get extend screen faild use default!");
8447         screenSession = GetScreenSession(GetDefaultScreenId());
8448     }
8449     if (screenSession) {
8450         std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
8451         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
8452         if (displayInfo == nullptr) {
8453             TLOGI(WmsLogTag::DMS, "convert display error.");
8454             return nullptr;
8455         }
8456         displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
8457         return displayInfo;
8458     } else {
8459         TLOGE(WmsLogTag::DMS, "failed");
8460         return nullptr;
8461     }
8462 }
8463 
OnSuperFoldStatusChange(ScreenId screenId,SuperFoldStatus superFoldStatus)8464 void ScreenSessionManager::OnSuperFoldStatusChange(ScreenId screenId, SuperFoldStatus superFoldStatus)
8465 {
8466     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", superFoldStatus: %{public}d", screenId,
8467         static_cast<uint32_t>(superFoldStatus));
8468     if (!clientProxy_) {
8469         TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
8470         return;
8471     }
8472     clientProxy_->OnSuperFoldStatusChanged(screenId, superFoldStatus);
8473 }
8474 
OnExtendScreenConnectStatusChange(ScreenId screenId,ExtendScreenConnectStatus extendScreenConnectStatus)8475 void ScreenSessionManager::OnExtendScreenConnectStatusChange(ScreenId screenId,
8476     ExtendScreenConnectStatus extendScreenConnectStatus)
8477 {
8478     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", extendScreenConnectStatus: %{public}d", screenId,
8479         static_cast<uint32_t>(extendScreenConnectStatus));
8480     if (!clientProxy_) {
8481         TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
8482         return;
8483     }
8484     clientProxy_->OnExtendScreenConnectStatusChanged(screenId, extendScreenConnectStatus);
8485 }
8486 
OnSecondaryReflexionChange(ScreenId screenId,bool isSecondaryReflexion)8487 void ScreenSessionManager::OnSecondaryReflexionChange(ScreenId screenId, bool isSecondaryReflexion)
8488 {
8489     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", isSecondaryReflexion: %{public}d", screenId,
8490         isSecondaryReflexion);
8491     if (!clientProxy_) {
8492         TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
8493         return;
8494     }
8495     clientProxy_->OnSecondaryReflexionChanged(screenId, isSecondaryReflexion);
8496 }
8497 
GetCameraStatus()8498 int32_t ScreenSessionManager::GetCameraStatus()
8499 {
8500     return cameraStatus_;
8501 }
8502 
GetCameraPosition()8503 int32_t ScreenSessionManager::GetCameraPosition()
8504 {
8505     return cameraPosition_;
8506 }
8507 
IsScreenCasting()8508 bool ScreenSessionManager::IsScreenCasting()
8509 {
8510     if (virtualScreenCount_ > 0 || hdmiScreenCount_ > 0) {
8511         TLOGI(WmsLogTag::DMS, "virtualScreenCount_: %{public}" PRIu32 ", hdmiScreenCount_: %{public}d",
8512             virtualScreenCount_, hdmiScreenCount_);
8513         return true;
8514     }
8515     TLOGI(WmsLogTag::DMS, "not casting");
8516     return false;
8517 }
8518 
SetMultiScreenOuterMode(sptr<ScreenSession> & innerSession,sptr<ScreenSession> & outerSession)8519 void ScreenSessionManager::SetMultiScreenOuterMode(sptr<ScreenSession>& innerSession,
8520     sptr<ScreenSession>& outerSession)
8521 {
8522 #ifdef WM_MULTI_SCREEN_ENABLE
8523     std::string screenMode = "";
8524     if (clientProxy_ == nullptr) {
8525         TLOGE(WmsLogTag::DMS, "client proxy is null.");
8526         return;
8527     }
8528     TLOGI(WmsLogTag::DMS, "switch outer start");
8529     ScreenCombination outerCombination = outerSession->GetScreenCombination();
8530     if (outerCombination != ScreenCombination::SCREEN_MIRROR && outerCombination != ScreenCombination::SCREEN_EXTEND) {
8531         TLOGE(WmsLogTag::DMS, "outer mode error.");
8532         return;
8533     }
8534     screenMode = outerCombination == ScreenCombination::SCREEN_MIRROR ? SCREEN_MIRROR : SCREEN_EXTEND;
8535     MultiScreenManager::GetInstance().MultiScreenModeChange(outerSession, innerSession, screenMode);
8536     clientProxy_->OnScreenConnectionChanged(GetSessionOption(innerSession), ScreenEvent::DISCONNECTED);
8537     {
8538         std::shared_ptr<RSDisplayNode> displayNode = innerSession->GetDisplayNode();
8539         if (displayNode != nullptr) {
8540             displayNode->RemoveFromTree();
8541             innerSession->ReleaseDisplayNode();
8542         }
8543         displayNode = nullptr;
8544     }
8545     auto transactionProxy = RSTransactionProxy::GetInstance();
8546     if (transactionProxy != nullptr) {
8547         TLOGI(WmsLogTag::DMS, "free displayNode");
8548         transactionProxy->FlushImplicitTransaction();
8549     }
8550     ScreenSettingHelper::SetSettingValue("only_second_screen_info", screenMode);
8551     CallRsSetScreenPowerStatusSync(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
8552     TLOGI(WmsLogTag::DMS, "switch out end.");
8553 #endif
8554 }
8555 
RecoveryMultiScreenNormalMode(sptr<ScreenSession> & innerSession,sptr<ScreenSession> & outerSession)8556 void ScreenSessionManager::RecoveryMultiScreenNormalMode(sptr<ScreenSession>& innerSession,
8557     sptr<ScreenSession>& outerSession)
8558 {
8559 #ifdef WM_MULTI_SCREEN_ENABLE
8560     std::string screenMode = "";
8561     TLOGI(WmsLogTag::DMS, "recovery normal mode.");
8562     ScreenSettingHelper::GetSettingValue("only_second_screen_info", screenMode);
8563     if (clientProxy_ == nullptr || screenMode == "") {
8564         TLOGE(WmsLogTag::DMS, "client proxy is null.");
8565         return;
8566     }
8567     Rosen::RSDisplayNodeConfig rsConfig;
8568     rsConfig = {.screenId = innerSession->GetScreenId()};
8569     innerSession->CreateDisplayNode(rsConfig);
8570     innerSession->SetIsExtend(false);
8571     outerSession->SetIsExtend(true);
8572     CallRsSetScreenPowerStatusSync(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
8573     clientProxy_->OnScreenConnectionChanged(GetSessionOption(outerSession), ScreenEvent::DISCONNECTED);
8574     int64_t timeStamp = 50;  // wait notify
8575     std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
8576     if (screenMode == SCREEN_MIRROR) {
8577         NodeId nodeId = innerSession->GetDisplayNode()->GetId();
8578         rsConfig = {.screenId = outerSession->GetScreenId(), .isMirrored = true, .mirrorNodeId = nodeId};
8579         outerSession->CreateDisplayNode(rsConfig);
8580         outerSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
8581     } else if (screenMode == SCREEN_EXTEND) {
8582         rsConfig = {.screenId = outerSession->GetScreenId()};
8583         outerSession->CreateDisplayNode(rsConfig);
8584         outerSession->SetScreenCombination(ScreenCombination::SCREEN_EXTEND);
8585     }
8586     innerSession->SetScreenCombination(ScreenCombination::SCREEN_MAIN);
8587     clientProxy_->OnScreenConnectionChanged(GetSessionOption(innerSession), ScreenEvent::CONNECTED);
8588     std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
8589     if (screenMode == SCREEN_EXTEND) {
8590         clientProxy_->OnScreenConnectionChanged(GetSessionOption(outerSession), ScreenEvent::CONNECTED);
8591     }
8592     ScreenSettingHelper::SetSettingValue("only_second_screen_info", "");
8593     TLOGI(WmsLogTag::DMS, "recovery normal mode end.");
8594 #endif
8595 }
8596 
GetSessionOption(sptr<ScreenSession> screenSession)8597 SessionOption ScreenSessionManager::GetSessionOption(sptr<ScreenSession> screenSession)
8598 {
8599     SessionOption option = {
8600         .rsId_ = screenSession->GetRSScreenId(),
8601         .name_ = screenSession->GetName(),
8602         .isExtend_ = screenSession->GetIsExtend(),
8603         .innerName_ = screenSession->GetInnerName(),
8604         .screenId_ = screenSession->GetScreenId(),
8605     };
8606     return option;
8607 }
8608 
GetSessionOption(sptr<ScreenSession> screenSession,ScreenId screenId)8609 SessionOption ScreenSessionManager::GetSessionOption(sptr<ScreenSession> screenSession, ScreenId screenId)
8610 {
8611     SessionOption option = {
8612         .rsId_ = screenSession->GetRSScreenId(),
8613         .name_ = screenSession->GetName(),
8614         .isExtend_ = screenSession->GetIsExtend(),
8615         .innerName_ = screenSession->GetInnerName(),
8616         .screenId_ = screenId,
8617     };
8618     return option;
8619 }
8620 
MultiScreenChangeOuter(const std::string & outerFlag)8621 void ScreenSessionManager::MultiScreenChangeOuter(const std::string& outerFlag)
8622 {
8623 #ifdef WM_MULTI_SCREEN_ENABLE
8624     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8625         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
8626             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8627         return;
8628     }
8629     if (!clientProxy_ || (outerFlag != "1" && outerFlag != "0")) {
8630         TLOGE(WmsLogTag::DMS, "change params error.");
8631         return;
8632     }
8633     sptr<ScreenSession> innerSession = nullptr;
8634     sptr<ScreenSession> outerSession = nullptr;
8635     {
8636         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8637         for (auto sessionIt : screenSessionMap_) {
8638             auto screenSession = sessionIt.second;
8639             if (screenSession == nullptr) {
8640                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr.");
8641                 continue;
8642             }
8643             if (!screenSession->GetIsCurrentInUse()) {
8644                 continue;
8645             }
8646             if (screenSession->GetIsInternal()) {
8647                 innerSession = screenSession;
8648             } else {
8649                 outerSession = screenSession;
8650             }
8651         }
8652     }
8653     if (innerSession == nullptr || outerSession == nullptr) {
8654         TLOGE(WmsLogTag::DMS, "innerSession or outerSession is nullptr.");
8655         return;
8656     }
8657     if (outerFlag == "1") {
8658         SetMultiScreenOuterMode(innerSession, outerSession);
8659     } else {
8660         RecoveryMultiScreenNormalMode(innerSession, outerSession);
8661     }
8662     FixPowerStatus();
8663 #endif
8664 }
8665 
SetScreenSkipProtectedWindow(const std::vector<ScreenId> & screenIds,bool isEnable)8666 DMError ScreenSessionManager::SetScreenSkipProtectedWindow(const std::vector<ScreenId>& screenIds, bool isEnable)
8667 {
8668     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8669         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
8670             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8671         return DMError::DM_ERROR_NOT_SYSTEM_APP;
8672     }
8673     std::ostringstream oss;
8674     for (ScreenId screenId : screenIds) {
8675         oss << screenId << " ";
8676     }
8677     TLOGI(WmsLogTag::DMS, "screenIds:%{public}s, isEnable:%{public}d", oss.str().c_str(), isEnable);
8678     {
8679         std::lock_guard<std::mutex> lock(shareProtectMutex_);
8680         for (ScreenId screenId : screenIds) {
8681             sptr<ScreenSession> screenSession = GetScreenSession(screenId);
8682             if (screenSession == nullptr) {
8683                 continue;
8684             }
8685             if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
8686                 screenSession->SetShareProtect(isEnable);
8687             }
8688         }
8689     }
8690     SetScreenSkipProtectedWindowInner();
8691     return DMError::DM_OK;
8692 }
8693 
SetScreenSkipProtectedWindowInner()8694 void ScreenSessionManager::SetScreenSkipProtectedWindowInner()
8695 {
8696     TLOGI(WmsLogTag::DMS, "enter");
8697     bool screenSkipProtectedWindowValue = false;
8698     bool ret = ScreenSettingHelper::GetSettingscreenSkipProtectedWindow(screenSkipProtectedWindowValue);
8699     if (!ret) {
8700         TLOGE(WmsLogTag::DMS, "get setting failed, default value false");
8701     }
8702     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8703     for (auto sessionIt : screenSessionMap_) {
8704         auto screenSession = sessionIt.second;
8705         if (screenSession == nullptr) {
8706             TLOGE(WmsLogTag::DMS, "screenSession is nullptr, ScreenId:%{public}" PRIu64"",
8707                 sessionIt.first);
8708             continue;
8709         }
8710         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
8711             ScreenId rsScreenId;
8712             if (!screenIdManager_.ConvertToRsScreenId(screenSession->GetScreenId(), rsScreenId)) {
8713                 TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
8714                 continue;
8715             }
8716             bool requiredSkipWindow = screenSession->GetShareProtect() && screenSkipProtectedWindowValue;
8717             TLOGI(WmsLogTag::DMS, "virtualScreenId:%{public}" PRIu64 " requiredSkipWindow:%{public}d",
8718                 sessionIt.first, requiredSkipWindow);
8719             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
8720                 "SetCastScreenEnableSkipWindow(%" PRIu64")", sessionIt.first);
8721             rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, requiredSkipWindow);
8722         }
8723     }
8724 }
8725 
IsOrientationNeedChanged()8726 bool ScreenSessionManager::IsOrientationNeedChanged()
8727 {
8728     if (GetFoldDisplayMode() == FoldDisplayMode::GLOBAL_FULL) {
8729         return true;
8730     }
8731     return false;
8732 }
8733 
UpdateValidArea(ScreenId screenId,uint32_t validWidth,uint32_t validHeight)8734 void ScreenSessionManager::UpdateValidArea(ScreenId screenId, uint32_t validWidth, uint32_t validHeight)
8735 {
8736     auto screenSession = GetScreenSession(screenId);
8737     if (!screenSession) {
8738         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
8739         return;
8740     }
8741     screenSession->SetValidWidth(validWidth);
8742     screenSession->SetValidHeight(validHeight);
8743 }
8744 
GetIsRealScreen(ScreenId screenId)8745 bool ScreenSessionManager::GetIsRealScreen(ScreenId screenId)
8746 {
8747     if (!SessionPermission::IsSystemCalling()) {
8748         TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
8749             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8750         return false;
8751     }
8752     auto screenSession = GetScreenSession(screenId);
8753     if (!screenSession) {
8754         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
8755         return false;
8756     }
8757     return screenSession->GetIsRealScreen();
8758 }
8759 
SetSystemKeyboardStatus(bool isOn)8760 DMError ScreenSessionManager::SetSystemKeyboardStatus(bool isOn)
8761 {
8762     if (!SessionPermission::IsSACalling()) {
8763         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
8764             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8765         return DMError::DM_ERROR_NOT_SYSTEM_APP;
8766     }
8767 #ifdef FOLD_ABILITY_ENABLE
8768     std::string hprProductType = "HPR";
8769     std::string productType = OHOS::system::GetParameter("const.build.product", "HYM");
8770     if (productType == hprProductType) {
8771         SuperFoldStateManager::GetInstance().SetSystemKeyboardStatus(isOn);
8772         return DMError::DM_OK;
8773     } else {
8774         return DMError::DM_ERROR_DEVICE_NOT_SUPPORT;
8775     }
8776 #endif // FOLD_ABILITY_ENABLE
8777     return DMError::DM_ERROR_DEVICE_NOT_SUPPORT;
8778 }
8779 
WakeUpPictureFrameBlock(DisplayEvent event)8780 void ScreenSessionManager::WakeUpPictureFrameBlock(DisplayEvent event)
8781 {
8782     std::unique_lock <std::mutex> lock(screenWaitPictureFrameMutex_);
8783     if (event == DisplayEvent::SCREEN_LOCK_START_DREAM) {
8784         TLOGI(WmsLogTag::DMS, "[UL_POWER]get pictureFrameReady");
8785         pictureFrameReady_ = true;
8786     } else if (event == DisplayEvent::SCREEN_LOCK_END_DREAM) {
8787         TLOGI(WmsLogTag::DMS, "[UL_POWER]get pictureFrameBreak");
8788         pictureFrameBreak_ = true;
8789     }
8790     screenWaitPictureFrameCV_.notify_all();
8791 }
8792 
BlockScreenWaitPictureFrameByCV(bool isStartDream)8793 bool ScreenSessionManager::BlockScreenWaitPictureFrameByCV(bool isStartDream)
8794 {
8795     TLOGI(WmsLogTag::DMS, "[UL_POWER]enter");
8796     std::unique_lock <std::mutex> lock(screenWaitPictureFrameMutex_);
8797     pictureFrameReady_ = false;
8798     pictureFrameBreak_ = false;
8799     if (screenWaitPictureFrameCV_.wait_for(lock, std::chrono::milliseconds(SCREEN_WAIT_PICTURE_FRAME_TIME))
8800         == std::cv_status::timeout) {
8801         TLOGI(WmsLogTag::DMS, "[UL_POWER]wait picture frame timeout");
8802         return true;
8803     }
8804     return isStartDream ? pictureFrameReady_ : pictureFrameBreak_;
8805 }
8806 } // namespace OHOS::Rosen
8807