• 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 <unordered_set>
25 #include "input_manager.h"
26 
27 #include <hitrace_meter.h>
28 #ifdef DEVICE_STATUS_ENABLE
29 #include <interaction_manager.h>
30 #endif // DEVICE_STATUS_ENABLE
31 #include <ipc_skeleton.h>
32 #include <parameter.h>
33 #include <parameters.h>
34 #include <privacy_kit.h>
35 #include <system_ability_definition.h>
36 #include <transaction/rs_interfaces.h>
37 #include <xcollie/watchdog.h>
38 #include <hisysevent.h>
39 #include <power_mgr_client.h>
40 #include <screen_power_utils.h>
41 
42 #include "dm_common.h"
43 #include "fold_screen_state_internel.h"
44 #ifdef WM_MULTI_SCREEN_ENABLE
45 #include "multi_screen_manager.h"
46 #include "multi_screen_power_change_manager.h"
47 #include "multi_screen_change_utils.h"
48 #endif
49 #include "pipeline/rs_node_map.h"
50 #include "rs_adapter.h"
51 #include "scene_board_judgement.h"
52 #include "session_permission.h"
53 #include "screen_scene_config.h"
54 #include "surface_capture_future.h"
55 #include "sys_cap_util.h"
56 #include "permission.h"
57 #include "window_manager_hilog.h"
58 #include "screen_rotation_property.h"
59 #include "screen_sensor_connector.h"
60 #include "screen_setting_helper.h"
61 #include "screen_session_dumper.h"
62 #include "mock_session_manager_service.h"
63 #include "connection/screen_snapshot_picker_connection.h"
64 #include "connection/screen_cast_connection.h"
65 #include "publish/screen_session_publish.h"
66 #include "dms_xcollie.h"
67 #include "screen_sensor_plugin.h"
68 #include "screen_cache.h"
69 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
70 #include <display_power_mgr_client.h>
71 #endif
72 #ifdef FOLD_ABILITY_ENABLE
73 #include "fold_screen_controller/super_fold_sensor_manager.h"
74 #include "fold_screen_controller/super_fold_state_manager.h"
75 #include "fold_screen_controller/secondary_fold_sensor_manager.h"
76 #include "fold_screen_controller/super_fold_policy.h"
77 #endif
78 #include "screen_aod_plugin.h"
79 
80 namespace OHOS::Rosen {
81 namespace {
82 const std::string SCREEN_SESSION_MANAGER_THREAD = "OS_ScreenSessionManager";
83 const std::string SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD = "OS_ScreenSessionManager_ScreenPower";
84 const std::string SCREEN_CAPTURE_PERMISSION = "ohos.permission.CAPTURE_SCREEN";
85 const std::string CUSTOM_SCREEN_CAPTURE_PERMISSION = "ohos.permission.CUSTOM_SCREEN_CAPTURE";
86 const std::string BOOTEVENT_BOOT_COMPLETED = "bootevent.boot.completed";
87 const std::string ACCESS_VIRTUAL_SCREEN_PERMISSION = "ohos.permission.ACCESS_VIRTUAL_SCREEN";
88 const std::string IS_PC_MODE_KEY = "persist.sceneboard.ispcmode";
89 const std::string PC_MODE_DPI_KEY = "pcModeDpi";
90 const int32_t CV_WAIT_SCREENON_MS = 300;
91 const int32_t CV_WAIT_SCREENOFF_MS = 1500;
92 const int32_t CV_WAIT_SCREENOFF_MS_MAX = 3000;
93 const int32_t CV_WAIT_SCBSWITCH_MS = 3000;
94 const int32_t CV_WAIT_USERSWITCH_MS = 3000;
95 #ifdef WM_MULTI_USR_ABILITY_ENABLE
96 const int64_t SWITCH_USER_DISPLAYMODE_CHANGE_DELAY = 500;
97 #endif
98 const int32_t SCREEN_OFF_MIN_DELAY_TIME = 300;
99 const int32_t SCREEN_WAIT_PICTURE_FRAME_TIME = 1500;
100 const std::string STATUS_FOLD_HALF = "-z";
101 const std::string STATUS_EXPAND = "-y";
102 const std::string STATUS_FOLD = "-p";
103 const std::string SETTING_LOCKED_KEY = "settings.general.accelerometer_rotation_status";
104 const ScreenId SCREEN_ID_DEFAULT = 0;
105 const ScreenId RS_ID_DEFAULT = 0;
106 const ScreenId SCREEN_ID_FULL = 0;
107 const ScreenId SCREEN_ID_MAIN = 5;
108 const ScreenId SCREEN_ID_PC_MAIN = 9;
109 const ScreenId MINIMUM_VIRTUAL_SCREEN_ID = 1000;
110 constexpr int32_t INVALID_UID = -1;
111 constexpr int32_t INVALID_USER_ID = -1;
112 constexpr int32_t INVALID_SCB_PID = -1;
113 constexpr int32_t BASE_USER_RANGE = 200000;
114 static bool g_foldScreenFlag = system::GetParameter("const.window.foldscreen.type", "") != "";
115 static const int32_t g_screenRotationOffSet = system::GetIntParameter<int32_t>("const.fold.screen_rotation.offset", 0);
116 static const int32_t ROTATION_90 = 1;
117 #ifdef FOLD_ABILITY_ENABLE
118 static const int32_t ROTATION_270 = 3;
119 constexpr int32_t REMOVE_DISPLAY_MODE = 0;
120 #endif
121 const unsigned int XCOLLIE_TIMEOUT_10S = 10;
122 constexpr int32_t CAST_WIRED_PROJECTION_START = 1005;
123 constexpr int32_t CAST_WIRED_PROJECTION_STOP = 1007;
124 constexpr int32_t RES_FAILURE_FOR_PRIVACY_WINDOW = -2;
125 constexpr int32_t IRREGULAR_REFRESH_RATE_SKIP_THRETHOLD = 10;
126 constexpr float EXTEND_SCREEN_DPI_DEFAULT_PARAMETER = 1.0f;
127 static const int32_t AUTO_ROTATE_OFF = 0;
128 static const int NOTIFY_EVENT_FOR_DUAL_FAILED = 0;
129 static const int NOTIFY_EVENT_FOR_DUAL_SUCESS = 1;
130 static const int NO_NEED_NOTIFY_EVENT_FOR_DUAL = 2;
131 static bool g_isPcDevice = false;
132 static float g_extendScreenDpiCoef = EXTEND_SCREEN_DPI_DEFAULT_PARAMETER;
133 static uint32_t g_internalWidth = 3120;
134 #ifdef WM_MULTI_SCREEN_CTL_ABILITY_ENABLE
135 constexpr uint32_t NUMBER_OF_PHYSICAL_SCREEN = 2;
136 constexpr bool ADD_VOTE = true;
137 constexpr bool REMOVE_VOTE = false;
138 constexpr uint32_t OLED_60_HZ = 60;
139 #endif
140 constexpr uint32_t FOUR_K_WIDTH = 3840;
141 constexpr uint32_t THREE_K_WIDTH = 3000;
142 constexpr uint32_t DISPLAY_B_HEIGHT = 1608;
143 
144 const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
145 constexpr int32_t FOLDABLE_DEVICE { 2 };
146 constexpr float DEFAULT_PIVOT = 0.5f;
147 constexpr float DEFAULT_SCALE = 1.0f;
148 constexpr float SECONDARY_ROTATION_90 = 90.0F;
149 constexpr float SECONDARY_ROTATION_270 = 270.0F;
150 static const constexpr char* SET_SETTING_DPI_KEY {"default_display_dpi"};
151 const std::vector<std::string> ROTATION_DEFAULT = {"0", "1", "2", "3"};
152 const std::vector<std::string> ORIENTATION_DEFAULT = {"0", "1", "2", "3"};
153 const uint32_t MAX_INTERVAL_US = 1800000000; // 30分钟
154 const int32_t MAP_SIZE = 300;
155 const std::string NO_EXIST_BUNDLE_MANE = "null";
156 ScreenCache<int32_t, std::string> g_uidVersionMap(MAP_SIZE, NO_EXIST_BUNDLE_MANE);
157 
158 const std::string SCREEN_UNKNOWN = "unknown";
159 
160 const int32_t SCREEN_SCAN_TYPE = system::GetIntParameter<int32_t>("const.window.screen.scan_type", 0);
161 constexpr int32_t SCAN_TYPE_VERTICAL = 1;
162 constexpr uint32_t ROTATION_MOD = 4;
163 // F state offset
164 constexpr uint32_t FULL_STATUS_OFFSET_X = 1136;
165 
166 #ifdef WM_MULTI_SCREEN_ENABLE
167 const ScreenId SCREEN_ID_OUTER_ONLY = 0;
168 const std::string SCREEN_EXTEND = "extend";
169 const std::string SCREEN_MIRROR = "mirror";
170 const std::string MULTI_SCREEN_EXIT_STR = "exit";
171 const std::string MULTI_SCREEN_ENTER_STR = "enter";
172 const int32_t CV_WAIT_SCREEN_MASK_MS = 1500;
173 #endif
174 const bool IS_COORDINATION_SUPPORT =
175     OHOS::system::GetBoolParameter("const.window.foldabledevice.is_coordination_support", false);
176 
177 const std::string FAULT_DESCRIPTION = "842003014";
178 const std::string FAULT_SUGGESTION = "542003014";
179 constexpr uint32_t COMMON_EVENT_SERVICE_ID = 3299;
180 const long GET_HDR_PIXELMAP_TIMEOUT = 2000;
181 const int32_t CV_WAIT_UPDATE_AVAILABLE_MS = 300;
182 
183 const static uint32_t PIXMAP_VECTOR_SIZE = 2;
184 static const uint32_t SDR_PIXMAP = 0;
185 const bool IS_SUPPORT_PC_MODE = system::GetBoolParameter("const.window.support_window_pcmode_switch", false);
186 const ScreenId SCREEN_GROUP_ID_DEFAULT = 1;
187 const std::string SCREEN_NAME_EXTEND = "ExtendedDisplay";
188 const std::string SCREEN_NAME_CAST = "CastEngine";
189 const std::set<std::string> INDIVIDUAL_SCREEN_GROUP_SET = {"CeliaView", "DevEcoViewer"};
190 
191 constexpr int32_t MAIN_STATUS_WIDTH_INDEX = 0;
192 constexpr int32_t FULL_STATUS_WIDTH_INDEX = 1;
193 constexpr int32_t GLOBAL_FULL_STATUS_WIDTH_INDEX = 2;
194 constexpr int32_t SCREEN_HEIGHT_INDEX = 3;
195 constexpr int32_t STATUS_PARAM_VALID_INDEX = 4;
196 constexpr uint32_t MAIN_STATUS_DEFAULT_WIDTH = 1008;
197 constexpr uint32_t SCREEN_DEFAULT_HEIGHT = 2232;
198 constexpr int32_t SECONDARY_FULL_OFFSET = 1136;
199 constexpr int32_t SECONDARY_FULL_STATUS_WIDTH = 2048;
200 
201 // based on the bundle_util
202 // LCOV_EXCL_START
GetUserIdByCallingUid()203 inline int32_t GetUserIdByCallingUid()
204 {
205     int32_t uid = IPCSkeleton::GetCallingUid();
206     TLOGD(WmsLogTag::WMS_MULTI_USER, "get calling uid(%{public}d)", uid);
207     if (uid <= INVALID_UID) {
208         TLOGE(WmsLogTag::WMS_MULTI_USER, "uid is illegal: %{public}d", uid);
209         return INVALID_USER_ID;
210     }
211     return uid / BASE_USER_RANGE;
212 }
213 // LCOV_EXCL_STOP
214 } // namespace
215 
216 WM_IMPLEMENT_SINGLE_INSTANCE(ScreenSessionManager)
217 
218 const bool REGISTER_RESULT = !SceneBoardJudgement::IsSceneBoardEnabled() ? false :
219     SystemAbility::MakeAndRegisterAbility(&ScreenSessionManager::GetInstance());
220 
ScreenSessionManager()221 ScreenSessionManager::ScreenSessionManager()
222     : SystemAbility(DISPLAY_MANAGER_SERVICE_SA_ID, true), rsInterface_(RSInterfaces::GetInstance())
223 {
224     screenEventTracker_.RecordEvent("Dms construct.");
225     LoadScreenSceneXml();
226     screenOffDelay_ = CV_WAIT_SCREENOFF_MS;
227     screenOnDelay_ = CV_WAIT_SCREENON_MS;
228     taskScheduler_ = std::make_shared<TaskScheduler>(SCREEN_SESSION_MANAGER_THREAD);
229     screenPowerTaskScheduler_ = std::make_shared<TaskScheduler>(SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD);
230     screenCutoutController_ = new (std::nothrow) ScreenCutoutController();
231     if (!screenCutoutController_) {
232         TLOGE(WmsLogTag::DMS, "screenCutoutController_ is nullptr");
233         return;
234     }
235     sessionDisplayPowerController_ = new SessionDisplayPowerController(
236         std::bind(&ScreenSessionManager::NotifyDisplayStateChange, this,
237             std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
238     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
239         g_foldScreenFlag = false;
240     }
241     if (g_foldScreenFlag) {
242         HandleFoldScreenPowerInit();
243     }
244     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
245         InitSecondaryDisplayPhysicalParams();
246     }
247     WatchParameter(BOOTEVENT_BOOT_COMPLETED.c_str(), BootFinishedCallback, this);
248 }
249 
SortByScreenId(const ScreenId & screenIdA,const ScreenId & screenIdB)250 bool SortByScreenId(const ScreenId& screenIdA, const ScreenId& screenIdB)
251 {
252     return static_cast<int32_t>(screenIdA) < static_cast<int32_t>(screenIdB);
253 }
254 
GetPcStatus() const255 bool ScreenSessionManager::GetPcStatus() const
256 {
257     std::lock_guard<std::mutex> lock(setPcStatusMutex_);
258     return g_isPcDevice;
259 }
260 
SetPcStatus(bool isPc)261 void ScreenSessionManager::SetPcStatus(bool isPc) {
262     std::lock_guard<std::mutex> lock(setPcStatusMutex_);
263     g_isPcDevice = isPc;
264 }
265 
266 // LCOV_EXCL_START
ConvertOffsetToCorrectRotation(int32_t phyOffset)267 ScreenRotation ScreenSessionManager::ConvertOffsetToCorrectRotation(int32_t phyOffset)
268 {
269     ScreenRotation offsetRotation = ScreenRotation::ROTATION_0;
270     switch (phyOffset) {
271         case 90: // Rotation 90 degree
272             offsetRotation = ScreenRotation::ROTATION_270;
273             break;
274         case 180: // Rotation 180 degree
275             offsetRotation = ScreenRotation::ROTATION_180;
276             break;
277         case 270: // Rotation 270 degree
278             offsetRotation = ScreenRotation::ROTATION_90;
279             break;
280         default:
281             offsetRotation = ScreenRotation::ROTATION_0;
282             break;
283     }
284     return offsetRotation;
285 }
286 
ConvertIntToRotation(int32_t rotation)287 Rotation ScreenSessionManager::ConvertIntToRotation(int32_t rotation)
288 {
289     Rotation targetRotation = Rotation::ROTATION_0;
290     switch (rotation) {
291         case 90:
292             targetRotation = Rotation::ROTATION_90;
293             break;
294         case 180:
295             targetRotation = Rotation::ROTATION_180;
296             break;
297         case 270:
298             targetRotation = Rotation::ROTATION_270;
299             break;
300         default:
301             targetRotation = Rotation::ROTATION_0;
302             break;
303     }
304     return targetRotation;
305 }
306 
HandleFoldScreenPowerInit()307 void ScreenSessionManager::HandleFoldScreenPowerInit()
308 {
309 #ifdef FOLD_ABILITY_ENABLE
310     TLOGI(WmsLogTag::DMS, "Enter");
311     foldScreenController_ = new (std::nothrow) FoldScreenController(displayInfoMutex_, screenPowerTaskScheduler_);
312     if (!foldScreenController_) {
313         TLOGE(WmsLogTag::DMS, "foldScreenController_ is nullptr");
314         return;
315     }
316     foldScreenController_->SetOnBootAnimation(true);
317     if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
318         SetFoldScreenPowerInit([&]() {
319             foldScreenController_->BootAnimationFinishPowerInit();
320             FixPowerStatus();
321             foldScreenController_->SetOnBootAnimation(false);
322             RegisterApplicationStateObserver();
323         });
324     } else {
325         // 后续其他设备rs上电规格将陆续迁移到BootAnimationFinishPowerInit中
326         FoldScreenPowerInit();
327     }
328 #endif
329 }
330 
IsSupportCoordination()331 bool ScreenSessionManager::IsSupportCoordination()
332 {
333     return !FoldScreenStateInternel::IsDualDisplayFoldDevice() || IS_COORDINATION_SUPPORT;
334 }
335 
FoldScreenPowerInit()336 void ScreenSessionManager::FoldScreenPowerInit()
337 {
338 #ifdef FOLD_ABILITY_ENABLE
339     SetFoldScreenPowerInit([&]() {
340         int64_t timeStamp = 50;
341 #ifdef TP_FEATURE_ENABLE
342         int32_t tpType = 12;
343         std::string fullTpChange = "0";
344         std::string mainTpChange = "1";
345 #endif
346         if (!foldScreenController_) {
347             TLOGE(WmsLogTag::DMS, "foldScreenController_ is nullptr");
348             return;
349         }
350         foldScreenController_->SetIsClearingBootAnimation(true);
351         ScreenId currentScreenId = foldScreenController_->GetCurrentScreenId();
352         if (currentScreenId == SCREEN_ID_FULL) {
353             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Full animation Init 1.");
354             SetRSScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF_FAKE);
355             if (IsSupportCoordination()) {
356                 SetRSScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
357             }
358             std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
359             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Full animation Init 2.");
360 #ifdef TP_FEATURE_ENABLE
361             rsInterface_.SetTpFeatureConfig(tpType, fullTpChange.c_str());
362 #endif
363             SetRSScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
364             foldScreenController_->AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, REMOVE_DISPLAY_MODE);
365             SetRSScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
366         } else if (currentScreenId == SCREEN_ID_MAIN) {
367             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Main animation Init 3.");
368             SetRSScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF_FAKE);
369             if (IsSupportCoordination()) {
370                 SetRSScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
371             }
372             std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
373             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Main animation Init 4.");
374 #ifdef TP_FEATURE_ENABLE
375             rsInterface_.SetTpFeatureConfig(tpType, mainTpChange.c_str());
376 #endif
377             SetRSScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
378             foldScreenController_->AddOrRemoveDisplayNodeToTree(SCREEN_ID_FULL, REMOVE_DISPLAY_MODE);
379             SetRSScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
380         } else {
381             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Init, invalid active screen id");
382         }
383         FixPowerStatus();
384         foldScreenController_->SetIsClearingBootAnimation(false);
385         foldScreenController_->SetOnBootAnimation(false);
386         RegisterApplicationStateObserver();
387     });
388 #endif
389 }
390 
FixPowerStatus()391 void ScreenSessionManager::FixPowerStatus()
392 {
393     if (!PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
394         PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
395         TLOGI(WmsLogTag::DMS, "Fix Screen Power State");
396     }
397 }
398 
Init()399 void ScreenSessionManager::Init()
400 {
401     if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none" ||
402         system::GetBoolParameter(IS_PC_MODE_KEY, false)) {
403         g_isPcDevice = true;
404     }
405     if (system::GetParameter("soc.boot.mode", "") != "rescue") {
406         uint64_t interval = g_isPcDevice ? 10 * 1000 : 5 * 1000; // 10 second for PC
407         if (HiviewDFX::Watchdog::GetInstance().AddThread(
408             SCREEN_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
409             TLOGW(WmsLogTag::DMS, "Add thread %{public}s to watchdog failed.", SCREEN_SESSION_MANAGER_THREAD.c_str());
410         }
411 
412         if (HiviewDFX::Watchdog::GetInstance().AddThread(
413             SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD, screenPowerTaskScheduler_->GetEventHandler(), interval)) {
414             TLOGW(WmsLogTag::DMS, "Add thread %{public}s to watchdog failed.",
415                 SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD.c_str());
416         }
417     } else {
418         TLOGI(WmsLogTag::DMS, "Dms in rescue mode, not need watchdog.");
419         screenEventTracker_.RecordEvent("Dms in rescue mode, not need watchdog.");
420     }
421 
422     auto stringConfig = ScreenSceneConfig::GetStringConfig();
423     if (stringConfig.count("defaultDisplayCutoutPath") != 0) {
424         std::string defaultDisplayCutoutPath = static_cast<std::string>(stringConfig["defaultDisplayCutoutPath"]);
425         TLOGD(WmsLogTag::DMS, "defaultDisplayCutoutPath = %{public}s.", defaultDisplayCutoutPath.c_str());
426         ScreenSceneConfig::SetCutoutSvgPath(GetDefaultScreenId(), defaultDisplayCutoutPath);
427     }
428 
429     if (!LoadMotionSensor()) {
430         screenEventTracker_.RecordEvent("Dms load motion plugin failed.");
431         TLOGW(WmsLogTag::DMS, "load motion plugin failed.");
432     }
433 
434     if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() ||
435         FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
436         if (!LoadAodLib()) {
437             TLOGE(WmsLogTag::DMS, "load aod lib failed");
438         }
439     }
440 
441     RegisterScreenChangeListener();
442     if(FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
443         RegisterFoldNotSwitchingListener();
444     }
445     if (!ScreenSceneConfig::IsSupportRotateWithSensor()) {
446         TLOGI(WmsLogTag::DMS, "Current type not support SetSensorSubscriptionEnabled.");
447     } else if (GetScreenPower(SCREEN_ID_FULL) == ScreenPowerState::POWER_ON) {
448         // 多屏设备只要有屏幕亮,GetScreenPower获取的任意一块屏幕状态均是ON
449         SetSensorSubscriptionEnabled();
450         screenEventTracker_.RecordEvent("Dms subscribed to sensor successfully.");
451     }
452 
453     // publish init
454     ScreenSessionPublish::GetInstance().InitPublishEvents();
455     screenEventTracker_.RecordEvent("Dms init end.");
456 }
457 
OnStart()458 void ScreenSessionManager::OnStart()
459 {
460     TLOGI(WmsLogTag::DMS, "start");
461     DmsXcollie dmsXcollie("DMS:OnStart", XCOLLIE_TIMEOUT_10S,
462         [this](void *) { screenEventTracker_.LogWarningAllInfos(); });
463     Init();
464     sptr<ScreenSessionManager> dms(this);
465     dms->IncStrongRef(nullptr);
466     if (!Publish(dms)) {
467         TLOGE(WmsLogTag::DMS, "Publish DMS failed");
468         return;
469     }
470     TLOGI(WmsLogTag::DMS, "DMS SA AddSystemAbilityListener");
471     (void)AddSystemAbilityListener(SENSOR_SERVICE_ABILITY_ID);
472     (void)AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
473     (void)AddSystemAbilityListener(MULTIMODAL_INPUT_SERVICE_ID);
474     screenEventTracker_.RecordEvent("Dms AddSystemAbilityListener finished.");
475     TLOGI(WmsLogTag::DMS, "end");
476     screenEventTracker_.RecordEvent("Dms onstart end.");
477 }
478 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)479 void ScreenSessionManager::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
480 {
481     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "OnAddSystemAbility: %d", systemAbilityId);
482     TLOGI(WmsLogTag::DMS, "receive sa add:%{public}d", systemAbilityId);
483     if (systemAbilityId == MULTIMODAL_INPUT_SERVICE_ID) {
484         if (!g_isPcDevice) {
485             TLOGI(WmsLogTag::DMS, "current device is not pc");
486             return;
487         }
488         SwitchSubscriberInit();
489         TLOGI(WmsLogTag::DMS, " SwitchSubscriber finished.");
490     }
491     if (systemAbilityId == SENSOR_SERVICE_ABILITY_ID) {
492 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
493         if (!g_foldScreenFlag) {
494             TLOGI(WmsLogTag::DMS, "current device is not fold phone.");
495             return;
496         }
497         if (!foldScreenController_ || isFoldScreenOuterScreenReady_) {
498             TLOGI(WmsLogTag::DMS, "foldScreenController_ is null or outer screen is not ready.");
499             return;
500         }
501         if (GetDisplayState(foldScreenController_->GetCurrentScreenId()) == DisplayState::ON) {
502             if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
503                 SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
504             } else {
505                 FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
506             }
507             TLOGI(WmsLogTag::DMS, "Recover Posture sensor finished");
508         }
509 
510         if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
511             SecondaryFoldSensorManager::GetInstance().RegisterHallCallback();
512         } else {
513             FoldScreenSensorManager::GetInstance().RegisterHallCallback();
514         }
515         TLOGI(WmsLogTag::DMS, "Recover Hall sensor finished");
516         screenEventTracker_.RecordEvent("Dms recover Posture and Hall sensor finished.");
517 #endif
518     } else if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
519         auto task = []() {
520             ScreenSessionPublish::GetInstance().RegisterLowTempSubscriber();
521             ScreenSessionPublish::GetInstance().RegisterUserSwitchedSubscriber();
522         };
523         taskScheduler_->PostAsyncTask(task, "RegisterCommonEventSubscriber");
524     }
525 }
526 
CheckDisplayMangerAgentTypeAndPermission(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)527 DMError ScreenSessionManager::CheckDisplayMangerAgentTypeAndPermission(
528     const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
529 {
530     if ((type == DisplayManagerAgentType::SCREEN_EVENT_LISTENER ||
531         type == DisplayManagerAgentType::PRIVATE_WINDOW_LISTENER) &&
532         !SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
533         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
534             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
535         return DMError::DM_ERROR_NOT_SYSTEM_APP;
536     }
537 
538     if ((displayManagerAgent == nullptr) || (displayManagerAgent->AsObject() == nullptr)) {
539         TLOGE(WmsLogTag::DMS, "displayManagerAgent invalid");
540         return DMError::DM_ERROR_NULLPTR;
541     }
542     return DMError::DM_OK;
543 }
544 
RegisterDisplayManagerAgent(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)545 DMError ScreenSessionManager::RegisterDisplayManagerAgent(
546     const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
547 {
548     TLOGI(WmsLogTag::DMS, " called type: %{public}u", type);
549     DmsXcollie dmsXcollie("DMS:RegisterDisplayManagerAgent", XCOLLIE_TIMEOUT_10S);
550     DMError ret;
551 
552     ret = CheckDisplayMangerAgentTypeAndPermission(displayManagerAgent, type);
553     if (ret != DMError::DM_OK) {
554         TLOGE(WmsLogTag::DMS, "call CheckDisplayMangerAgentTypeAndPermission fail!");
555         return ret;
556     }
557 
558     if (type < DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER
559         || type >= DisplayManagerAgentType::DISPLAY_MANAGER_MAX_AGENT_TYPE) {
560         TLOGE(WmsLogTag::DMS, "DisplayManagerAgentType: %{public}u", static_cast<uint32_t>(type));
561         return DMError::DM_ERROR_INVALID_PARAM;
562     }
563     return dmAgentContainer_.RegisterAgent(displayManagerAgent, type) ? DMError::DM_OK :DMError::DM_ERROR_NULLPTR;
564 }
565 
UnregisterDisplayManagerAgent(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)566 DMError ScreenSessionManager::UnregisterDisplayManagerAgent(
567     const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
568 {
569     TLOGI(WmsLogTag::DMS, " called type: %{public}u", type);
570     DMError ret;
571 
572     ret = CheckDisplayMangerAgentTypeAndPermission(displayManagerAgent, type);
573     if (ret != DMError::DM_OK) {
574         TLOGE(WmsLogTag::DMS, "call CheckDisplayMangerAgentTypeAndPermission fail!");
575         return ret;
576     }
577     return dmAgentContainer_.UnregisterAgent(displayManagerAgent, type) ? DMError::DM_OK :DMError::DM_ERROR_NULLPTR;
578 }
579 // LCOV_EXCL_STOP
580 
LoadScreenSceneXml()581 void ScreenSessionManager::LoadScreenSceneXml()
582 {
583     if (ScreenSceneConfig::LoadConfigXml()) {
584         ScreenSceneConfig::DumpConfig();
585         ConfigureScreenScene();
586     }
587 }
588 
ConfigureScreenScene()589 void ScreenSessionManager::ConfigureScreenScene()
590 {
591     auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
592     auto enableConfig = ScreenSceneConfig::GetEnableConfig();
593     auto stringConfig = ScreenSceneConfig::GetStringConfig();
594     ConfigureDpi();
595     if (numbersConfig.count("defaultDeviceRotationOffset") != 0) {
596         defaultDeviceRotationOffset_ = static_cast<uint32_t>(numbersConfig["defaultDeviceRotationOffset"][0]);
597         TLOGD(WmsLogTag::DMS, "defaultDeviceRotationOffset = %{public}u", defaultDeviceRotationOffset_);
598     }
599     if (enableConfig.count("isWaterfallDisplay") != 0) {
600         bool isWaterfallDisplay = static_cast<bool>(enableConfig["isWaterfallDisplay"]);
601         TLOGD(WmsLogTag::DMS, "isWaterfallDisplay = %{public}d", isWaterfallDisplay);
602     }
603     if (numbersConfig.count("curvedScreenBoundary") != 0) {
604         std::vector<int> vtBoundary = static_cast<std::vector<int>>(numbersConfig["curvedScreenBoundary"]);
605         TLOGD(WmsLogTag::DMS, "vtBoundary.size=%{public}u", static_cast<uint32_t>(vtBoundary.size()));
606     }
607     if (stringConfig.count("subDisplayCutoutPath") != 0) {
608         std::string subDisplayCutoutPath = stringConfig["subDisplayCutoutPath"];
609         TLOGD(WmsLogTag::DMS, "subDisplayCutoutPath = %{public}s.", subDisplayCutoutPath.c_str());
610         ScreenSceneConfig::SetSubCutoutSvgPath(subDisplayCutoutPath);
611     }
612     if (stringConfig.count("rotationPolicy") != 0) {
613         std::string rotationPolicy = stringConfig["rotationPolicy"];
614         TLOGD(WmsLogTag::DMS, "rotationPolicy = %{public}s.", rotationPolicy.c_str());
615         deviceScreenConfig_.rotationPolicy_ = rotationPolicy;
616     }
617     if (stringConfig.count("defaultRotationPolicy") != 0) {
618         std::string defaultRotationPolicy = stringConfig["defaultRotationPolicy"];
619         TLOGD(WmsLogTag::DMS, "defaultRotationPolicy = %{public}s.", defaultRotationPolicy.c_str());
620         deviceScreenConfig_.defaultRotationPolicy_ = defaultRotationPolicy;
621     }
622     if (enableConfig.count("isRightPowerButton") != 0) {
623         bool isRightPowerButton = static_cast<bool>(enableConfig["isRightPowerButton"]);
624         TLOGD(WmsLogTag::DMS, "isRightPowerButton = %{public}d", isRightPowerButton);
625         deviceScreenConfig_.isRightPowerButton_ = isRightPowerButton;
626     }
627     ConfigureWaterfallDisplayCompressionParams();
628     ConfigureCastParams();
629 
630     if (numbersConfig.count("buildInDefaultOrientation") != 0) {
631         Orientation orientation = static_cast<Orientation>(numbersConfig["buildInDefaultOrientation"][0]);
632         TLOGD(WmsLogTag::DMS, "orientation = %{public}d", orientation);
633     }
634     {
635         std::lock_guard<std::mutex> lock(allDisplayPhysicalResolutionMutex_);
636         allDisplayPhysicalResolution_ = ScreenSceneConfig::GetAllDisplayPhysicalConfig();
637     }
638 }
639 
ConfigureDpi()640 void ScreenSessionManager::ConfigureDpi()
641 {
642     auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
643     if (numbersConfig.count("dpi") != 0) {
644         uint32_t densityDpi = static_cast<uint32_t>(numbersConfig["dpi"][0]);
645         TLOGI(WmsLogTag::DMS, "densityDpi = %{public}u", densityDpi);
646         if (densityDpi >= DOT_PER_INCH_MINIMUM_VALUE && densityDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
647             isDensityDpiLoad_ = true;
648             defaultDpi = densityDpi;
649             cachedSettingDpi_ = defaultDpi;
650             densityDpi_ = static_cast<float>(densityDpi) / BASELINE_DENSITY;
651         }
652     }
653     if (numbersConfig.count("subDpi") != 0) {
654         uint32_t subDensityDpi = static_cast<uint32_t>(numbersConfig["subDpi"][0]);
655         TLOGI(WmsLogTag::DMS, "subDensityDpi = %{public}u", subDensityDpi);
656         if (subDensityDpi >= DOT_PER_INCH_MINIMUM_VALUE && subDensityDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
657             isDensityDpiLoad_ = true;
658             subDensityDpi_ = static_cast<float>(subDensityDpi) / BASELINE_DENSITY;
659         }
660     }
661     const bool isPcMode = system::GetBoolParameter(IS_PC_MODE_KEY, false);
662     if (isPcMode && numbersConfig.count(PC_MODE_DPI_KEY) != 0 && numbersConfig[PC_MODE_DPI_KEY].size() > 0) {
663         uint32_t pcModeDpi = static_cast<uint32_t>(numbersConfig[PC_MODE_DPI_KEY][0]);
664         if (pcModeDpi >= DOT_PER_INCH_MINIMUM_VALUE && pcModeDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
665             pcModeDpi_ = pcModeDpi;
666             isDensityDpiLoad_ = true;
667             defaultDpi = pcModeDpi_;
668             cachedSettingDpi_ = defaultDpi;
669             densityDpi_ = static_cast<float>(pcModeDpi_) / BASELINE_DENSITY;
670         }
671         TLOGI(WmsLogTag::DMS, "config pcmode densityDpi: %{public}f", densityDpi_);
672     }
673 }
674 
ConfigureCastParams()675 void ScreenSessionManager::ConfigureCastParams()
676 {
677     auto stringConfig = ScreenSceneConfig::GetStringConfig();
678     if (stringConfig.count("castBundleName") == 0) {
679         TLOGE(WmsLogTag::DMS, "not find cast bundleName in config xml");
680         return;
681     }
682     std::string castBundleName = static_cast<std::string>(stringConfig["castBundleName"]);
683     TLOGD(WmsLogTag::DMS, "castBundleName = %{public}s", castBundleName.c_str());
684     ScreenCastConnection::GetInstance().SetBundleName(castBundleName);
685     if (stringConfig.count("castAbilityName") == 0) {
686         TLOGE(WmsLogTag::DMS, "not find cast ability in config xml");
687         return;
688     }
689     std::string castAbilityName = static_cast<std::string>(stringConfig["castAbilityName"]);
690     TLOGD(WmsLogTag::DMS, "castAbilityName = %{public}s", castAbilityName.c_str());
691     ScreenCastConnection::GetInstance().SetAbilityName(castAbilityName);
692 }
693 
ConfigureWaterfallDisplayCompressionParams()694 void ScreenSessionManager::ConfigureWaterfallDisplayCompressionParams()
695 {
696     auto enableConfig = ScreenSceneConfig::GetEnableConfig();
697     if (enableConfig.count("isWaterfallAreaCompressionEnableWhenHorizontal") != 0) {
698         bool enable = static_cast<bool>(enableConfig["isWaterfallAreaCompressionEnableWhenHorizontal"]);
699         TLOGD(WmsLogTag::DMS, "isWaterfallAreaCompressionEnableWhenHorizontal=%{public}d.", enable);
700     }
701     ScreenSceneConfig::SetCurvedCompressionAreaInLandscape();
702 }
703 
704 // LCOV_EXCL_START
ConfigureScreenSnapshotParams()705 void ScreenSessionManager::ConfigureScreenSnapshotParams()
706 {
707     auto stringConfig = ScreenSceneConfig::GetStringConfig();
708     if (stringConfig.count("screenSnapshotBundleName") == 0) {
709         TLOGE(WmsLogTag::DMS, "not find screen snapshot bundleName in config xml");
710         return;
711     }
712     std::string screenSnapshotBundleName = static_cast<std::string>(stringConfig["screenSnapshotBundleName"]);
713     TLOGD(WmsLogTag::DMS, "screenSnapshotBundleName = %{public}s.", screenSnapshotBundleName.c_str());
714     ScreenSnapshotPickerConnection::GetInstance().SetBundleName(screenSnapshotBundleName);
715     if (stringConfig.count("screenSnapshotAbilityName") == 0) {
716         TLOGE(WmsLogTag::DMS, "not find screen snapshot ability in config xml");
717         return;
718     }
719     std::string screenSnapshotAbilityName = static_cast<std::string>(stringConfig["screenSnapshotAbilityName"]);
720     TLOGD(WmsLogTag::DMS, "screenSnapshotAbilityName = %{public}s.", screenSnapshotAbilityName.c_str());
721     ScreenSnapshotPickerConnection::GetInstance().SetAbilityName(screenSnapshotAbilityName);
722 }
723 // LCOV_EXCL_STOP
724 
RegisterScreenChangeListener()725 void ScreenSessionManager::RegisterScreenChangeListener()
726 {
727     TLOGI(WmsLogTag::DMS, "start");
728     auto res = rsInterface_.SetScreenChangeCallback(
729         [this](ScreenId screenId, ScreenEvent screenEvent, ScreenChangeReason reason) {
730             OnScreenChange(screenId, screenEvent, reason);
731         });
732     if (res != StatusCode::SUCCESS) {
733         auto task = [this]() { RegisterScreenChangeListener(); };
734         taskScheduler_->PostAsyncTask(task, "RegisterScreenChangeListener", 50);  // Retry after 50 ms.
735         screenEventTracker_.RecordEvent("Dms OnScreenChange register failed.");
736     } else {
737         screenEventTracker_.RecordEvent("Dms OnScreenChange register success.");
738     }
739 }
740 
RegisterFoldNotSwitchingListener()741 void ScreenSessionManager::RegisterFoldNotSwitchingListener()
742 {
743     TLOGI(WmsLogTag::DMS, "start");
744     auto res = rsInterface_.SetScreenSwitchingNotifyCallback(
745         [this](bool isSwitching) {
746             OnFoldStatusChange(isSwitching);
747         });
748     if (res != StatusCode::SUCCESS) {
749         auto task = [this]() { RegisterFoldNotSwitchingListener(); };
750         taskScheduler_->PostAsyncTask(task, "RegisterFoldNotSwitchingListener", 50);  // Retry after 50 ms.
751         screenEventTracker_.RecordEvent("Dms fold not switching register failed.");
752     } else {
753         screenEventTracker_.RecordEvent("Dms fold not switching register success.");
754     }
755 }
756 
ReportFoldDisplayTime(uint64_t screenId,int64_t rsFirstFrameTime)757 void ScreenSessionManager::ReportFoldDisplayTime(uint64_t screenId, int64_t rsFirstFrameTime)
758 {
759 #ifdef FOLD_ABILITY_ENABLE
760     TLOGI(WmsLogTag::DMS, "[UL_FOLD]ReportFoldDisplayTime rsFirstFrameTime: %{public}" PRId64
761         ", screenId: %{public}" PRIu64, rsFirstFrameTime, screenId);
762     if (foldScreenController_ != nullptr && foldScreenController_->GetIsFirstFrameCommitReported() == false) {
763         int64_t foldStartTime = foldScreenController_->GetStartTimePoint().time_since_epoch().count();
764         int32_t ret = HiSysEventWrite(
765             OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
766             "DISPLAY_MODE",
767             OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
768             "FOLD_TIME", rsFirstFrameTime - foldStartTime);
769         foldScreenController_->SetIsFirstFrameCommitReported(true);
770         if (ret != 0) {
771             TLOGE(WmsLogTag::DMS, "[UL_FOLD]ReportFoldDisplayTime Write HiSysEvent error, ret: %{public}d", ret);
772         }
773     }
774 #endif
775 }
776 
RegisterFirstFrameCommitCallback()777 void ScreenSessionManager::RegisterFirstFrameCommitCallback()
778 {
779     TLOGI(WmsLogTag::DMS, "[UL_FOLD]RegisterFirstFrameCommitCallback start");
780     auto callback = [=](uint64_t screenId, int64_t rsFirstFrameTime) {
781         ReportFoldDisplayTime(screenId, rsFirstFrameTime);
782     };
783     RSInterfaces::GetInstance().RegisterFirstFrameCommitCallback(callback);
784 }
785 
RegisterRefreshRateChangeListener()786 void ScreenSessionManager::RegisterRefreshRateChangeListener()
787 {
788     static bool isRegisterRefreshRateListener = false;
789     // LCOV_EXCL_START
790     if (!isRegisterRefreshRateListener) {
791         TLOGW(WmsLogTag::DMS, "call rsInterface_ RegisterHgmRefreshRateUpdateCallback");
792         auto res = rsInterface_.RegisterHgmRefreshRateUpdateCallback(
793             [this](uint32_t refreshRate) { OnHgmRefreshRateChange(refreshRate); });
794         TLOGW(WmsLogTag::DMS, "call rsInterface_ RegisterHgmRefreshRateUpdateCallback end");
795         if (res != StatusCode::SUCCESS) {
796             TLOGE(WmsLogTag::DMS, "failed");
797             screenEventTracker_.RecordEvent("Dms RefreshRateChange register failed.");
798         } else {
799             isRegisterRefreshRateListener = true;
800             screenEventTracker_.RecordEvent("Dms RefreshRateChange register success.");
801         }
802     }
803     // LCOV_EXCL_STOP
804 }
805 
OnVirtualScreenChange(ScreenId screenId,ScreenEvent screenEvent)806 void ScreenSessionManager::OnVirtualScreenChange(ScreenId screenId, ScreenEvent screenEvent)
807 {
808     TLOGI(WmsLogTag::DMS, "Notify scb virtual screen change, ScreenId: %{public}" PRIu64 ", ScreenEvent: %{public}d",
809         screenId, static_cast<int>(screenEvent));
810     auto screenSession = GetScreenSession(screenId);
811     if (!screenSession) {
812         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
813         return;
814     }
815     if (screenEvent == ScreenEvent::CONNECTED) {
816         auto clientProxy = GetClientProxy();
817         TLOGI(WmsLogTag::DMS, "screenCombination:%{public}d, screenName:%{public}s",
818             screenSession->GetScreenCombination(), screenSession->GetName().c_str());
819         if(screenSession->GetScreenCombination() == ScreenCombination::SCREEN_UNIQUE &&
820             INDIVIDUAL_SCREEN_GROUP_SET.find(screenSession->GetName()) != INDIVIDUAL_SCREEN_GROUP_SET.end()) {
821             screenSession->SetDisplayGroupId(displayGroupNum_++);
822             screenSession->SetMainDisplayIdOfGroup(screenId);
823         } else {
824             // Unique screens outside of INDIVIDUAL_SCREEN_GROUP_SET are placed in the default group.
825             screenSession->SetDisplayGroupId(DISPLAY_GROUP_ID_DEFAULT);
826             screenSession->SetMainDisplayIdOfGroup(MAIN_SCREEN_ID_DEFAULT);
827         }
828         if (clientProxy) {
829             clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId),
830                 ScreenEvent::CONNECTED);
831         }
832         return;
833     }
834     if (screenEvent == ScreenEvent::DISCONNECTED) {
835         std::map<int32_t, sptr<IScreenSessionManagerClient>> clientProxyMap;
836         {
837             std::lock_guard<std::mutex> lock(clientProxyMutex_);
838             clientProxyMap = clientProxyMap_;
839         }
840         for (const auto& [userId, clientProxy] : clientProxyMap) {
841             if (clientProxy) {
842                 clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId),
843                     ScreenEvent::DISCONNECTED);
844             }
845         }
846     }
847 }
848 
849 // LCOV_EXCL_START
IsDefaultMirrorMode(ScreenId screenId)850 bool ScreenSessionManager::IsDefaultMirrorMode(ScreenId screenId)
851 {
852     if (screenId != SCREEN_ID_MAIN && screenId != SCREEN_ID_FULL && screenId != SCREEN_ID_PC_MAIN) {
853         return true;
854     }
855     return false;
856 }
857 
FreeDisplayMirrorNodeInner(const sptr<ScreenSession> mirrorSession)858 void ScreenSessionManager::FreeDisplayMirrorNodeInner(const sptr<ScreenSession> mirrorSession)
859 {
860     if (mirrorSession == nullptr) {
861         return;
862     }
863     {
864         std::shared_ptr<RSDisplayNode> displayNode = mirrorSession->GetDisplayNode();
865         if (displayNode == nullptr) {
866             return;
867         }
868         if (!g_isPcDevice) {
869             hdmiScreenCount_ = hdmiScreenCount_ > 0 ? hdmiScreenCount_ - 1 : 0;
870             NotifyCaptureStatusChanged();
871         }
872         displayNode->RemoveFromTree();
873         mirrorSession->ReleaseDisplayNode();
874         displayNode = nullptr;
875     }
876     TLOGI(WmsLogTag::DMS, "free displayNode");
877     RSTransactionAdapter::FlushImplicitTransaction(mirrorSession->GetRSUIContext());
878 }
879 
SetScreenCorrection()880 void ScreenSessionManager::SetScreenCorrection()
881 {
882     std::ostringstream oss;
883     if (g_foldScreenFlag) {
884         if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
885             auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_MAIN,
886                 static_cast<ScreenRotation>(ROTATION_90));
887             oss << "main screenRotationOffSet: " << g_screenRotationOffSet << " ret value: " << ret;
888         } else {
889             auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_FULL,
890                 static_cast<ScreenRotation>(g_screenRotationOffSet));
891             oss << "full screenRotationOffSet: " << g_screenRotationOffSet << " ret value: " << ret;
892         }
893     } else {
894         std::vector<std::string> phyOffsets = FoldScreenStateInternel::GetPhyRotationOffset();
895         int32_t phyOffset = static_cast<int32_t>(std::stoi(phyOffsets[0]));
896         ScreenRotation correctRotation = ConvertOffsetToCorrectRotation(phyOffset);
897         auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_DEFAULT, correctRotation);
898         oss << "phyOffset: " << phyOffset << " correctRotation value: " <<
899             static_cast<int32_t>(correctRotation) << " ret value: " << ret;
900     }
901     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
902     screenEventTracker_.RecordEvent(oss.str());
903 }
904 
AdaptSuperHorizonalBoot(sptr<ScreenSession> screenSession,ScreenId screenId)905 void ScreenSessionManager::AdaptSuperHorizonalBoot(sptr<ScreenSession> screenSession, ScreenId screenId)
906 {
907     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && screenSession->isInternal_) {
908         auto screenMode = rsInterface_.GetScreenActiveMode(screenId);
909         int32_t screenWidth = screenMode.GetScreenWidth();
910         int32_t screenHeight = screenMode.GetScreenHeight();
911         RRect screenBounds = RRect({ 0, 0, screenHeight, screenWidth }, 0.0f, 0.0f);
912         screenSession->SetBounds(screenBounds);
913         screenSession->SetHorizontalRotation();
914         screenSession->SetValidWidth(screenHeight);
915         screenSession->SetValidHeight(screenWidth);
916     }
917 }
918 
OnScreenChange(ScreenId screenId,ScreenEvent screenEvent,ScreenChangeReason reason)919 void ScreenSessionManager::OnScreenChange(ScreenId screenId, ScreenEvent screenEvent, ScreenChangeReason reason)
920 {
921     if (reason == ScreenChangeReason::HWCDEAD) {
922         NotifyAbnormalScreenConnectChange(screenId);
923         TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " ScreenChangeReason: %{public}d",
924             screenId, static_cast<int>(reason));
925         return;
926     }
927     if (g_isPcDevice) {
928         OnScreenChangeForPC(screenId, screenEvent, reason);
929     } else {
930         OnScreenChangeDefault(screenId, screenEvent, reason);
931     }
932 }
933 
OnScreenChangeForPC(ScreenId screenId,ScreenEvent screenEvent,ScreenChangeReason reason)934 void ScreenSessionManager::OnScreenChangeForPC(ScreenId screenId, ScreenEvent screenEvent, ScreenChangeReason reason)
935 {
936     std::lock_guard<std::mutex> lock(screenChangeMutex_);
937     std::ostringstream oss;
938     oss << "OnScreenChange triggered. screenId: " << static_cast<int32_t>(screenId)
939         << "  screenEvent: " << static_cast<int32_t>(screenEvent);
940     screenEventTracker_.RecordEvent(oss.str());
941     TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " screenEvent: %{public}d",
942         screenId, static_cast<int>(screenEvent));
943     SetScreenCorrection();
944     auto screenSession = GetOrCreateScreenSession(screenId);
945     if (!screenSession) {
946         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
947         return;
948     }
949     AdaptSuperHorizonalBoot(screenSession, screenId);
950     if (g_isPcDevice) {
951         auto physicalScreenSession = GetOrCreatePhysicalScreenSession(screenId);
952         if (!physicalScreenSession) {
953             TLOGE(WmsLogTag::DMS, "physicalScreenSession is nullptr");
954             return;
955         }
956         AdaptSuperHorizonalBoot(physicalScreenSession, screenId);
957     }
958     OnFoldScreenChange(screenSession);
959     if (screenEvent == ScreenEvent::CONNECTED) {
960         connectScreenNumber_ ++;
961         DestroyExtendVirtualScreen();
962         HandleScreenConnectEvent(screenSession, screenId, screenEvent);
963     } else if (screenEvent == ScreenEvent::DISCONNECTED) {
964         connectScreenNumber_ --;
965         HandleScreenDisconnectEvent(screenSession, screenId, screenEvent);
966     } else {
967         TLOGE(WmsLogTag::DMS, "screenEvent error!");
968     }
969     NotifyScreenModeChange();
970 }
971 
OnScreenChangeDefault(ScreenId screenId,ScreenEvent screenEvent,ScreenChangeReason reason)972 void ScreenSessionManager::OnScreenChangeDefault(ScreenId screenId, ScreenEvent screenEvent, ScreenChangeReason reason)
973 {
974     std::ostringstream oss;
975     oss << "OnScreenChange triggered. screenId: " << static_cast<int32_t>(screenId)
976         << "  screenEvent: " << static_cast<int32_t>(screenEvent);
977     screenEventTracker_.RecordEvent(oss.str());
978     TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " screenEvent: %{public}d",
979         screenId, static_cast<int>(screenEvent));
980     SetScreenCorrection();
981     auto screenSession = GetOrCreateScreenSession(screenId);
982     if (!screenSession) {
983         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
984         return;
985     }
986     if (g_isPcDevice) {
987         auto physicalScreenSession = GetOrCreatePhysicalScreenSession(screenId);
988         if (!physicalScreenSession) {
989             TLOGE(WmsLogTag::DMS, "physicalScreenSession is nullptr");
990             return;
991         }
992     }
993     OnFoldScreenChange(screenSession);
994     if (screenEvent == ScreenEvent::CONNECTED) {
995         connectScreenNumber_ ++;
996         HandleScreenConnectEvent(screenSession, screenId, screenEvent);
997     } else if (screenEvent == ScreenEvent::DISCONNECTED) {
998         connectScreenNumber_ --;
999         HandleScreenDisconnectEvent(screenSession, screenId, screenEvent);
1000     } else {
1001         TLOGE(WmsLogTag::DMS, "screenEvent error!");
1002     }
1003     NotifyScreenModeChange();
1004 }
1005 
OnFoldScreenChange(sptr<ScreenSession> & screenSession)1006 void ScreenSessionManager::OnFoldScreenChange(sptr<ScreenSession>& screenSession)
1007 {
1008 #ifdef FOLD_ABILITY_ENABLE
1009     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1010         SuperFoldSensorManager::GetInstance().SetTaskScheduler(screenPowerTaskScheduler_);
1011         SuperFoldSensorManager::GetInstance().RegisterPostureCallback();
1012         SuperFoldSensorManager::GetInstance().RegisterHallCallback();
1013         SetSensorSubscriptionEnabled();
1014         screenEventTracker_.RecordEvent("Dms subscribed to sensor successfully.");
1015     }
1016 
1017     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
1018         SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
1019         SecondaryFoldSensorManager::GetInstance().RegisterHallCallback();
1020         SetSensorSubscriptionEnabled();
1021         screenEventTracker_.RecordEvent("secondary device: Dms subscribed to sensor successfully.");
1022     }
1023 
1024     if (foldScreenController_ != nullptr) {
1025         RegisterFirstFrameCommitCallback();
1026         screenSession->SetFoldScreen(true);
1027     }
1028 #endif
1029 }
1030 
OnFoldStatusChange(bool isSwitching)1031 void ScreenSessionManager::OnFoldStatusChange(bool isSwitching)
1032 {
1033 #ifdef FOLD_ABILITY_ENABLE
1034     if (foldScreenController_ == nullptr) {
1035         TLOGE(WmsLogTag::DMS, "fold screen controller is not initialized.");
1036         return;
1037     }
1038     if (!isSwitching) {
1039         TLOGI(WmsLogTag::DMS, "receive switching end.");
1040         foldScreenController_->SetdisplayModeChangeStatus(false);
1041     }
1042 #endif
1043 }
1044 
DestroyExtendVirtualScreen()1045 void ScreenSessionManager::DestroyExtendVirtualScreen()
1046 {
1047     TLOGI(WmsLogTag::DMS, "start");
1048     std::map<ScreenId, sptr<ScreenSession>> screenSessionMap;
1049     {
1050         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1051         screenSessionMap = screenSessionMap_;
1052     }
1053     for (auto sessionIt : screenSessionMap) {
1054         sptr<ScreenSession> screenSession = sessionIt.second;
1055         if (screenSession == nullptr) {
1056             TLOGE(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64,
1057                 sessionIt.first);
1058             continue;
1059         }
1060         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL &&
1061             screenSession->GetIsExtendVirtual()) {
1062             DestroyVirtualScreen(screenSession->GetScreenId());
1063             TLOGI(WmsLogTag::DMS, "destory screenId: %{public}" PRIu64, screenSession->GetScreenId());
1064         }
1065     }
1066 }
1067 
NotifyScreenModeChange(ScreenId disconnectedScreenId)1068 void ScreenSessionManager::NotifyScreenModeChange(ScreenId disconnectedScreenId)
1069 {
1070     TLOGI(WmsLogTag::DMS, "NotifyScreenModeChange start");
1071     auto task = [=] {
1072         auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER);
1073         if (agents.empty()) {
1074             TLOGNE(WmsLogTag::DMS, "NotifyScreenModeChange agent is null");
1075             return;
1076         }
1077         std::vector<sptr<ScreenInfo>> screenInfos;
1078         std::vector<ScreenId> screenIds = GetAllScreenIds();
1079         for (auto screenId : screenIds) {
1080             if (disconnectedScreenId == screenId) {
1081                 continue;
1082             }
1083             TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64, screenId);
1084             auto screenSession = GetScreenSession(screenId);
1085             screenInfos.emplace_back(screenSession->ConvertToScreenInfo());
1086         }
1087         for (auto& agent : agents) {
1088             int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
1089             if (!IsFreezed(agentPid, DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER)) {
1090                 agent->NotifyScreenModeChange(screenInfos);
1091             }
1092         }
1093     };
1094     taskScheduler_->PostAsyncTask(task, "NotifyScreenModeChange");
1095 }
1096 
NotifyAbnormalScreenConnectChange(ScreenId screenId)1097 void ScreenSessionManager::NotifyAbnormalScreenConnectChange(ScreenId screenId)
1098 {
1099     auto agents = dmAgentContainer_.GetAgentsByType(
1100         DisplayManagerAgentType::ABNORMAL_SCREEN_CONNECT_CHANGE_LISTENER);
1101     if (agents.empty()) {
1102         TLOGE(WmsLogTag::DMS, "agents is empty");
1103         return;
1104     }
1105     for (auto& agent : agents) {
1106         agent->NotifyAbnormalScreenConnectChange(screenId);
1107     }
1108 }
1109 
SendCastEvent(const bool & isPlugIn)1110 void ScreenSessionManager::SendCastEvent(const bool &isPlugIn)
1111 {
1112     TLOGI(WmsLogTag::DMS, "isPlugIn:%{public}d", isPlugIn);
1113     if (!ScreenCastConnection::GetInstance().CastConnectExtension(static_cast<int32_t>(isPlugIn))) {
1114         TLOGE(WmsLogTag::DMS, "CastConnectionExtension failed");
1115         return;
1116     }
1117     if (!ScreenCastConnection::GetInstance().IsConnectedSync()) {
1118         TLOGE(WmsLogTag::DMS, "CastConnectionExtension connected failed");
1119         ScreenCastConnection::GetInstance().CastDisconnectExtension();
1120         return;
1121     }
1122     MessageParcel data;
1123     MessageParcel reply;
1124     if (isPlugIn) {
1125         ScreenCastConnection::GetInstance().SendMessageToCastService(CAST_WIRED_PROJECTION_START, data, reply);
1126     } else {
1127         ScreenCastConnection::GetInstance().SendMessageToCastService(CAST_WIRED_PROJECTION_STOP, data, reply);
1128     }
1129     ScreenCastConnection::GetInstance().CastDisconnectExtension();
1130 }
1131 
NotifyCastWhenScreenConnectChange(bool isConnected)1132 void ScreenSessionManager::NotifyCastWhenScreenConnectChange(bool isConnected)
1133 {
1134     if (g_isPcDevice) {
1135         TLOGI(WmsLogTag::DMS, "pc device");
1136         return;
1137     }
1138     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1139         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
1140             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1141         return;
1142     }
1143     if (isConnected) {
1144         auto task = [this]() {
1145             SendCastEvent(true);
1146             ScreenSessionPublish::GetInstance().PublishCastPlugInEvent();
1147         };
1148         taskScheduler_->PostAsyncTask(task, "SendCastEventTrue");
1149         TLOGI(WmsLogTag::DMS, "PostAsyncTask SendCastEventTrue");
1150     } else {
1151         auto task = [this]() {
1152             SendCastEvent(false);
1153             ScreenSessionPublish::GetInstance().PublishCastPlugOutEvent();
1154         };
1155         taskScheduler_->PostAsyncTask(task, "SendCastEventFalse");
1156         TLOGI(WmsLogTag::DMS, "PostAsyncTask SendCastEventFalse");
1157     }
1158 }
1159 
PhyMirrorConnectWakeupScreen()1160 void ScreenSessionManager::PhyMirrorConnectWakeupScreen()
1161 {
1162 #ifdef WM_MULTI_SCREEN_ENABLE
1163     if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "mirror") {
1164         TLOGI(WmsLogTag::DMS, "Connect to an external screen to wakeup the phone screen");
1165         FixPowerStatus();
1166     }
1167 #endif
1168 }
1169 
GetIsCurrentInUseById(ScreenId screenId)1170 bool ScreenSessionManager::GetIsCurrentInUseById(ScreenId screenId)
1171 {
1172     auto session = GetScreenSession(screenId);
1173     if (session == nullptr) {
1174         TLOGE(WmsLogTag::DMS, "session not found");
1175         return false;
1176     }
1177     if (!session->GetIsCurrentInUse()) {
1178         TLOGE(WmsLogTag::DMS, "session not in use");
1179         return false;
1180     }
1181     return true;
1182 }
1183 
SetMultiScreenDefaultRelativePosition()1184 void ScreenSessionManager::SetMultiScreenDefaultRelativePosition()
1185 {
1186 #ifdef WM_MULTI_SCREEN_ENABLE
1187     MultiScreenPositionOptions mainOptions;
1188     MultiScreenPositionOptions extendOptions;
1189     sptr<ScreenSession> mainSession = nullptr;
1190     sptr<ScreenSession> extendSession = nullptr;
1191     {
1192         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1193         for (auto sessionIt : screenSessionMap_) {
1194             auto screenSession = sessionIt.second;
1195             if (screenSession == nullptr) {
1196                 TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64,
1197                     sessionIt.first);
1198                 continue;
1199             }
1200             if (screenSession->GetIsRealScreen()) {
1201                 if (screenSession->GetIsExtend() && extendSession == nullptr) {
1202                     extendSession = screenSession;
1203                 } else {
1204                     mainSession = screenSession;
1205                 }
1206             }
1207         }
1208     }
1209     if (extendSession != nullptr && mainSession != nullptr) {
1210         ScreenProperty mainProperty = mainSession->GetScreenProperty();
1211         int32_t mainWidth = mainProperty.GetBounds().rect_.GetWidth();
1212         if (g_isPcDevice) {
1213             mainOptions = { mainSession->GetRSScreenId(), 0, 0 };
1214             extendOptions = { extendSession->GetRSScreenId(), mainWidth, 0 };
1215         } else {
1216             mainOptions = { mainSession->GetScreenId(), 0, 0 };
1217             extendOptions = { extendSession->GetScreenId(), mainWidth, 0 };
1218         }
1219         auto ret = SetMultiScreenRelativePosition(mainOptions, extendOptions);
1220         if (ret != DMError::DM_OK) {
1221             TLOGE(WmsLogTag::DMS, "set Relative Position failed, DMError:%{public}d", static_cast<int32_t>(ret));
1222         }
1223     }
1224 #endif
1225 }
1226 
GetAndMergeEdidInfo(sptr<ScreenSession> screenSession)1227 void ScreenSessionManager::GetAndMergeEdidInfo(sptr<ScreenSession> screenSession)
1228 {
1229     ScreenId screenId = screenSession->GetScreenId();
1230     struct BaseEdid edid;
1231     int32_t fillInfo = 4;
1232     if (!GetEdid(screenId, edid)) {
1233         TLOGE(WmsLogTag::DMS, "get EDID failed.");
1234         return;
1235     }
1236     std::string serialNumber = ConvertEdidToString(edid);
1237     TLOGI(WmsLogTag::DMS, "serialNumber: %{public}s", serialNumber.c_str());
1238     screenSession->SetSerialNumber(serialNumber);
1239     if (g_isPcDevice) {
1240         if (!edid.displayProductName_.empty()) {
1241             screenSession->SetName(edid.displayProductName_);
1242         } else {
1243             std::string productCodeStr;
1244             std::string connector = "-";
1245             std::ostringstream oss;
1246             oss << std::hex << std::uppercase << std::setw(fillInfo) << std::setfill('0') << edid.productCode_;
1247             productCodeStr = oss.str();
1248             screenSession->SetName(edid.manufacturerName_ + connector + productCodeStr);
1249         }
1250     }
1251 }
1252 
ConvertEdidToString(const struct BaseEdid edid)1253 std::string ScreenSessionManager::ConvertEdidToString(const struct BaseEdid edid)
1254 {
1255     std::string edidInfo = edid.manufacturerName_ + std::to_string(edid.productCode_)
1256         + std::to_string(edid.serialNumber_) + std::to_string(edid.weekOfManufactureOrModelYearFlag_)
1257         + std::to_string(edid.yearOfManufactureOrModelYear_);
1258     TLOGI(WmsLogTag::DMS, "edidInfo: %{public}s", edidInfo.c_str());
1259     std::hash<std::string> hasher;
1260     std::size_t hashValue = hasher(edidInfo);
1261     std::ostringstream oss;
1262     oss << std::hex << std::uppercase << hashValue;
1263     return oss.str();
1264 }
1265 
DisconnectScreenIfScreenInfoNull(sptr<ScreenSession> & screenSession)1266 void ScreenSessionManager::DisconnectScreenIfScreenInfoNull(sptr<ScreenSession>& screenSession)
1267 {
1268 #ifdef FOLD_ABILITY_ENABLE
1269    if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1270         TLOGI(WmsLogTag::DMS, "not superFoldDisplayDevice");
1271         return;
1272    }
1273    auto clientProxy = GetClientProxy();
1274    if (!clientProxy) {
1275         TLOGE(WmsLogTag::DMS, "clientProxy is null");
1276         return;
1277    }
1278    if (screenSession == nullptr) {
1279         TLOGE(WmsLogTag::DMS, "screenSession is null");
1280         return;
1281     }
1282     if (IsDefaultMirrorMode(screenSession->GetRSScreenId()) &&
1283         screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
1284         clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenSession->GetRSScreenId()),
1285                                                ScreenEvent::DISCONNECTED);
1286     }
1287 #endif
1288 }
1289 
RecoverRestoredMultiScreenMode(sptr<ScreenSession> screenSession)1290 bool ScreenSessionManager::RecoverRestoredMultiScreenMode(sptr<ScreenSession> screenSession)
1291 {
1292 #ifdef WM_MULTI_SCREEN_ENABLE
1293     if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL) {
1294         TLOGI(WmsLogTag::DMS, "not real screen, return before recover.");
1295         return true;
1296     }
1297     std::map<std::string, MultiScreenInfo> multiScreenInfoMap = ScreenSettingHelper::GetMultiScreenInfo();
1298     std::string serialNumber = screenSession->GetSerialNumber();
1299     if (!CheckMultiScreenInfoMap(multiScreenInfoMap, serialNumber)) {
1300         DisconnectScreenIfScreenInfoNull(screenSession);
1301         return false;
1302     }
1303     auto info = multiScreenInfoMap[serialNumber];
1304     if (info.outerOnly) {
1305         SetIsOuterOnlyMode(true);
1306         MultiScreenModeChange(SCREEN_ID_OUTER_ONLY, SCREEN_ID_OUTER_ONLY, "off");
1307         return true;
1308     }
1309     sptr<ScreenSession> internalSession = GetInternalScreenSession();
1310     if (internalSession == nullptr) {
1311         TLOGE(WmsLogTag::DMS, "internalSession is nullptr");
1312         return false;
1313     }
1314     if (info.isExtendMain) {
1315         TLOGI(WmsLogTag::DMS, "extend screen is main");
1316         info.mainScreenOption.screenId_ = screenSession->GetRSScreenId();
1317         info.secondaryScreenOption.screenId_ = internalSession->GetRSScreenId();
1318     } else {
1319         TLOGI(WmsLogTag::DMS, "extend screen is not main");
1320         info.mainScreenOption.screenId_ = internalSession->GetRSScreenId();
1321         info.secondaryScreenOption.screenId_ = screenSession->GetRSScreenId();
1322     }
1323     if (info.multiScreenMode == MultiScreenMode::SCREEN_MIRROR) {
1324         SetMultiScreenMode(info.mainScreenOption.screenId_, info.secondaryScreenOption.screenId_, info.multiScreenMode);
1325         TLOGW(WmsLogTag::DMS, "mirror, return befor OnScreenConnectionChanged");
1326         ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_MIRROR);
1327         return true;
1328     }
1329     SetMultiScreenMode(info.mainScreenOption.screenId_, info.secondaryScreenOption.screenId_, info.multiScreenMode);
1330     auto ret = SetMultiScreenRelativePosition(info.mainScreenOption, info.secondaryScreenOption);
1331     if (ret != DMError::DM_OK) {
1332         SetMultiScreenDefaultRelativePosition();
1333     }
1334     ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_EXTEND);
1335     return true;
1336 #else
1337     return false;
1338 #endif
1339 }
1340 
CheckMultiScreenInfoMap(std::map<std::string,MultiScreenInfo> multiScreenInfoMap,const std::string & serialNumber)1341 bool ScreenSessionManager::CheckMultiScreenInfoMap(std::map<std::string, MultiScreenInfo> multiScreenInfoMap,
1342     const std::string& serialNumber)
1343 {
1344     if (multiScreenInfoMap.empty()) {
1345         TLOGE(WmsLogTag::DMS, "no restored screen, use default mode!");
1346         return false;
1347     }
1348     if (serialNumber.size() == 0) {
1349         TLOGE(WmsLogTag::DMS, "serialNumber empty!");
1350         return false;
1351     }
1352     if (multiScreenInfoMap.find(serialNumber) == multiScreenInfoMap.end()) {
1353         TLOGE(WmsLogTag::DMS, "screen not found, use default mode!");
1354         return false;
1355     }
1356     return true;
1357 }
1358 
ReportHandleScreenEvent(ScreenEvent screenEvent,ScreenCombination screenCombination)1359 void ScreenSessionManager::ReportHandleScreenEvent(ScreenEvent screenEvent, ScreenCombination screenCombination)
1360 {
1361     MultiScreenMode multiScreenMode;
1362     if (screenCombination == ScreenCombination::SCREEN_EXTEND) {
1363         multiScreenMode = MultiScreenMode::SCREEN_EXTEND;
1364     } else {
1365         multiScreenMode = MultiScreenMode::SCREEN_MIRROR;
1366     }
1367     int32_t ret = HiSysEventWrite(
1368         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
1369         "EXTEND_DISPLAY_PLUG_IN_AND_OUT",
1370         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
1371         "PLUG_IN_AND_OUT", static_cast<int32_t>(screenEvent),
1372         "DISPLAY_CONNECT_NUM", connectScreenNumber_,
1373         "DISPLAY_INUSED_NUM", GetCurrentInUseScreenNumber(),
1374         "EXTENSION_DISPLAY_MODE_STATUS", static_cast<int32_t>(multiScreenMode),
1375         "MAIN_DISPLAY_ID", GetInternalScreenId());
1376     if (ret != 0) {
1377         TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d", ret);
1378     }
1379 }
1380 
GetCurrentInUseScreenNumber()1381 int32_t ScreenSessionManager::GetCurrentInUseScreenNumber()
1382 {
1383     int32_t inUseScreenNumber_ = 0;
1384     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1385     for (auto sessionIt : screenSessionMap_) {
1386         auto screenSession = sessionIt.second;
1387         if (screenSession == nullptr) {
1388             TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
1389             continue;
1390         }
1391         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
1392             screenSession->GetIsCurrentInUse()) {
1393             TLOGI(WmsLogTag::DMS, "found screenId = %{public}" PRIu64, sessionIt.first);
1394             inUseScreenNumber_++;
1395         }
1396     }
1397     return inUseScreenNumber_;
1398 }
1399 
SetCastPrivacyToRS(sptr<ScreenSession> screenSession,bool enable)1400 bool ScreenSessionManager::SetCastPrivacyToRS(sptr<ScreenSession> screenSession, bool enable)
1401 {
1402     bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId());
1403     if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL || !phyMirrorEnable) {
1404         TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"",
1405             screenSession->GetScreenId());
1406         return false;
1407     }
1408     ScreenId rsScreenId = INVALID_SCREEN_ID;
1409     if (!screenIdManager_.ConvertToRsScreenId(screenSession->GetScreenId(), rsScreenId) ||
1410         rsScreenId == INVALID_SCREEN_ID) {
1411         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
1412         return false;
1413     }
1414     rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, enable);
1415     return true;
1416 }
1417 
SetCastPrivacyFromSettingData()1418 void ScreenSessionManager::SetCastPrivacyFromSettingData()
1419 {
1420     bool enable = true;
1421     bool isOK = ScreenSettingHelper::GetSettingCast(enable);
1422     TLOGI(WmsLogTag::DMS, "get setting cast done, isOK: %{public}u, enable: %{public}u", isOK, enable);
1423     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1424     for (const auto& sessionIt : screenSessionMap_) {
1425         auto screenSession = sessionIt.second;
1426         if (screenSession == nullptr) {
1427             TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first);
1428             continue;
1429         }
1430         bool isSuc = SetCastPrivacyToRS(screenSession, enable);
1431         TLOGI(WmsLogTag::DMS, "set cast privacy done, isSuc:%{public}d, enable:%{public}d, screenId:%{public}" PRIu64"",
1432             isSuc, enable, sessionIt.first);
1433     }
1434 }
1435 
RegisterSettingWireCastObserver(sptr<ScreenSession> & screenSession)1436 void ScreenSessionManager::RegisterSettingWireCastObserver(sptr<ScreenSession>& screenSession)
1437 {
1438     if (screenSession == nullptr) {
1439         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
1440         return;
1441     }
1442     bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId());
1443     if (!g_isPcDevice && phyMirrorEnable && screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL) {
1444         TLOGI(WmsLogTag::DMS, "Register Setting wire cast Observer");
1445         SettingObserver::UpdateFunc updateFunc = [this](const std::string& key) { SetCastPrivacyFromSettingData(); };
1446         ScreenSettingHelper::RegisterSettingWireCastObserver(updateFunc);
1447     }
1448 }
1449 
UnregisterSettingWireCastObserver(ScreenId screenId)1450 void ScreenSessionManager::UnregisterSettingWireCastObserver(ScreenId screenId)
1451 {
1452     if (g_isPcDevice) {
1453         return;
1454     }
1455     {
1456         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1457         for (const auto& sessionIt : screenSessionMap_) {
1458             auto screenSession = sessionIt.second;
1459             if (screenSession == nullptr) {
1460                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first);
1461                 continue;
1462             }
1463             bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId());
1464             if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL || !phyMirrorEnable) {
1465                 TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"", sessionIt.first);
1466                 continue;
1467             }
1468             if (screenSession ->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR &&
1469                 screenSession->GetScreenId() != screenId) {
1470                 return;
1471             }
1472         }
1473     }
1474     ScreenSettingHelper::UnregisterSettingWireCastObserver();
1475     TLOGI(WmsLogTag::DMS, "unregister Setting wire cast Observer");
1476 }
1477 
SwitchSubscriberInit()1478 void ScreenSessionManager::SwitchSubscriberInit()
1479 {
1480     switchId_ = MMI::InputManager::GetInstance()->SubscribeSwitchEvent(
1481         [this](std::shared_ptr<OHOS::MMI::SwitchEvent> switchEvent) {
1482             if (switchEvent->GetSwitchValue() == MMI::SwitchEvent::SWITCH_OFF) {
1483                 SetLapTopLidOpenStatus(false);
1484             } else {
1485                 SetLapTopLidOpenStatus(true);
1486             }
1487         }
1488     );
1489     TLOGD(WmsLogTag::DMS, "switchId is: %{public}d", switchId_);
1490 }
1491 
IsLapTopLidOpen() const1492 bool ScreenSessionManager::IsLapTopLidOpen() const
1493 {
1494     return isLapTopLidOpen_.load();
1495 }
1496 
SetLapTopLidOpenStatus(bool isLapTopLidOpen)1497 void ScreenSessionManager::SetLapTopLidOpenStatus(bool isLapTopLidOpen)
1498 {
1499     isLapTopLidOpen_.store(isLapTopLidOpen);
1500     TLOGI(WmsLogTag::DMS, "isLapTopLidOpen is: %{public}d", static_cast<int32_t>(isLapTopLidOpen));
1501 }
1502 
HandleScreenConnectEvent(sptr<ScreenSession> screenSession,ScreenId screenId,ScreenEvent screenEvent)1503 void ScreenSessionManager::HandleScreenConnectEvent(sptr<ScreenSession> screenSession,
1504     ScreenId screenId, ScreenEvent screenEvent)
1505 {
1506     bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
1507     HandlePhysicalMirrorConnect(screenSession, phyMirrorEnable);
1508     auto clientProxy = GetClientProxy();
1509 #ifdef FOLD_ABILITY_ENABLE
1510     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1511         SuperFoldStateManager::GetInstance().RefreshExternalRegion();
1512     }
1513     if (foldScreenController_ != nullptr) {
1514         if ((screenId == 0 || (screenId == SCREEN_ID_MAIN && isCoordinationFlag_ == true)) && clientProxy) {
1515             TLOGW(WmsLogTag::DMS, "event: connect %{public}" PRIu64 ", %{public}" PRIu64 ", "
1516                 "name=%{public}s", screenId, screenSession->GetRSScreenId(), screenSession->GetName().c_str());
1517             clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1518         }
1519         return;
1520     }
1521 #endif
1522     if (clientProxy && g_isPcDevice) {
1523         {
1524             std::unique_lock<std::mutex> lock(displayAddMutex_);
1525             needWaitAvailableArea_ = true;
1526         }
1527         clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1528         sptr<ScreenSession> internalSession = GetInternalScreenSession();
1529         if (!RecoverRestoredMultiScreenMode(screenSession)) {
1530             SetMultiScreenDefaultRelativePosition();
1531             ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_EXTEND);
1532         }
1533         sptr<ScreenSession> newInternalSession = GetInternalScreenSession();
1534         if (newInternalSession != nullptr && internalSession != nullptr &&
1535             internalSession->GetScreenId() != newInternalSession->GetScreenId()) {
1536             TLOGW(WmsLogTag::DMS, "main screen changed, reset screenSession.");
1537             screenSession = internalSession;
1538         }
1539         SetExtendedScreenFallbackPlan(screenSession->GetScreenId());
1540     }
1541     if (clientProxy && !g_isPcDevice && !phyMirrorEnable) {
1542         TLOGW(WmsLogTag::DMS, "screen connect and notify to scb.");
1543         clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1544     }
1545     if (phyMirrorEnable) {
1546         NotifyScreenConnected(screenSession->ConvertToScreenInfo());
1547         // when display add, need wait update available area, ensure display info is accurate
1548         WaitUpdateAvailableAreaForPc();
1549         NotifyDisplayCreate(screenSession->ConvertToDisplayInfo());
1550     }
1551     TLOGW(WmsLogTag::DMS, "connect end. ScreenId: %{public}" PRIu64, screenId);
1552 }
1553 
WaitUpdateAvailableAreaForPc()1554 void ScreenSessionManager::WaitUpdateAvailableAreaForPc()
1555 {
1556     std::unique_lock<std::mutex> lock(displayAddMutex_);
1557     TLOGI(WmsLogTag::DMS, "begin wait notify display. need wait: %{public}d", needWaitAvailableArea_);
1558     if (g_isPcDevice && needWaitAvailableArea_) {
1559         TLOGI(WmsLogTag::DMS, "need wait update available area");
1560         if (displayAddCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_UPDATE_AVAILABLE_MS)) ==
1561             std::cv_status::timeout) {
1562             TLOGE(WmsLogTag::DMS, "wait update available area timeout");
1563             needWaitAvailableArea_ = false;
1564         }
1565     }
1566 }
1567 
HandleScreenDisconnectEvent(sptr<ScreenSession> screenSession,ScreenId screenId,ScreenEvent screenEvent)1568 void ScreenSessionManager::HandleScreenDisconnectEvent(sptr<ScreenSession> screenSession,
1569     ScreenId screenId, ScreenEvent screenEvent)
1570 {
1571     if (!screenSession) {
1572        TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
1573        return;
1574     }
1575     RemoveScreenCastInfo(screenId);
1576     if (g_isPcDevice) {
1577         ScreenId rsId = screenSession->GetRSScreenId();
1578         if (screenId != rsId && screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL) {
1579             screenSession = GetScreenSessionByRsId(screenId);
1580             if (!screenSession) {
1581                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, rsid: %{public}" PRIu64, rsId);
1582                 return;
1583             }
1584         }
1585     }
1586     HandlePCScreenDisconnect(screenSession);
1587     bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
1588     HandlePhysicalMirrorDisconnect(screenSession, screenId, phyMirrorEnable);
1589     auto clientProxy = GetClientProxy();
1590     if (clientProxy) {
1591         TLOGW(WmsLogTag::DMS, "screen disconnect and notify to scb.");
1592         clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), ScreenEvent::DISCONNECTED);
1593     }
1594 #ifdef WM_MULTI_SCREEN_ENABLE
1595     HandleExtendScreenDisconnect(screenId);
1596 #endif
1597     HandleMapWhenScreenDisconnect(screenId);
1598     if (g_isPcDevice) {
1599         ScreenCombination screenCombination = screenSession->GetScreenCombination();
1600         ReportHandleScreenEvent(ScreenEvent::DISCONNECTED, screenCombination);
1601         SetMultiScreenFrameControl();
1602     }
1603     if (!(screenId == SCREEN_ID_MAIN && isCoordinationFlag_ == true)) {
1604         std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
1605         phyScreenPropMap_.erase(screenId);
1606     }
1607     if (phyMirrorEnable) {
1608         NotifyScreenDisconnected(screenSession->GetScreenId());
1609         NotifyDisplayDestroy(screenSession->GetScreenId());
1610         isPhyScreenConnected_ = false;
1611     }
1612     if (!g_isPcDevice && phyMirrorEnable) {
1613         UnregisterSettingWireCastObserver(screenId);
1614     }
1615     TLOGW(WmsLogTag::DMS, "disconnect success. ScreenId: %{public}" PRIu64 "", screenId);
1616 }
1617 
HandlePhysicalMirrorConnect(sptr<ScreenSession> screenSession,bool phyMirrorEnable)1618 void ScreenSessionManager::HandlePhysicalMirrorConnect(sptr<ScreenSession> screenSession, bool phyMirrorEnable)
1619 {
1620     if (phyMirrorEnable) {
1621         PhyMirrorConnectWakeupScreen();
1622         NotifyCastWhenScreenConnectChange(true);
1623         isPhyScreenConnected_ = true;
1624         RegisterSettingWireCastObserver(screenSession);
1625         if (!g_isPcDevice) {
1626             ScreenPowerUtils::EnablePowerForceTimingOut();
1627             DisablePowerOffRenderControl(0);
1628         }
1629     }
1630 }
1631 
HandlePhysicalMirrorDisconnect(sptr<ScreenSession> screenSession,ScreenId screenId,bool phyMirrorEnable)1632 void ScreenSessionManager::HandlePhysicalMirrorDisconnect(sptr<ScreenSession> screenSession, ScreenId screenId,
1633     bool phyMirrorEnable)
1634 {
1635     if (phyMirrorEnable) {
1636         NotifyCastWhenScreenConnectChange(false);
1637         FreeDisplayMirrorNodeInner(screenSession);
1638         isPhyScreenConnected_ = false;
1639         if (!g_isPcDevice) {
1640             std::vector<ScreenId> screenIdsToExclude = { screenId };
1641             if (!HasCastEngineOrPhyMirror(screenIdsToExclude)) {
1642                 ScreenPowerUtils::DisablePowerForceTimingOut();
1643                 ScreenPowerUtils::LightAndLockScreen("light and lock screen");
1644             }
1645         }
1646     }
1647 }
1648 
HandleMapWhenScreenDisconnect(ScreenId screenId)1649 void ScreenSessionManager::HandleMapWhenScreenDisconnect(ScreenId screenId)
1650 {
1651     {
1652         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1653         screenSessionMap_.erase(screenId);
1654     }
1655     {
1656         std::lock_guard<std::recursive_mutex> lock(physicalScreenSessionMapMutex_);
1657         physicalScreenSessionMap_.erase(screenId);
1658     }
1659 }
1660 
HandlePCScreenDisconnect(sptr<ScreenSession> & screenSession)1661 void ScreenSessionManager::HandlePCScreenDisconnect(sptr<ScreenSession>& screenSession)
1662 {
1663 #ifdef WM_MULTI_SCREEN_ENABLE
1664     ScreenCombination screenCombination = screenSession->GetScreenCombination();
1665     if (!g_isPcDevice) {
1666         TLOGE(WmsLogTag::DMS, "not PC device, return before process.");
1667         return;
1668     }
1669     if (screenCombination == ScreenCombination::SCREEN_MAIN) {
1670         TLOGW(WmsLogTag::DMS, "reset to inner screen to main.");
1671         HandleMainScreenDisconnect(screenSession);
1672     }
1673     screenCombination = screenSession->GetScreenCombination();
1674     if (screenCombination == ScreenCombination::SCREEN_EXTEND) {
1675         MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_EXIT_STR);
1676     } else {
1677         MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_MIRROR, MULTI_SCREEN_EXIT_STR);
1678         NotifyCaptureStatusChanged(false);
1679     }
1680     MultiScreenPositionOptions defaultOptions = { GetDefaultScreenId(), 0, 0 };
1681     SetRelativePositionForDisconnect(defaultOptions);
1682 #endif
1683 }
1684 
HandleMainScreenDisconnect(sptr<ScreenSession> & screenSession)1685 void ScreenSessionManager::HandleMainScreenDisconnect(sptr<ScreenSession>& screenSession)
1686 {
1687 #ifdef WM_MULTI_SCREEN_ENABLE
1688     if (!g_isPcDevice) {
1689         TLOGE(WmsLogTag::DMS, "not PC device, return before process.");
1690         return;
1691     }
1692     sptr<ScreenSession> internalSession = GetInternalScreenSession();
1693     if (internalSession == nullptr) {
1694         TLOGE(WmsLogTag::DMS, "internalSession is nullptr");
1695         return;
1696     }
1697     if (GetIsOuterOnlyMode()) {
1698         TLOGI(WmsLogTag::DMS, "exit outer only mode.");
1699         SetIsOuterOnlyMode(false);
1700         ExitOuterOnlyMode(internalSession->GetRSScreenId(), screenSession->GetRSScreenId(),
1701             MultiScreenMode::SCREEN_MIRROR);
1702     } else {
1703         SetIsOuterOnlyMode(false);
1704         MultiScreenModeChange(internalSession->GetRSScreenId(), screenSession->GetRSScreenId(),
1705             SCREEN_MIRROR);
1706     }
1707     if (screenSession->GetScreenId() == screenSession->GetRSScreenId()) {
1708         TLOGW(WmsLogTag::DMS, "main screen changed, reset screenSession.");
1709         screenSession = internalSession;
1710     } else {
1711         if (!screenSession->GetIsInternal() && screenSession->GetIsCurrentInUse()) {
1712             TLOGW(WmsLogTag::DMS, "main screen not changed, reset internal session.");
1713             sptr<ScreenSession> newInternalSession = GetInternalScreenSession();
1714             ResetInternalScreenSession(newInternalSession, screenSession);
1715             screenSession = newInternalSession;
1716         }
1717     }
1718 #endif
1719 }
1720 
ResetInternalScreenSession(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)1721 void ScreenSessionManager::ResetInternalScreenSession(sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
1722 {
1723 #ifdef WM_MULTI_SCREEN_ENABLE
1724     if (innerScreen == nullptr || externalScreen == nullptr) {
1725         TLOGE(WmsLogTag::DMS, "screen sessions null.");
1726         return;
1727     }
1728     std::ostringstream oss;
1729     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
1730         << ", rsId: " << innerScreen->GetRSScreenId()
1731         << ", externalScreen screenId: " << externalScreen->GetScreenId()
1732         << ", rsId: " << externalScreen->GetRSScreenId();
1733     oss << std::endl;
1734     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
1735 
1736     /* reset display node */
1737     auto mainNode = innerScreen->GetDisplayNode();
1738     auto extendNode = externalScreen->GetDisplayNode();
1739     ScreenId innerRSId = innerScreen->GetRSScreenId();
1740     ScreenId externalRSId = externalScreen->GetRSScreenId();
1741     if (mainNode != nullptr) {
1742         mainNode->SetScreenId(externalRSId);
1743         RSInterfaces::GetInstance().SetScreenOffset(externalRSId, 0, 0);
1744     }
1745     if (extendNode != nullptr) {
1746         extendNode->SetScreenId(innerRSId);
1747         RSInterfaces::GetInstance().SetScreenOffset(innerRSId, 0, 0);
1748     }
1749     RSTransactionAdapter::FlushImplicitTransaction(
1750         {innerScreen->GetRSUIContext(), externalScreen->GetRSUIContext()});
1751 
1752     /* reset physical info */
1753     MultiScreenChangeUtils::ScreenPhysicalInfoChange(innerScreen, externalScreen);
1754 
1755     /* reset relative position */
1756     innerScreen->SetStartPosition(0, 0);
1757     externalScreen->SetStartPosition(0, 0);
1758 
1759     /* reset combination */
1760     innerScreen->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
1761     externalScreen->SetScreenCombination(ScreenCombination::SCREEN_MAIN);
1762     innerScreen->SetIsExtend(true);
1763     externalScreen->SetIsExtend(false);
1764 
1765     /* set screen available */
1766     innerScreen->SetScreenAvailableStatus(true);
1767     externalScreen->SetScreenAvailableStatus(true);
1768 #endif
1769 }
1770 
OnHgmRefreshRateChange(uint32_t refreshRate)1771 void ScreenSessionManager::OnHgmRefreshRateChange(uint32_t refreshRate)
1772 {
1773     GetDefaultScreenId();
1774     TLOGD(WmsLogTag::DMS, "Set refreshRate: %{public}u, defaultScreenId: %{public}" PRIu64"",
1775         refreshRate, defaultScreenId_);
1776     sptr<ScreenSession> screenSession = GetScreenSession(defaultScreenId_);
1777     if (screenSession) {
1778         screenSession->UpdateRefreshRate(refreshRate);
1779         NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
1780             DisplayChangeEvent::UPDATE_REFRESHRATE);
1781         UpdateCoordinationRefreshRate(refreshRate);
1782         std::map<ScreenId, sptr<ScreenSession>> screenSessionMap;
1783         {
1784             std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1785             screenSessionMap = screenSessionMap_;
1786         }
1787         for (const auto &sessionItem : screenSessionMap) {
1788             const auto &screenSessionItem = sessionItem.second;
1789             const auto &screenType = screenSessionItem->GetScreenProperty().GetScreenType();
1790             if (screenType == ScreenType::VIRTUAL) {
1791                 screenSessionItem->UpdateRefreshRate(refreshRate);
1792                 screenSessionItem->SetSupportedRefreshRate({refreshRate});
1793                 NotifyDisplayChanged(screenSessionItem->ConvertToDisplayInfo(),
1794                     DisplayChangeEvent::UPDATE_REFRESHRATE);
1795             }
1796         }
1797     } else {
1798         TLOGE(WmsLogTag::DMS, "Get default screen session failed.");
1799     }
1800     return;
1801 }
1802 
IsPhysicalScreenAndInUse(sptr<ScreenSession> screenSession) const1803 bool ScreenSessionManager::IsPhysicalScreenAndInUse(sptr<ScreenSession> screenSession) const
1804 {
1805     if (!screenSession) {
1806         return false;
1807     }
1808     if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
1809         screenSession->GetIsCurrentInUse()) {
1810         return true;
1811     }
1812     return false;
1813 }
1814 
SetMultiScreenFrameControl(void)1815 void ScreenSessionManager::SetMultiScreenFrameControl(void)
1816 {
1817 #ifdef WM_MULTI_SCREEN_CTL_ABILITY_ENABLE
1818     uint32_t count = 0;
1819     {
1820         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1821         for (auto sessionIt : screenSessionMap_) {
1822             if (IsPhysicalScreenAndInUse(sessionIt.second)) {
1823                 count++;
1824             }
1825         }
1826     }
1827     if (count >= NUMBER_OF_PHYSICAL_SCREEN) {
1828         TLOGW(WmsLogTag::DMS, "MultiScreen control frame rate to 60");
1829         EventInfo event = { "VOTER_MUTIPHSICALSCREEN", ADD_VOTE, OLED_60_HZ, OLED_60_HZ };
1830         rsInterface_.NotifyRefreshRateEvent(event);
1831     } else {
1832         TLOGW(WmsLogTag::DMS, "Disabling frame rate control");
1833         EventInfo event = { "VOTER_MUTIPHSICALSCREEN", REMOVE_VOTE };
1834         rsInterface_.NotifyRefreshRateEvent(event);
1835     }
1836 #endif
1837 }
1838 
GetScreenSession(ScreenId screenId) const1839 sptr<ScreenSession> ScreenSessionManager::GetScreenSession(ScreenId screenId) const
1840 {
1841     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1842     if (screenSessionMap_.empty()) {
1843         screenEventTracker_.LogWarningAllInfos();
1844     }
1845     auto iter = screenSessionMap_.find(screenId);
1846     if (iter == screenSessionMap_.end()) {
1847         TLOGW(WmsLogTag::DMS, "not found screen session id: %{public}" PRIu64".", screenId);
1848         return nullptr;
1849     }
1850     return iter->second;
1851 }
1852 
GetDefaultScreenSession()1853 sptr<ScreenSession> ScreenSessionManager::GetDefaultScreenSession()
1854 {
1855     GetDefaultScreenId();
1856     return GetScreenSession(defaultScreenId_);
1857 }
1858 
HookDisplayInfoByUid(sptr<DisplayInfo> displayInfo,const sptr<ScreenSession> & screenSession)1859 sptr<DisplayInfo> ScreenSessionManager::HookDisplayInfoByUid(sptr<DisplayInfo> displayInfo,
1860     const sptr<ScreenSession>& screenSession)
1861 {
1862     if (displayInfo == nullptr) {
1863         TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1864         return nullptr;
1865     }
1866     auto uid = IPCSkeleton::GetCallingUid();
1867     std::shared_lock<std::shared_mutex> lock(hookInfoMutex_);
1868     if (displayHookMap_.find(uid) != displayHookMap_.end()) {
1869         auto info = displayHookMap_[uid];
1870         std::ostringstream oss;
1871         oss << "hW: " << info.width_ << ", hH: " << info.height_ << ", hD: " << info.density_
1872             << ", hR: " << info.rotation_ << ", hER: " << info.enableHookRotation_
1873             << " hO: " << info.displayOrientation_ << ", hEO: " << info.enableHookDisplayOrientation_
1874             << ", dW: " << displayInfo->GetHeight() << ", dH: " << displayInfo->GetHeight()
1875             << ", dR: " << static_cast<uint32_t>(displayInfo->GetRotation())
1876             << ", dO: " << static_cast<uint32_t>(displayInfo->GetDisplayOrientation());
1877         TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
1878 
1879         displayInfo->SetWidth(info.width_);
1880         displayInfo->SetHeight(info.height_);
1881         displayInfo->SetVirtualPixelRatio(info.density_);
1882         if (info.enableHookRotation_) {
1883             if (screenSession) {
1884                 Rotation targetRotation = screenSession->ConvertIntToRotation(static_cast<int32_t>(info.rotation_));
1885                 displayInfo->SetRotation(targetRotation);
1886                 DisplayOrientation targetOrientation = screenSession->CalcDisplayOrientation(targetRotation,
1887                     FoldDisplayMode::UNKNOWN);
1888                 TLOGI(WmsLogTag::DMS, "tR: %{public}u, tO: %{public}u", targetRotation, targetOrientation);
1889                 displayInfo->SetDisplayOrientation(targetOrientation);
1890             } else {
1891                 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, screenSession is nullptr.");
1892                 return nullptr;
1893             }
1894         }
1895         if (info.enableHookDisplayOrientation_ &&
1896             info.displayOrientation_ < static_cast<uint32_t>(DisplayOrientation::UNKNOWN)) {
1897             displayInfo->SetDisplayOrientation(static_cast<DisplayOrientation>(info.displayOrientation_));
1898         }
1899     }
1900     return displayInfo;
1901 }
1902 
GetDefaultDisplayInfo()1903 sptr<DisplayInfo> ScreenSessionManager::GetDefaultDisplayInfo()
1904 {
1905     GetDefaultScreenId();
1906     sptr<ScreenSession> screenSession = GetScreenSession(defaultScreenId_);
1907     std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
1908     if (screenSession) {
1909         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1910         if (displayInfo == nullptr) {
1911             TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1912             return nullptr;
1913         }
1914         // 在PC/PAD上安装的竖屏应用以及白名单中的应用在显示状态非全屏时需要hook displayinfo
1915         displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
1916         return displayInfo;
1917     } else {
1918         TLOGE(WmsLogTag::DMS, "failed");
1919         return nullptr;
1920     }
1921 }
1922 
GetDisplayInfoById(DisplayId displayId)1923 sptr<DisplayInfo> ScreenSessionManager::GetDisplayInfoById(DisplayId displayId)
1924 {
1925     TLOGD(WmsLogTag::DMS, "enter, displayId: %{public}" PRIu64" ", displayId);
1926     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1927     for (auto sessionIt : screenSessionMap_) {
1928         auto screenSession = sessionIt.second;
1929         if (screenSession == nullptr) {
1930             TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64 "",
1931                 sessionIt.first);
1932             continue;
1933         }
1934         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1935         if (displayInfo == nullptr) {
1936             TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1937             continue;
1938         }
1939         if (displayId == displayInfo->GetDisplayId()) {
1940             TLOGD(WmsLogTag::DMS, "success");
1941             displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
1942             return displayInfo;
1943         }
1944         if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1945             continue;
1946         }
1947         if (!screenSession->GetScreenProperty().GetIsFakeInUse()) {
1948             continue;
1949         }
1950         sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
1951         if (fakeScreenSession == nullptr) {
1952             TLOGE(WmsLogTag::DMS, "error, fakeScreenSession is nullptr.");
1953             continue;
1954         }
1955         sptr<DisplayInfo> fakeDisplayInfo = fakeScreenSession->ConvertToDisplayInfo();
1956         if (fakeDisplayInfo == nullptr) {
1957             TLOGE(WmsLogTag::DMS, "error, fakeDisplayInfo is nullptr.");
1958             continue;
1959         }
1960         fakeDisplayInfo = HookDisplayInfoByUid(fakeDisplayInfo, fakeScreenSession);
1961         DisplayId fakeDisplayId = fakeDisplayInfo->GetDisplayId();
1962         if (displayId == fakeDisplayId) {
1963             TLOGD(WmsLogTag::DMS, "find fake success");
1964             return fakeDisplayInfo;
1965         }
1966     }
1967     TLOGE(WmsLogTag::DMS, "failed. displayId: %{public}" PRIu64" ", displayId);
1968     return nullptr;
1969 }
1970 
GetVisibleAreaDisplayInfoById(DisplayId displayId)1971 sptr<DisplayInfo> ScreenSessionManager::GetVisibleAreaDisplayInfoById(DisplayId displayId)
1972 {
1973     TLOGD(WmsLogTag::DMS, "enter, displayId: %{public}" PRIu64" ", displayId);
1974     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1975     for (auto sessionIt : screenSessionMap_) {
1976         auto screenSession = sessionIt.second;
1977         if (screenSession == nullptr) {
1978             TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64 "",
1979                 sessionIt.first);
1980             continue;
1981         }
1982         sptr<DisplayInfo> displayInfo = screenSession->ConvertToRealDisplayInfo();
1983         if (displayInfo == nullptr) {
1984             TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1985             continue;
1986         }
1987         if (displayId != displayInfo->GetDisplayId()) {
1988             continue;
1989         }
1990         TLOGD(WmsLogTag::DMS, "success");
1991         displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
1992         if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1993             return displayInfo;
1994         }
1995 #ifdef FOLD_ABILITY_ENABLE
1996         SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
1997         bool isSystemKeyboardOn = SuperFoldStateManager::GetInstance().GetSystemKeyboardStatus();
1998         RRect bounds = screenSession->GetScreenProperty().GetBounds();
1999         auto screenWdith = bounds.rect_.GetWidth();
2000         auto screenHeight = bounds.rect_.GetHeight();
2001         // Adjust screen height when physical keyboard attach or touchPad virtual Keyboard on
2002         if (status == SuperFoldStatus::KEYBOARD || isSystemKeyboardOn) {
2003             if (screenWdith > screenHeight) {
2004                 std::swap(screenWdith, screenHeight);
2005             }
2006             DMRect creaseRect = screenSession->GetScreenProperty().GetCreaseRect();
2007             if (creaseRect.posY_ > 0) {
2008                 displayInfo->SetHeight(creaseRect.posY_);
2009             } else {
2010                 displayInfo->SetHeight(screenHeight / HALF_SCREEN_PARAM);
2011             }
2012             displayInfo->SetWidth(screenWdith);
2013         } else {
2014             displayInfo->SetWidth(screenWdith);
2015             displayInfo->SetHeight(screenHeight);
2016         }
2017         return displayInfo;
2018 #endif
2019     }
2020     TLOGE(WmsLogTag::DMS, "GetVisibleAreaDisplayInfoById failed. displayId: %{public}" PRIu64" ", displayId);
2021     return nullptr;
2022 }
2023 
GetDisplayInfoByScreen(ScreenId screenId)2024 sptr<DisplayInfo> ScreenSessionManager::GetDisplayInfoByScreen(ScreenId screenId)
2025 {
2026     TLOGD(WmsLogTag::DMS, "enter, screenId: %{public}" PRIu64"", screenId);
2027     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2028     for (auto sessionIt : screenSessionMap_) {
2029         auto screenSession = sessionIt.second;
2030         if (screenSession == nullptr) {
2031             TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId:%{public}" PRIu64"",
2032                 sessionIt.first);
2033             continue;
2034         }
2035         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
2036         if (displayInfo == nullptr) {
2037             TLOGI(WmsLogTag::DMS, "error, displayInfo is nullptr.");
2038             continue;
2039         }
2040         if (screenId == displayInfo->GetScreenId()) {
2041             return displayInfo;
2042         }
2043     }
2044     TLOGE(WmsLogTag::DMS, "failed. screenId: %{public}" PRIu64" ", screenId);
2045     return nullptr;
2046 }
2047 
GetFakeDisplayId(sptr<ScreenSession> screenSession)2048 DisplayId ScreenSessionManager::GetFakeDisplayId(sptr<ScreenSession> screenSession)
2049 {
2050     sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
2051     if (fakeScreenSession == nullptr) {
2052         TLOGE(WmsLogTag::DMS, "error, fakeScreenSession is nullptr.");
2053         return DISPLAY_ID_INVALID;
2054     }
2055     sptr<DisplayInfo> fakeDisplayInfo = fakeScreenSession->ConvertToDisplayInfo();
2056     if (fakeDisplayInfo == nullptr) {
2057         TLOGE(WmsLogTag::DMS, "error, fakeDisplayInfo is nullptr.");
2058         return DISPLAY_ID_INVALID;
2059     }
2060     DisplayId fakeDisplayId = fakeDisplayInfo->GetDisplayId();
2061     return fakeDisplayId;
2062 }
2063 
GetAllDisplayIds()2064 std::vector<DisplayId> ScreenSessionManager::GetAllDisplayIds()
2065 {
2066     TLOGD(WmsLogTag::DMS, "enter");
2067     std::vector<DisplayId> res;
2068     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2069     for (auto sessionIt : screenSessionMap_) {
2070         auto screenSession = sessionIt.second;
2071         if (screenSession == nullptr) {
2072             TLOGE(WmsLogTag::DMS, "screenSession is nullptr, ScreenId:%{public}" PRIu64"",
2073                 sessionIt.first);
2074             continue;
2075         }
2076         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
2077         if (displayInfo == nullptr) {
2078             TLOGE(WmsLogTag::DMS, "error, displayInfo is nullptr.");
2079             continue;
2080         }
2081         DisplayId displayId = displayInfo->GetDisplayId();
2082         res.push_back(displayId);
2083         if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
2084             continue;
2085         }
2086         if (!screenSession->GetScreenProperty().GetIsFakeInUse()) {
2087             continue;
2088         }
2089         DisplayId fakeDisplayId = GetFakeDisplayId(screenSession);
2090         if (fakeDisplayId == DISPLAY_ID_FAKE) {
2091             res.push_back(fakeDisplayId);
2092             TLOGI(WmsLogTag::DMS, "add fakeDisplayId: %{public}" PRIu64 "", fakeDisplayId);
2093         }
2094     }
2095     return res;
2096 }
2097 
CalculateXYPosition(sptr<ScreenSession> firstScreenSession,sptr<ScreenSession> secondaryScreenSession)2098 void ScreenSessionManager::CalculateXYPosition(sptr<ScreenSession> firstScreenSession,
2099     sptr<ScreenSession> secondaryScreenSession)
2100 {
2101     if (firstScreenSession != nullptr &&
2102         firstScreenSession->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
2103         firstScreenSession->SetXYPosition(0, 0);
2104         NotifyDisplayChanged(firstScreenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
2105         CalculateSecondryXYPosition(firstScreenSession, secondaryScreenSession);
2106     } else if (secondaryScreenSession != nullptr &&
2107         secondaryScreenSession->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
2108         secondaryScreenSession->SetXYPosition(0, 0);
2109         NotifyDisplayChanged(secondaryScreenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
2110         CalculateSecondryXYPosition(secondaryScreenSession, firstScreenSession);
2111     } else {
2112         TLOGE(WmsLogTag::DMS, "CalculateXYPosition error!");
2113     }
2114 }
2115 
CalculateSecondryXYPosition(sptr<ScreenSession> firstScreenSession,sptr<ScreenSession> secondaryScreenSession)2116 void ScreenSessionManager::CalculateSecondryXYPosition(sptr<ScreenSession> firstScreenSession,
2117     sptr<ScreenSession> secondaryScreenSession)
2118 {
2119     if (firstScreenSession == nullptr || secondaryScreenSession == nullptr) {
2120         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
2121         return;
2122     }
2123     ScreenProperty firstScreenProperty = firstScreenSession->GetScreenProperty();
2124     ScreenProperty secondaryScreenProperty = secondaryScreenSession->GetScreenProperty();
2125     int32_t firstStartX = static_cast<int32_t>(firstScreenProperty.GetStartX());
2126     int32_t firstStartY = static_cast<int32_t>(firstScreenProperty.GetStartY());
2127     int32_t secondaryStartX = static_cast<int32_t>(secondaryScreenProperty.GetStartX());
2128     int32_t secondaryStartY = static_cast<int32_t>(secondaryScreenProperty.GetStartY());
2129     int32_t secondaryX = -firstStartX + secondaryStartX;
2130     int32_t secondaryY = -firstStartY + secondaryStartY;
2131     secondaryScreenSession->SetXYPosition(secondaryX, secondaryY);
2132     NotifyDisplayChanged(secondaryScreenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
2133 }
2134 
GetScreenInfoById(ScreenId screenId)2135 sptr<ScreenInfo> ScreenSessionManager::GetScreenInfoById(ScreenId screenId)
2136 {
2137     if (!SessionPermission::IsSystemCalling() &&
2138         !Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION)) {
2139         TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
2140             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2141         return nullptr;
2142     }
2143     auto screenSession = GetScreenSession(screenId);
2144     if (screenSession == nullptr) {
2145         TLOGE(WmsLogTag::DMS, "cannot find screenInfo: %{public}" PRIu64"", screenId);
2146         return nullptr;
2147     }
2148     return screenSession->ConvertToScreenInfo();
2149 }
2150 
SetScreenActiveMode(ScreenId screenId,uint32_t modeId)2151 DMError ScreenSessionManager::SetScreenActiveMode(ScreenId screenId, uint32_t modeId)
2152 {
2153 #ifdef WM_SCREEN_ACTIVE_MODE_ENABLE
2154     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", modeId: %{public}u", screenId, modeId);
2155     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2156         TLOGE(WmsLogTag::DMS, "Permission Denied!  calling: %{public}s, calling pid: %{public}d",
2157             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2158         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2159     }
2160     if (screenId == SCREEN_ID_INVALID) {
2161         TLOGE(WmsLogTag::DMS, "invalid screenId");
2162         return DMError::DM_ERROR_NULLPTR;
2163     }
2164     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2165     if (screenSession == nullptr) {
2166         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2167         return DMError::DM_ERROR_NULLPTR;
2168     }
2169     ScreenId rsScreenId = SCREEN_ID_INVALID;
2170     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
2171         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
2172         return DMError::DM_ERROR_NULLPTR;
2173     }
2174     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetScreenActiveMode(%" PRIu64", %u)", screenId, modeId);
2175     rsInterface_.SetScreenActiveMode(rsScreenId, modeId);
2176     screenSession->activeIdx_ = static_cast<int32_t>(modeId);
2177     screenSession->UpdatePropertyByActiveMode();
2178     ScreenProperty property = screenSession->GetScreenProperty();
2179     property.SetPropertyChangeReason("active mode change");
2180     screenSession->PropertyChange(property, ScreenPropertyChangeReason::CHANGE_MODE);
2181     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
2182     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
2183 #endif
2184     return DMError::DM_OK;
2185 }
2186 
ConvertScreenIdToRsScreenId(ScreenId screenId,ScreenId & rsScreenId)2187 bool ScreenSessionManager::ConvertScreenIdToRsScreenId(ScreenId screenId, ScreenId& rsScreenId)
2188 {
2189     return screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
2190 }
2191 
UpdateDisplayHookInfo(int32_t uid,bool enable,const DMHookInfo & hookInfo)2192 void ScreenSessionManager::UpdateDisplayHookInfo(int32_t uid, bool enable, const DMHookInfo& hookInfo)
2193 {
2194     TLOGD(WmsLogTag::DMS, "DisplayHookInfo will update");
2195     if (!SessionPermission::IsSystemCalling()) {
2196         TLOGE(WmsLogTag::DMS, "permission denied!");
2197         return;
2198     }
2199 
2200     std::unique_lock<std::shared_mutex> lock(hookInfoMutex_);
2201     if (enable) {
2202         if (uid != 0) {
2203             displayHookMap_[uid] = hookInfo;
2204         }
2205     } else {
2206         displayHookMap_.erase(uid);
2207     }
2208 }
2209 
GetDisplayHookInfo(int32_t uid,DMHookInfo & hookInfo)2210 void ScreenSessionManager::GetDisplayHookInfo(int32_t uid, DMHookInfo& hookInfo)
2211 {
2212     std::shared_lock<std::shared_mutex> lock(hookInfoMutex_);
2213     if (displayHookMap_.find(uid) != displayHookMap_.end()) {
2214         hookInfo = displayHookMap_[uid];
2215     }
2216 }
2217 
IsFreezed(const int32_t & agentPid,const DisplayManagerAgentType & agentType)2218 bool ScreenSessionManager::IsFreezed(const int32_t& agentPid, const DisplayManagerAgentType& agentType)
2219 {
2220     std::lock_guard<std::mutex> lock(freezedPidListMutex_);
2221     if (freezedPidList_.count(agentPid) == 0) {
2222         return false;
2223     }
2224     // 冻结的应用记录应用 pid 和注册的 agentType
2225     if (pidAgentTypeMap_.count(agentPid) == 0) {
2226         std::set agentTypes = { agentType };
2227         pidAgentTypeMap_[agentPid] = agentTypes;
2228     } else {
2229         pidAgentTypeMap_[agentPid].insert(agentType);
2230     }
2231     TLOGD(WmsLogTag::DMS, "Agent is freezed, no need notify. PID: %{public}d.", agentPid);
2232     return true;
2233 }
2234 
NotifyScreenChanged(sptr<ScreenInfo> screenInfo,ScreenChangeEvent event)2235 void ScreenSessionManager::NotifyScreenChanged(sptr<ScreenInfo> screenInfo, ScreenChangeEvent event)
2236 {
2237     if (screenInfo == nullptr) {
2238         TLOGE(WmsLogTag::DMS, "error, screenInfo is nullptr.");
2239         return;
2240     }
2241     {
2242         std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
2243         lastScreenChangeEvent_ = event;
2244     }
2245     auto task = [=] {
2246         auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
2247         TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", agent size: %{public}u",
2248             screenInfo->GetScreenId(), static_cast<uint32_t>(agents.size()));
2249         if (agents.empty()) {
2250             return;
2251         }
2252         for (auto& agent : agents) {
2253             int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
2254             if (!IsFreezed(agentPid, DisplayManagerAgentType::SCREEN_EVENT_LISTENER)) {
2255                 agent->OnScreenChange(screenInfo, event);
2256             }
2257         }
2258     };
2259     taskScheduler_->PostAsyncTask(task, "NotifyScreenChanged:SID:" + std::to_string(screenInfo->GetScreenId()));
2260 }
2261 
SetVirtualPixelRatio(ScreenId screenId,float virtualPixelRatio)2262 DMError ScreenSessionManager::SetVirtualPixelRatio(ScreenId screenId, float virtualPixelRatio)
2263 {
2264     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2265         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
2266             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2267         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2268     }
2269 
2270     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2271     if (!screenSession) {
2272         TLOGE(WmsLogTag::DMS, "screen session is nullptr");
2273         return DMError::DM_ERROR_UNKNOWN;
2274     }
2275     if (screenSession->isScreenGroup_) {
2276         TLOGE(WmsLogTag::DMS, "cannot set virtual pixel ratio to the combination. screen: %{public}" PRIu64"",
2277             screenId);
2278         return DMError::DM_ERROR_NULLPTR;
2279     }
2280     // less to 1e-6 mean equal
2281     if (fabs(screenSession->GetScreenProperty().GetVirtualPixelRatio() - virtualPixelRatio) < 1e-6) {
2282         TLOGE(WmsLogTag::DMS,
2283             "The density is equivalent to the original value, no update operation is required, aborted.");
2284         return DMError::DM_OK;
2285     }
2286     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetVirtualPixelRatio(%" PRIu64", %f)", screenId,
2287         virtualPixelRatio);
2288     screenSession->SetVirtualPixelRatio(virtualPixelRatio);
2289     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
2290         sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
2291         if (fakeScreenSession != nullptr) {
2292             fakeScreenSession->SetVirtualPixelRatio(virtualPixelRatio);
2293             NotifyDisplayChanged(fakeScreenSession->ConvertToDisplayInfo(),
2294                 DisplayChangeEvent::DISPLAY_VIRTUAL_PIXEL_RATIO_CHANGED);
2295         }
2296     }
2297     std::map<DisplayId, sptr<DisplayInfo>> emptyMap;
2298     OnPropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::VIRTUAL_PIXEL_RATIO_CHANGE,
2299         screenId);
2300     NotifyDisplayStateChange(screenId, screenSession->ConvertToDisplayInfo(),
2301         emptyMap, DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE);
2302     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::VIRTUAL_PIXEL_RATIO_CHANGED);
2303     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
2304         DisplayChangeEvent::DISPLAY_VIRTUAL_PIXEL_RATIO_CHANGED);
2305     if (g_isPcDevice) {
2306         sptr<ScreenSession> physicalScreen = GetPhysicalScreenSession(screenSession->GetRSScreenId());
2307         if (physicalScreen) {
2308             physicalScreen->SetVirtualPixelRatio(virtualPixelRatio);
2309         }
2310     }
2311     return DMError::DM_OK;
2312 }
2313 
SetVirtualPixelRatioSystem(ScreenId screenId,float virtualPixelRatio)2314 DMError ScreenSessionManager::SetVirtualPixelRatioSystem(ScreenId screenId, float virtualPixelRatio)
2315 {
2316     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2317         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
2318             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2319         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2320     }
2321 
2322     auto clientProxy = GetClientProxy();
2323     if (clientProxy) {
2324         clientProxy->SetVirtualPixelRatioSystem(screenId, virtualPixelRatio);
2325     }
2326     return DMError::DM_OK;
2327 }
2328 
SetDefaultDensityDpi(ScreenId screenId,float virtualPixelRatio)2329 DMError ScreenSessionManager::SetDefaultDensityDpi(ScreenId screenId, float virtualPixelRatio)
2330 {
2331     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2332         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
2333             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2334         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2335     }
2336 
2337     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2338     if (!screenSession) {
2339         TLOGE(WmsLogTag::DMS, "screen session is nullptr");
2340         return DMError::DM_ERROR_UNKNOWN;
2341     }
2342     if (screenSession->isScreenGroup_) {
2343         TLOGE(WmsLogTag::DMS, "cannot set virtual pixel ratio to the combination. screen: %{public}" PRIu64"",
2344             screenId);
2345         return DMError::DM_ERROR_NULLPTR;
2346     }
2347     // less to 1e-6 mean equal
2348     if (fabs(screenSession->GetScreenProperty().GetDefaultDensity() - virtualPixelRatio) < 1e-6) {
2349         TLOGE(WmsLogTag::DMS,
2350             "The density is equivalent to the original value, no update operation is required, aborted.");
2351         return DMError::DM_OK;
2352     }
2353     screenSession->SetDefaultDensity(virtualPixelRatio);
2354     return DMError::DM_OK;
2355 }
2356 
SetResolution(ScreenId screenId,uint32_t width,uint32_t height,float virtualPixelRatio)2357 DMError ScreenSessionManager::SetResolution(ScreenId screenId, uint32_t width, uint32_t height, float virtualPixelRatio)
2358 {
2359     TLOGI(WmsLogTag::DMS,
2360         "ScreenId: %{public}" PRIu64 ", w: %{public}u, h: %{public}u, virtualPixelRatio: %{public}f",
2361         screenId, width, height, virtualPixelRatio);
2362     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2363         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2364             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2365         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2366     }
2367     if (screenId == SCREEN_ID_INVALID) {
2368         TLOGE(WmsLogTag::DMS, "invalid screenId");
2369         return DMError::DM_ERROR_NULLPTR;
2370     }
2371     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2372     if (screenSession == nullptr) {
2373         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2374         return DMError::DM_ERROR_NULLPTR;
2375     }
2376     sptr<SupportedScreenModes> screenSessionModes = screenSession->GetActiveScreenMode();
2377     if (screenSessionModes == nullptr) {
2378         return DMError::DM_ERROR_NULLPTR;
2379     }
2380     if (width <= 0 || width > screenSessionModes->width_ ||
2381         height <= 0 || height > screenSessionModes->height_ ||
2382         virtualPixelRatio < (static_cast<float>(DOT_PER_INCH_MINIMUM_VALUE) / DOT_PER_INCH) ||
2383         virtualPixelRatio > (static_cast<float>(DOT_PER_INCH_MAXIMUM_VALUE) / DOT_PER_INCH)) {
2384         TLOGE(WmsLogTag::DMS, "invalid param! w:%{public}u h:%{public}u min:%{public}f max:%{public}f",
2385             screenSessionModes->width_, screenSessionModes->height_,
2386             static_cast<float>(DOT_PER_INCH_MINIMUM_VALUE) / DOT_PER_INCH,
2387             static_cast<float>(DOT_PER_INCH_MAXIMUM_VALUE) / DOT_PER_INCH);
2388         return DMError::DM_ERROR_INVALID_PARAM;
2389     }
2390     screenSession->SetDensityInCurResolution(virtualPixelRatio);
2391     DMError ret = SetVirtualPixelRatio(screenId, virtualPixelRatio);
2392     if (ret != DMError::DM_OK) {
2393         TLOGE(WmsLogTag::DMS, "Failed to setVirtualPixelRatio when settingResolution");
2394         screenSession->SetDensityInCurResolution(screenSession->GetScreenProperty().GetVirtualPixelRatio());
2395         return ret;
2396     }
2397     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetResolution(%" PRIu64", %u, %u, %f)",
2398         screenId, width, height, virtualPixelRatio);
2399     screenSession->UpdatePropertyByResolution(width, height);
2400     screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::CHANGE_MODE);
2401     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
2402     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
2403     return DMError::DM_OK;
2404 }
2405 
GetDensityInCurResolution(ScreenId screenId,float & virtualPixelRatio)2406 DMError ScreenSessionManager::GetDensityInCurResolution(ScreenId screenId, float& virtualPixelRatio)
2407 {
2408     DmsXcollie dmsXcollie("DMS:GetDensityInCurResolution", XCOLLIE_TIMEOUT_10S);
2409     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2410     if (screenSession == nullptr) {
2411         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2412         return DMError::DM_ERROR_NULLPTR;
2413     }
2414 
2415     virtualPixelRatio = screenSession->GetScreenProperty().GetDensityInCurResolution();
2416     return DMError::DM_OK;
2417 }
2418 
GetScreenColorGamut(ScreenId screenId,ScreenColorGamut & colorGamut)2419 DMError ScreenSessionManager::GetScreenColorGamut(ScreenId screenId, ScreenColorGamut& colorGamut)
2420 {
2421 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
2422     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 "", screenId);
2423     if (screenId == SCREEN_ID_INVALID) {
2424         TLOGE(WmsLogTag::DMS, "screenId invalid");
2425         return DMError::DM_ERROR_INVALID_PARAM;
2426     }
2427     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2428     if (screenSession == nullptr) {
2429         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2430         return DMError::DM_ERROR_INVALID_PARAM;
2431     }
2432     return screenSession->GetScreenColorGamut(colorGamut);
2433 #else
2434     return DMError::DM_OK;
2435 #endif
2436 }
2437 
SetScreenColorGamut(ScreenId screenId,int32_t colorGamutIdx)2438 DMError ScreenSessionManager::SetScreenColorGamut(ScreenId screenId, int32_t colorGamutIdx)
2439 {
2440 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
2441     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2442         TLOGE(WmsLogTag::DMS, "permission denied!");
2443         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2444     }
2445 
2446     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", colorGamutIdx %{public}d",
2447         screenId, colorGamutIdx);
2448     if (screenId == SCREEN_ID_INVALID) {
2449         TLOGE(WmsLogTag::DMS, "screenId invalid");
2450         return DMError::DM_ERROR_INVALID_PARAM;
2451     }
2452     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2453     if (screenSession == nullptr) {
2454         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2455         return DMError::DM_ERROR_INVALID_PARAM;
2456     }
2457     return screenSession->SetScreenColorGamut(colorGamutIdx);
2458 #else
2459     return DMError::DM_OK;
2460 #endif
2461 }
2462 
GetScreenGamutMap(ScreenId screenId,ScreenGamutMap & gamutMap)2463 DMError ScreenSessionManager::GetScreenGamutMap(ScreenId screenId, ScreenGamutMap& gamutMap)
2464 {
2465 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
2466     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 "", screenId);
2467     if (screenId == SCREEN_ID_INVALID) {
2468         TLOGE(WmsLogTag::DMS, "screenId invalid");
2469         return DMError::DM_ERROR_INVALID_PARAM;
2470     }
2471     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2472     if (screenSession == nullptr) {
2473         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2474         return DMError::DM_ERROR_INVALID_PARAM;
2475     }
2476     return screenSession->GetScreenGamutMap(gamutMap);
2477 #else
2478     return DMError::DM_OK;
2479 #endif
2480 }
2481 
SetScreenGamutMap(ScreenId screenId,ScreenGamutMap gamutMap)2482 DMError ScreenSessionManager::SetScreenGamutMap(ScreenId screenId, ScreenGamutMap gamutMap)
2483 {
2484 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
2485     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2486         TLOGE(WmsLogTag::DMS, "permission denied!");
2487         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2488     }
2489 
2490     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", ScreenGamutMap %{public}u",
2491         screenId, static_cast<uint32_t>(gamutMap));
2492     if (screenId == SCREEN_ID_INVALID) {
2493         TLOGE(WmsLogTag::DMS, "screenId invalid");
2494         return DMError::DM_ERROR_INVALID_PARAM;
2495     }
2496     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2497     if (screenSession == nullptr) {
2498         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2499         return DMError::DM_ERROR_INVALID_PARAM;
2500     }
2501     return screenSession->SetScreenGamutMap(gamutMap);
2502 #else
2503     return DMError::DM_OK;
2504 #endif
2505 }
2506 
SetScreenColorTransform(ScreenId screenId)2507 DMError ScreenSessionManager::SetScreenColorTransform(ScreenId screenId)
2508 {
2509     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2510         TLOGE(WmsLogTag::DMS, "permission denied!");
2511         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2512     }
2513 
2514     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 "", screenId);
2515     if (screenId == SCREEN_ID_INVALID) {
2516         TLOGE(WmsLogTag::DMS, "screenId invalid");
2517         return DMError::DM_ERROR_INVALID_PARAM;
2518     }
2519     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2520     if (screenSession == nullptr) {
2521         TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2522         return DMError::DM_ERROR_INVALID_PARAM;
2523     }
2524     return screenSession->SetScreenColorTransform();
2525 }
2526 
GetPhysicalScreenSession(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)2527 sptr<ScreenSession> ScreenSessionManager::GetPhysicalScreenSession(ScreenId screenId, ScreenId defScreenId,
2528     ScreenProperty property)
2529 {
2530     sptr<ScreenSession> screenSession = nullptr;
2531     ScreenSessionConfig config;
2532     if (g_isPcDevice) {
2533         config = {
2534             .screenId = screenId,
2535             .rsId = screenId,
2536             .defaultScreenId = defScreenId,
2537             .property = property,
2538         };
2539         screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_REAL);
2540     } else {
2541         sptr<ScreenSession> defaultScreen = GetDefaultScreenSession();
2542         if (defaultScreen == nullptr || defaultScreen->GetDisplayNode() == nullptr) {
2543             TLOGE(WmsLogTag::DMS, "default screen null");
2544             return screenSession;
2545         }
2546         NodeId nodeId = defaultScreen->GetDisplayNode()->GetId();
2547         TLOGI(WmsLogTag::DMS, "physical mirror screen nodeId: %{public}" PRIu64, nodeId);
2548         config = {
2549             .screenId = screenId,
2550             .rsId = screenId,
2551             .defaultScreenId = defScreenId,
2552             .mirrorNodeId = nodeId,
2553             .property = property,
2554         };
2555         screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_MIRROR);
2556         screenSession->SetIsPhysicalMirrorSwitch(true);
2557 #ifdef FOLD_ABILITY_ENABLE
2558         if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
2559             DMRect mainScreenRegion = {0, 0, 0, 0};
2560             foldScreenController_->SetMainScreenRegion(mainScreenRegion);
2561             screenSession->SetMirrorScreenRegion(screenId, mainScreenRegion);
2562             screenSession->SetIsEnableRegionRotation(true);
2563             screenSession->EnableMirrorScreenRegion();
2564         }
2565 #endif
2566     }
2567     return screenSession;
2568 }
2569 
SetDefaultScreenModeWhenCreateMirror(sptr<ScreenSession> & screenSession)2570 void ScreenSessionManager::SetDefaultScreenModeWhenCreateMirror(sptr<ScreenSession>& screenSession)
2571 {
2572     if (screenSession == nullptr) {
2573         TLOGE(WmsLogTag::DMS, "screenSession is null");
2574         return;
2575     }
2576 #ifdef FOLD_ABILITY_ENABLE
2577     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
2578         SuperFoldStateManager::GetInstance().GetCurrentStatus() != SuperFoldStatus::EXPANDED) {
2579         screenSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
2580     } else {
2581 #endif
2582     screenSession->SetScreenCombination(ScreenCombination::SCREEN_EXTEND);
2583 #ifdef FOLD_ABILITY_ENABLE
2584     }
2585 #endif
2586 }
2587 
CreatePhysicalMirrorSessionInner(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)2588 sptr<ScreenSession> ScreenSessionManager::CreatePhysicalMirrorSessionInner(ScreenId screenId, ScreenId defScreenId,
2589     ScreenProperty property)
2590 {
2591 #ifdef WM_MULTI_SCREEN_ENABLE
2592     sptr<ScreenSession> screenSession = nullptr;
2593     if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
2594         TLOGW(WmsLogTag::DMS, "mirror disabled by edm!");
2595         return screenSession;
2596     }
2597     screenSession = GetPhysicalScreenSession(screenId, defScreenId, property);
2598     if (!screenSession) {
2599         TLOGE(WmsLogTag::DMS, "screenSession is null");
2600         return nullptr;
2601     }
2602     MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_ENTER_STR);
2603     HandleExtendScreenConnect(screenId);
2604     if (g_isPcDevice) {
2605         // pc is none, pad&&phone is mirror
2606         InitExtendScreenProperty(screenId, screenSession, property);
2607         screenSession->SetName(SCREEN_NAME_EXTEND);
2608         screenSession->SetIsExtend(true);
2609         SetDefaultScreenModeWhenCreateMirror(screenSession);
2610     } else {
2611         screenSession->SetIsExtend(true);
2612         screenSession->SetName(SCREEN_NAME_CAST);
2613         screenSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
2614         screenSession->SetVirtualScreenFlag(VirtualScreenFlag::CAST);
2615     }
2616     GetAndMergeEdidInfo(screenSession);
2617     screenSession->SetMirrorScreenType(MirrorScreenType::PHYSICAL_MIRROR);
2618     screenSession->SetIsPcUse(g_isPcDevice ? true : false);
2619     screenSession->SetIsInternal(false);
2620     screenSession->SetIsRealScreen(true);
2621     screenSession->SetIsCurrentInUse(true);
2622     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE);
2623     if (!g_isPcDevice) {
2624         hdmiScreenCount_ = hdmiScreenCount_ + 1;
2625         NotifyCaptureStatusChanged();
2626     }
2627     return screenSession;
2628 #else
2629     return nullptr;
2630 #endif
2631 }
2632 
GetScreenSessionInner(ScreenId screenId,ScreenProperty property)2633 sptr<ScreenSession> ScreenSessionManager::GetScreenSessionInner(ScreenId screenId, ScreenProperty property)
2634 {
2635     ScreenId defScreenId = GetDefaultScreenId();
2636     TLOGW(WmsLogTag::DMS, "screenId:%{public}" PRIu64 "", screenId);
2637     if (IsDefaultMirrorMode(screenId)) {
2638 #ifdef WM_MULTI_SCREEN_ENABLE
2639         return CreatePhysicalMirrorSessionInner(screenId, defScreenId, property);
2640 #else
2641         return nullptr;
2642 #endif
2643     }
2644     std::string screenName = "UNKNOWN";
2645     if (screenId == SCREEN_ID_MAIN) {
2646         screenName = "SubScreen";
2647     }
2648     ScreenSessionConfig config = {
2649         .screenId = screenId,
2650         .rsId = screenId,
2651         .defaultScreenId = defScreenId,
2652         .name = screenName,
2653         .property = property,
2654     };
2655     sptr<ScreenSession> screenSession = nullptr;
2656     screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_REAL);
2657     screenSession->SetIsExtend(false);
2658     screenSession->SetScreenCombination(ScreenCombination::SCREEN_MAIN);
2659     screenSession->SetIsInternal(true);
2660     screenSession->SetIsRealScreen(true);
2661     screenSession->SetIsCurrentInUse(true);
2662     screenSession->SetIsPcUse(g_isPcDevice ? true : false);
2663     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
2664         InitFakeScreenSession(screenSession);
2665     }
2666     return screenSession;
2667 }
2668 
CreateScreenProperty(ScreenId screenId,ScreenProperty & property)2669 void ScreenSessionManager::CreateScreenProperty(ScreenId screenId, ScreenProperty& property)
2670 {
2671     int id = HiviewDFX::XCollie::GetInstance().SetTimer("CreateScreenPropertyCallRS", XCOLLIE_TIMEOUT_10S, nullptr,
2672         nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
2673     TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenActiveMode ScreenId: %{public}" PRIu64, screenId);
2674     ScreenId phyScreenId = GetPhyScreenId(screenId);
2675     auto screenMode = rsInterface_.GetScreenActiveMode(phyScreenId);
2676     TLOGW(WmsLogTag::DMS, "get screenWidth: %{public}d, screenHeight: %{public}d",
2677         static_cast<uint32_t>(screenMode.GetScreenWidth()), static_cast<uint32_t>(screenMode.GetScreenHeight()));
2678     auto screenBounds = GetScreenBounds(screenId, screenMode);
2679     auto screenRefreshRate = screenMode.GetScreenRefreshRate();
2680     TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenCapability ScreenId: %{public}" PRIu64, phyScreenId);
2681     auto screenCapability = rsInterface_.GetScreenCapability(phyScreenId);
2682     HiviewDFX::XCollie::GetInstance().CancelTimer(id);
2683     TLOGW(WmsLogTag::DMS, "Call RS interface end, create ScreenProperty begin");
2684     InitScreenProperty(screenId, screenMode, screenCapability, property);
2685 
2686     if (isDensityDpiLoad_) {
2687         if (phyScreenId == SCREEN_ID_MAIN) {
2688             TLOGW(WmsLogTag::DMS, "subDensityDpi_ = %{public}f", subDensityDpi_);
2689             property.SetVirtualPixelRatio(subDensityDpi_);
2690             property.SetDefaultDensity(subDensityDpi_);
2691             property.SetDensityInCurResolution(subDensityDpi_);
2692         } else {
2693             TLOGW(WmsLogTag::DMS, "densityDpi_ = %{public}f", densityDpi_);
2694             property.SetVirtualPixelRatio(densityDpi_);
2695             property.SetDefaultDensity(densityDpi_);
2696             property.SetDensityInCurResolution(densityDpi_);
2697         }
2698     } else {
2699         property.UpdateVirtualPixelRatio(screenBounds);
2700     }
2701     property.SetRefreshRate(screenRefreshRate);
2702     property.SetDefaultDeviceRotationOffset(defaultDeviceRotationOffset_);
2703 #ifdef FOLD_ABILITY_ENABLE
2704     if (foldScreenController_ != nullptr && screenId == 0
2705         && (g_screenRotationOffSet == ROTATION_90 || g_screenRotationOffSet == ROTATION_270)) {
2706         screenBounds = RRect({ 0, 0, screenMode.GetScreenHeight(), screenMode.GetScreenWidth() }, 0.0f, 0.0f);
2707         property.SetBounds(screenBounds);
2708     }
2709     sptr<FoldCreaseRegion> creaseRegion = GetCurrentFoldCreaseRegion();
2710     if (creaseRegion != nullptr) {
2711         std::vector<DMRect> creaseRects = creaseRegion->GetCreaseRects();
2712         if (creaseRects.size() > 0) {
2713             property.SetCreaseRect(creaseRects[0]);
2714         }
2715     }
2716 #endif
2717     property.CalcDefaultDisplayOrientation();
2718     property.SetScreenShape(ScreenSettingHelper::GetScreenShape(screenId));
2719     if (property.GetDisplayGroupId() == DISPLAY_GROUP_ID_INVALID) {
2720         property.SetDisplayGroupId(DISPLAY_GROUP_ID_DEFAULT);
2721     }
2722     if (property.GetMainDisplayIdOfGroup() == SCREEN_ID_INVALID) {
2723         property.SetMainDisplayIdOfGroup(MAIN_SCREEN_ID_DEFAULT);
2724     }
2725 }
2726 
InitScreenProperty(ScreenId screenId,RSScreenModeInfo & screenMode,RSScreenCapability & screenCapability,ScreenProperty & property)2727 void ScreenSessionManager::InitScreenProperty(ScreenId screenId, RSScreenModeInfo& screenMode,
2728     RSScreenCapability& screenCapability, ScreenProperty& property)
2729 {
2730     auto screenBounds = GetScreenBounds(screenId, screenMode);
2731     property.SetRotation(0.0f);
2732     property.SetPhyWidth(screenCapability.GetPhyWidth());
2733     property.SetPhyHeight(screenCapability.GetPhyHeight());
2734     property.SetValidWidth(screenBounds.rect_.width_);
2735     property.SetValidHeight(screenBounds.rect_.height_);
2736     property.SetDpiPhyBounds(screenCapability.GetPhyWidth(), screenCapability.GetPhyHeight());
2737     property.SetPhyBounds(screenBounds);
2738     property.SetBounds(screenBounds);
2739     property.SetAvailableArea({0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight()});
2740     property.SetPhysicalTouchBounds();
2741     property.SetInputOffsetY();
2742     property.SetCurrentOffScreenRendering(false);
2743     property.SetScreenRealWidth(property.GetBounds().rect_.GetWidth());
2744     property.SetScreenRealHeight(property.GetBounds().rect_.GetHeight());
2745     property.SetMirrorWidth(property.GetBounds().rect_.GetWidth());
2746     property.SetMirrorHeight(property.GetBounds().rect_.GetHeight());
2747     property.SetScreenRealPPI();
2748     property.SetScreenRealDPI();
2749     property.SetScreenAreaOffsetX(property.GetPhyBounds().rect_.GetLeft());
2750     property.SetScreenAreaOffsetY(property.GetPhyBounds().rect_.GetTop());
2751     property.SetScreenAreaWidth(property.GetPhyBounds().rect_.GetWidth());
2752     property.SetScreenAreaHeight(property.GetPhyBounds().rect_.GetHeight());
2753 }
2754 
GetScreenBounds(ScreenId screenId,RSScreenModeInfo & screenMode)2755 RRect ScreenSessionManager::GetScreenBounds(ScreenId screenId, RSScreenModeInfo& screenMode)
2756 {
2757     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice() &&
2758         GetCoordinationFlag() && screenId == SCREEN_ID_MAIN) {
2759         if (screenParams_.size() < STATUS_PARAM_VALID_INDEX) {
2760             TLOGE(WmsLogTag::DMS, "invalid param num, use default");
2761             return RRect({ 0, 0, MAIN_STATUS_DEFAULT_WIDTH, SCREEN_DEFAULT_HEIGHT }, 0.0f, 0.0f);
2762         }
2763         return RRect({ 0, 0, screenParams_[MAIN_STATUS_WIDTH_INDEX], screenParams_[SCREEN_HEIGHT_INDEX] }, 0.0f, 0.0f);
2764     }
2765     return RRect({ 0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight() }, 0.0f, 0.0f);
2766 }
2767 
GetInternalWidth()2768 void ScreenSessionManager::GetInternalWidth()
2769 {
2770     ScreenId screenId = GetInternalScreenId();
2771     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2772     if (screenSession == nullptr) {
2773         TLOGE(WmsLogTag::DMS, "screen session is null");
2774         return;
2775     }
2776     ScreenProperty screenProperty = screenSession->GetScreenProperty();
2777     uint32_t screenWidth = screenProperty.GetScreenRealWidth();
2778     uint32_t screenHeight = screenProperty.GetScreenRealHeight();
2779     g_internalWidth = (screenWidth > screenHeight) ? screenWidth : screenHeight;
2780     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", g_internalWidth is:%{public}u",
2781         screenId, static_cast<uint32_t>(g_internalWidth));
2782     return;
2783 }
2784 
InitExtendScreenProperty(ScreenId screenId,sptr<ScreenSession> session,ScreenProperty property)2785 void ScreenSessionManager::InitExtendScreenProperty(ScreenId screenId, sptr<ScreenSession> session,
2786     ScreenProperty property)
2787 {
2788     if (!g_isPcDevice) {
2789         TLOGW(WmsLogTag::DMS, "not PC device");
2790         return;
2791     }
2792     bool isSupportOffScreenRendering = ScreenSceneConfig::IsSupportOffScreenRendering();
2793     if (!isSupportOffScreenRendering) {
2794         TLOGW(WmsLogTag::DMS, "xml isSupportOffScreenRendering is fasle");
2795         return;
2796     }
2797     GetInternalWidth();
2798     TLOGD(WmsLogTag::DMS, "g_internalWidth: %{public}u", static_cast<uint32_t>(g_internalWidth));
2799     float offScreenPPIThreshold = static_cast<float>(ScreenSceneConfig::GetOffScreenPPIThreshold());
2800     uint32_t screenWidth = property.GetBounds().rect_.GetWidth();
2801     uint32_t screenHeight = property.GetBounds().rect_.GetHeight();
2802     float screenPPI = property.GetScreenRealPPI();
2803     if (screenWidth == 0) {
2804         TLOGE(WmsLogTag::DMS, "screenWidth is zero");
2805         return;
2806     }
2807     if (screenWidth > FOUR_K_WIDTH) {
2808         float scale = static_cast<float>(FOUR_K_WIDTH) / screenWidth;
2809         uint32_t screenAdjustHeight = static_cast<uint32_t>(std::round(screenHeight * scale));
2810         auto screenBounds = RRect({ 0, 0, FOUR_K_WIDTH, screenAdjustHeight }, 0.0f, 0.0f);
2811         session->SetExtendProperty(screenBounds, false);
2812         session->SetAvailableArea({0, 0, FOUR_K_WIDTH, screenAdjustHeight});
2813         session->SetValidWidth(FOUR_K_WIDTH);
2814         session->SetValidHeight(screenAdjustHeight);
2815         TLOGD(WmsLogTag::DMS, "screenWidth > 4K, screenId:%{public}" PRIu64"", screenId);
2816     } else if (screenWidth < THREE_K_WIDTH && screenPPI < offScreenPPIThreshold) {
2817         float scale = static_cast<float>(g_internalWidth) / screenWidth;
2818         uint32_t screenAdjustHeight = static_cast<uint32_t>(std::round(screenHeight * scale));
2819         auto screenBounds = RRect({ 0, 0, g_internalWidth, screenAdjustHeight }, 0.0f, 0.0f);
2820         session->SetExtendProperty(screenBounds, true);
2821         session->SetAvailableArea({0, 0, g_internalWidth, screenAdjustHeight});
2822         session->SetValidWidth(g_internalWidth);
2823         session->SetValidHeight(screenAdjustHeight);
2824         TLOGD(WmsLogTag::DMS, "screenWidth < g_internalWidth, screenId:%{public}" PRIu64"", screenId);
2825     } else {
2826         TLOGW(WmsLogTag::DMS, "no need adjust, screenId:%{public}" PRIu64"", screenId);
2827         return;
2828     }
2829     std::ostringstream oss;
2830     oss << "screenId:" << screenId
2831         << ", screenWidth: " <<  session->GetScreenProperty().GetBounds().rect_.GetWidth()
2832         << ", screenHeight: " << session->GetScreenProperty().GetBounds().rect_.GetHeight()
2833         << ", propertyCurrentOffScreenRendering: " << session->GetScreenProperty().GetCurrentOffScreenRendering()
2834         << ", screenPPI: " << screenPPI;
2835     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
2836 }
2837 
SetExtendedScreenFallbackPlan(ScreenId screenId)2838 void ScreenSessionManager::SetExtendedScreenFallbackPlan(ScreenId screenId)
2839 {
2840     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2841     if (screenSession == nullptr) {
2842         TLOGE(WmsLogTag::DMS, "screen session is null");
2843         return;
2844     }
2845     if (screenSession->GetIsInternal()) {
2846         TLOGW(WmsLogTag::DMS, "screen is internal");
2847         SetInnerScreenFallbackPlan(screenSession);
2848         return;
2849     }
2850     ScreenProperty screenProperty = screenSession->GetScreenProperty();
2851     if (!screenProperty.GetCurrentOffScreenRendering()) {
2852         TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", propertyCurrentOffScreenRendering is false", screenId);
2853         return;
2854     }
2855     uint32_t screenAdjustWidth = 0;
2856     uint32_t screenAdjustHeight = 0;
2857     if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
2858         TLOGD(WmsLogTag::DMS, "Screen is mirror");
2859         screenAdjustWidth = screenProperty.GetScreenRealWidth();
2860         screenAdjustHeight = screenProperty.GetScreenRealHeight();
2861     } else {
2862         TLOGD(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", setPhysicalScreenResolution", screenId);
2863         screenAdjustWidth = screenProperty.GetBounds().rect_.GetWidth();
2864         screenAdjustHeight = screenProperty.GetBounds().rect_.GetHeight();
2865     }
2866     ScreenId rsScreenId;
2867     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
2868         TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
2869         return;
2870     }
2871     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetPhysicalScreenResolution(%" PRIu64")", screenId);
2872     int32_t res = rsInterface_.SetPhysicalScreenResolution(rsScreenId, screenAdjustWidth, screenAdjustHeight);
2873     if ((screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND ||
2874         screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) && !screenSession->GetIsInternal()) {
2875         screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::UNDEFINED);
2876         screenSession->SetFrameGravity(Rosen::Gravity::RESIZE);
2877     } else {
2878         screenSession->SetFrameGravity(Rosen::Gravity::TOP_LEFT);
2879     }
2880     SetExtendedScreenFallbackPlanEvent(res);
2881     TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 ", screenAdjustWidth:%{public}u, screenAdjustHeight:%{public}u",
2882         screenId, screenAdjustWidth, screenAdjustHeight);
2883 }
2884 
SetExtendedScreenFallbackPlanEvent(int32_t res)2885 void ScreenSessionManager::SetExtendedScreenFallbackPlanEvent(int32_t res)
2886 {
2887     if (res != StatusCode::SUCCESS) {
2888         TLOGE(WmsLogTag::DMS, "RS SetPhysicalScreenResolution failed.");
2889         screenEventTracker_.RecordEvent("SetPhysicalScreenResolution failed.");
2890     } else {
2891         TLOGI(WmsLogTag::DMS, "RS SetPhysicalScreenResolution success.");
2892         screenEventTracker_.RecordEvent("SetPhysicalScreenResolution success.");
2893     }
2894 }
2895 
2896 
SetInnerScreenFallbackPlan(sptr<ScreenSession> screenSession)2897 void ScreenSessionManager::SetInnerScreenFallbackPlan(sptr<ScreenSession> screenSession)
2898 {
2899     ScreenProperty screenProperty = screenSession->GetScreenProperty();
2900     uint32_t screenAdjustWidth = screenProperty.GetScreenRealWidth();
2901     uint32_t screenAdjustHeight = screenProperty.GetScreenRealHeight();
2902     ScreenId screenId = screenSession->GetScreenId();
2903     ScreenId rsScreenId;
2904     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
2905         TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
2906         return;
2907     }
2908     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetPhysicalScreenResolution(%" PRIu64")", screenId);
2909     int32_t res = rsInterface_.SetPhysicalScreenResolution(rsScreenId, screenAdjustWidth, screenAdjustHeight);
2910     if (res != StatusCode::SUCCESS) {
2911         TLOGE(WmsLogTag::DMS, "RS SetPhysicalScreenResolution failed.");
2912         screenEventTracker_.RecordEvent("SetPhysicalScreenResolution failed.");
2913     } else {
2914         TLOGI(WmsLogTag::DMS, "RS SetPhysicalScreenResolution success.");
2915         screenEventTracker_.RecordEvent("SetPhysicalScreenResolution success.");
2916     }
2917     TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 ", screenAdjustWidth:%{public}u, screenAdjustHeight:%{public}u",
2918         screenId, screenAdjustWidth, screenAdjustHeight);
2919 }
2920 
InitExtendScreenDensity(sptr<ScreenSession> session,ScreenProperty property)2921 void ScreenSessionManager::InitExtendScreenDensity(sptr<ScreenSession> session, ScreenProperty property)
2922 {
2923     if (session->GetScreenProperty().GetScreenType() != ScreenType::REAL || session->isInternal_) {
2924         // 表示非拓展屏
2925         TLOGW(WmsLogTag::DMS, "Not expandable screen, no need to set dpi");
2926         return;
2927     }
2928     ScreenId mainScreenId = GetDefaultScreenId();
2929     sptr<ScreenSession> screenSession = GetScreenSession(mainScreenId);
2930     if (screenSession == nullptr) {
2931         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
2932         return;
2933     }
2934     float extendDensity = screenSession->GetScreenProperty().GetDensity();
2935     float curResolution = screenSession->GetScreenProperty().GetDensityInCurResolution();
2936     float defaultDensity = screenSession->GetScreenProperty().GetDefaultDensity();
2937     TLOGW(WmsLogTag::DMS, "extendDensity = %{public}f", extendDensity);
2938     session->SetVirtualPixelRatio(extendDensity * g_extendScreenDpiCoef);
2939     session->SetDefaultDensity(defaultDensity * g_extendScreenDpiCoef);
2940     session->SetDensityInCurResolution(curResolution);
2941     ScreenId screenId = session->GetScreenId();
2942     property.SetVirtualPixelRatio(extendDensity * g_extendScreenDpiCoef);
2943     property.SetDefaultDensity(defaultDensity * g_extendScreenDpiCoef);
2944     property.SetDensityInCurResolution(curResolution);
2945     {
2946         std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
2947         phyScreenPropMap_[screenId] = property;
2948     }
2949     return;
2950 }
2951 
GetOrCreateScreenSession(ScreenId screenId)2952 sptr<ScreenSession> ScreenSessionManager::GetOrCreateScreenSession(ScreenId screenId)
2953 {
2954     TLOGW(WmsLogTag::DMS, "ENTER. ScreenId: %{public}" PRIu64 "", screenId);
2955     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2956     if (screenSession) {
2957         TLOGW(WmsLogTag::DMS, "screenSession Exist ScreenId: %{public}" PRIu64, screenId);
2958         return screenSession;
2959     }
2960 
2961     if (g_isPcDevice) {
2962         std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
2963         if (phyScreenPropMap_.size() > 1) {
2964             // pc is none, pad&&phone is mirror
2965             TLOGW(WmsLogTag::DMS, "Only Support one External screen.");
2966             return nullptr;
2967         }
2968     }
2969     screenIdManager_.UpdateScreenId(screenId, screenId);
2970 
2971     ScreenProperty property;
2972     CreateScreenProperty(screenId, property);
2973     TLOGW(WmsLogTag::DMS, "call create screen property end");
2974     screenEventTracker_.RecordEvent("CreateScreenProperty by rsInterface success.");
2975     {
2976         std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
2977         phyScreenPropMap_[screenId] = property;
2978     }
2979 
2980     if (HandleFoldScreenSessionCreate(screenId) == false) {
2981         return nullptr;
2982     }
2983 
2984     sptr<ScreenSession> session = GetScreenSessionInner(screenId, property);
2985     if (session == nullptr) {
2986         TLOGE(WmsLogTag::DMS, "get screen session fail ScreenId: %{public}" PRIu64, screenId);
2987         return session;
2988     }
2989     session->RegisterScreenChangeListener(this);
2990     InitExtendScreenDensity(session, property);
2991     InitAbstractScreenModesInfo(session);
2992     session->groupSmsId_ = 1;
2993     {
2994         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2995         screenSessionMap_[screenId] = session;
2996     }
2997     if (g_isPcDevice) {
2998         SetMultiScreenFrameControl();
2999     }
3000     screenEventTracker_.RecordEvent("create screen session success.");
3001     SetHdrFormats(GetPhyScreenId(screenId), session);
3002     SetColorSpaces(GetPhyScreenId(screenId), session);
3003     SetSupportedRefreshRate(session);
3004     if (session->GetFakeScreenSession() != nullptr) {
3005         std::vector<uint32_t> supportedRefreshRateFake = session->GetSupportedRefreshRate();
3006         sptr<ScreenSession> screenSessionFake = session->GetFakeScreenSession();
3007         screenSessionFake->SetSupportedRefreshRate(std::move(supportedRefreshRateFake));
3008     }
3009     RegisterRefreshRateChangeListener();
3010     TLOGW(WmsLogTag::DMS, "CreateScreenSession success. ScreenId: %{public}" PRIu64 "", screenId);
3011     return session;
3012 }
3013 
HandleFoldScreenSessionCreate(ScreenId screenId)3014 bool ScreenSessionManager::HandleFoldScreenSessionCreate(ScreenId screenId)
3015 {
3016 #ifdef FOLD_ABILITY_ENABLE
3017     if (foldScreenController_ != nullptr) {
3018         // sensor may earlier than screen connect, when physical screen property changed, update
3019         foldScreenController_->UpdateForPhyScreenPropertyChange();
3020         /* folder screen outer screenId is 5 */
3021         if (screenId == SCREEN_ID_MAIN) {
3022             SetPostureAndHallSensorEnabled();
3023             if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()
3024                 || FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
3025                 ScreenSensorConnector::SubscribeTentSensor();
3026             }
3027             isFoldScreenOuterScreenReady_ = true;
3028             if (!FoldScreenStateInternel::IsDualDisplayFoldDevice() && isCoordinationFlag_ == false) {
3029                 return false;
3030             }
3031         }
3032     }
3033 #endif
3034     return true;
3035 }
3036 
SetHdrFormats(ScreenId screenId,sptr<ScreenSession> & session)3037 void ScreenSessionManager::SetHdrFormats(ScreenId screenId, sptr<ScreenSession>& session)
3038 {
3039     TLOGI(WmsLogTag::DMS, "SetHdrFormats %{public}" PRIu64, screenId);
3040     std::vector<ScreenHDRFormat> rsHdrFormat;
3041     auto status = rsInterface_.GetScreenSupportedHDRFormats(screenId, rsHdrFormat);
3042     if (static_cast<StatusCode>(status) != StatusCode::SUCCESS) {
3043         TLOGE(WmsLogTag::DMS, "get hdr format failed! status code: %{public}d", status);
3044     } else {
3045         std::vector<uint32_t> hdrFormat(rsHdrFormat.size());
3046         std::transform(rsHdrFormat.begin(), rsHdrFormat.end(), hdrFormat.begin(), [](int val) {
3047             return static_cast<uint32_t>(val);
3048         });
3049         session->SetHdrFormats(std::move(hdrFormat));
3050     }
3051 }
3052 
SetColorSpaces(ScreenId screenId,sptr<ScreenSession> & session)3053 void ScreenSessionManager::SetColorSpaces(ScreenId screenId, sptr<ScreenSession>& session)
3054 {
3055     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3056         TLOGE(WmsLogTag::DMS, "spaces permission denied!");
3057         return;
3058     }
3059 
3060     TLOGI(WmsLogTag::DMS, "SetColorSpaces %{public}" PRIu64, screenId);
3061     std::vector<GraphicCM_ColorSpaceType> rsColorSpace;
3062     auto status = rsInterface_.GetScreenSupportedColorSpaces(screenId, rsColorSpace);
3063     if (static_cast<StatusCode>(status) != StatusCode::SUCCESS) {
3064         TLOGE(WmsLogTag::DMS, "get color space failed! status code: %{public}d", status);
3065     } else {
3066         std::vector<uint32_t> colorSpace(rsColorSpace.size());
3067         std::transform(rsColorSpace.begin(), rsColorSpace.end(), colorSpace.begin(), [](int val) {
3068             return static_cast<uint32_t>(val);
3069         });
3070         session->SetColorSpaces(std::move(colorSpace));
3071     }
3072 }
3073 
SetSupportedRefreshRate(sptr<ScreenSession> & session)3074 void ScreenSessionManager::SetSupportedRefreshRate(sptr<ScreenSession>& session)
3075 {
3076     std::vector<RSScreenModeInfo> allModes = rsInterface_.GetScreenSupportedModes(
3077         screenIdManager_.ConvertToRsScreenId(GetPhyScreenId(session->screenId_)));
3078     if (allModes.size() == 0) {
3079         TLOGE(WmsLogTag::DMS, "allModes.size() == 0, screenId=%{public}" PRIu64"", session->rsId_);
3080         return;
3081     }
3082     std::set<uint32_t> uniqueRefreshRates;
3083     for (const RSScreenModeInfo& rsScreenModeInfo : allModes) {
3084         uniqueRefreshRates.insert(rsScreenModeInfo.GetScreenRefreshRate());
3085     }
3086     std::vector<uint32_t> supportedRefreshRate(uniqueRefreshRates.begin(), uniqueRefreshRates.end());
3087     session->SetSupportedRefreshRate(std::move(supportedRefreshRate));
3088 }
3089 
GetDefaultScreenId()3090 ScreenId ScreenSessionManager::GetDefaultScreenId()
3091 {
3092     if (defaultScreenId_ == INVALID_SCREEN_ID) {
3093         defaultScreenId_ = rsInterface_.GetDefaultScreenId();
3094         std::ostringstream oss;
3095         oss << "Default screen id : " << defaultScreenId_;
3096         TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
3097         screenEventTracker_.RecordEvent(oss.str());
3098     }
3099     return defaultScreenId_;
3100 }
3101 
WakeUpBegin(PowerStateChangeReason reason)3102 bool ScreenSessionManager::WakeUpBegin(PowerStateChangeReason reason)
3103 {
3104     // 该接口当前只有Power调用
3105     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:WakeUpBegin(%u)", reason);
3106     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3107         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3108             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3109         return false;
3110     }
3111     TLOGI(WmsLogTag::DMS, "[UL_POWER]WakeUpBegin reason: %{public}u", reason);
3112     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_START_DREAM) {
3113         TLOGI(WmsLogTag::DMS, "[UL_POWER]wakeup cannot start dream");
3114         return false;
3115     }
3116     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_END_DREAM) {
3117         NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_END_DREAM, EventStatus::BEGIN, reason);
3118         return BlockScreenWaitPictureFrameByCV(false);
3119     }
3120     currentWakeUpReason_ = reason;
3121     // 多屏协作灭屏不通知锁屏
3122     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3123         isMultiScreenCollaboration_ = true;
3124         return true;
3125     }
3126     lastWakeUpReason_ = reason;
3127     return NotifyDisplayPowerEvent(DisplayPowerEvent::WAKE_UP, EventStatus::BEGIN, reason);
3128 }
3129 
WakeUpEnd()3130 bool ScreenSessionManager::WakeUpEnd()
3131 {
3132     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:WakeUpEnd");
3133     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3134         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3135             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3136         return false;
3137     }
3138     TLOGI(WmsLogTag::DMS, "[UL_POWER]WakeUpEnd enter");
3139     // 多屏协作灭屏不通知锁屏
3140     if (isMultiScreenCollaboration_) {
3141         isMultiScreenCollaboration_ = false;
3142         return true;
3143     }
3144     return NotifyDisplayPowerEvent(DisplayPowerEvent::WAKE_UP, EventStatus::END,
3145         PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
3146 }
3147 
SuspendBegin(PowerStateChangeReason reason)3148 bool ScreenSessionManager::SuspendBegin(PowerStateChangeReason reason)
3149 {
3150     // only power use
3151     powerStateChangeReason_ = reason;
3152     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:SuspendBegin(%u)", reason);
3153     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3154         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3155             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3156         return false;
3157     }
3158     TLOGI(WmsLogTag::DMS, "[UL_POWER]Reason: %{public}u", static_cast<uint32_t>(reason));
3159     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_END_DREAM) {
3160         TLOGI(WmsLogTag::DMS, "[UL_POWER]suspend cannot end dream");
3161         return false;
3162     }
3163     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_START_DREAM) {
3164         NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_START_DREAM, EventStatus::BEGIN, reason);
3165         return BlockScreenWaitPictureFrameByCV(true);
3166     }
3167     gotScreenlockFingerprint_ = false;
3168     lastWakeUpReason_ = PowerStateChangeReason::STATE_CHANGE_REASON_INIT;
3169     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
3170         lastWakeUpReason_ = PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF;
3171     }
3172     // 多屏协作灭屏不通知锁屏
3173     gotScreenOffNotify_  = false;
3174     if (!g_isPcDevice && reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT &&
3175         reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_SUCCESS &&
3176         reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_ON &&
3177         reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
3178         sessionDisplayPowerController_->canCancelSuspendNotify_ = true;
3179     }
3180     sessionDisplayPowerController_->isSuspendBegin_ = true;
3181     sessionDisplayPowerController_->SuspendBegin(reason);
3182     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3183         isMultiScreenCollaboration_ = true;
3184         return true;
3185     }
3186     return NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::BEGIN, reason);
3187 }
3188 
IsSystemSleep()3189 bool ScreenSessionManager::IsSystemSleep()
3190 {
3191     return powerStateChangeReason_ == PowerStateChangeReason::STATE_CHANGE_REASON_SYSTEM ||
3192         powerStateChangeReason_ == PowerStateChangeReason::STATE_CHANGE_REASON_HARD_KEY;
3193 }
3194 
SuspendEnd()3195 bool ScreenSessionManager::SuspendEnd()
3196 {
3197     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3198         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3199             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3200         return false;
3201     }
3202     TLOGI(WmsLogTag::DMS, "[UL_POWER] enter");
3203     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:SuspendEnd");
3204     // 多屏协作灭屏不通知锁屏
3205     if (isMultiScreenCollaboration_) {
3206         isMultiScreenCollaboration_ = false;
3207         return true;
3208     }
3209     return NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::END,
3210         PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
3211 }
3212 
GetInternalScreenId()3213 ScreenId ScreenSessionManager::GetInternalScreenId()
3214 {
3215     ScreenId screenId = SCREEN_ID_INVALID;
3216     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3217     for (auto sessionIt : screenSessionMap_) {
3218         auto screenSession = sessionIt.second;
3219         if (screenSession == nullptr) {
3220             TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
3221             continue;
3222         }
3223         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && screenSession->isInternal_) {
3224             TLOGI(WmsLogTag::DMS, "found screenId = %{public}" PRIu64, sessionIt.first);
3225             screenId = sessionIt.first;
3226             break;
3227         }
3228     }
3229     return screenId;
3230 }
3231 
GetInternalScreenSession()3232 sptr<ScreenSession> ScreenSessionManager::GetInternalScreenSession()
3233 {
3234     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3235     for (auto sessionIt : screenSessionMap_) {
3236         sptr<ScreenSession> screenSession = sessionIt.second;
3237         if (screenSession == nullptr) {
3238             TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
3239             continue;
3240         }
3241         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && screenSession->isInternal_) {
3242             TLOGI(WmsLogTag::DMS, "found screenSession, Id = %{public}" PRIu64, sessionIt.first);
3243             return screenSession;
3244         }
3245     }
3246     return nullptr;
3247 }
3248 
GetInternalAndExternalSession(sptr<ScreenSession> & internalSession,sptr<ScreenSession> & externalSession)3249 void ScreenSessionManager::GetInternalAndExternalSession(sptr<ScreenSession>& internalSession,
3250     sptr<ScreenSession>& externalSession)
3251 {
3252     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3253     for (auto sessionIt : screenSessionMap_) {
3254         auto screenSession = sessionIt.second;
3255         if (screenSession == nullptr) {
3256             TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
3257             continue;
3258         }
3259         if (!screenSession->GetIsCurrentInUse()) {
3260             TLOGE(WmsLogTag::DMS, "screenSession not in use!");
3261             continue;
3262         }
3263         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && screenSession->isInternal_) {
3264             TLOGI(WmsLogTag::DMS, "found internalSession, screenId = %{public}" PRIu64, sessionIt.first);
3265             internalSession = screenSession;
3266         } else {
3267             TLOGI(WmsLogTag::DMS, "found externalSession, screenId = %{public}" PRIu64, sessionIt.first);
3268             externalSession = screenSession;
3269         }
3270     }
3271 }
3272 
SetScreenPowerById(ScreenId screenId,ScreenPowerState state,PowerStateChangeReason reason)3273 bool ScreenSessionManager::SetScreenPowerById(ScreenId screenId, ScreenPowerState state,
3274     PowerStateChangeReason reason)
3275 {
3276     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3277         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3278             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3279         return false;
3280     }
3281     TLOGI(WmsLogTag::DMS, "screen id:%{public}" PRIu64
3282     ", state:%{public}u, reason:%{public}u", screenId, state, static_cast<uint32_t>(reason));
3283 
3284     bool isPowerSet = false;
3285     if (g_isPcDevice) {
3286         isPowerSet = SetScreenPowerByIdForPC(screenId, state);
3287     } else {
3288         isPowerSet = SetScreenPowerByIdDefault(screenId, state);
3289     }
3290     return isPowerSet;
3291 }
3292 
SetScreenPowerByIdForPC(ScreenId screenId,ScreenPowerState state)3293 bool ScreenSessionManager::SetScreenPowerByIdForPC(ScreenId screenId, ScreenPowerState state)
3294 {
3295     std::lock_guard<std::mutex> lock(screenPowerMutex_);
3296     switch (state) {
3297         case ScreenPowerState::POWER_ON: {
3298             TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_ON");
3299 #ifdef WM_MULTI_SCREEN_ENABLE
3300             if (GetIsOuterOnlyMode() && !GetIsOuterOnlyModeBeforePowerOff()) {
3301                 MultiScreenModeChange(screenId, screenId, "on");
3302             }
3303 #endif
3304             break;
3305         }
3306         case ScreenPowerState::POWER_OFF: {
3307             TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_OFF");
3308 #ifdef WM_MULTI_SCREEN_ENABLE
3309             if (!GetIsOuterOnlyMode() && !GetIsOuterOnlyModeBeforePowerOff()) {
3310                 MultiScreenModeChange(screenId, screenId, "off");
3311                 SetIsOuterOnlyModeBeforePowerOff(false);
3312             }
3313 #endif
3314             break;
3315         }
3316         default: {
3317             TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerById state not support");
3318             return false;
3319         }
3320     }
3321     return true;
3322 }
3323 
SetScreenPowerByIdDefault(ScreenId screenId,ScreenPowerState state)3324 bool ScreenSessionManager::SetScreenPowerByIdDefault(ScreenId screenId, ScreenPowerState state)
3325 {
3326     ScreenPowerStatus status;
3327     switch (state) {
3328         case ScreenPowerState::POWER_ON: {
3329             status = ScreenPowerStatus::POWER_STATUS_ON;
3330             TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_ON");
3331             break;
3332         }
3333         case ScreenPowerState::POWER_OFF: {
3334             status = ScreenPowerStatus::POWER_STATUS_OFF;
3335             TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_OFF");
3336             break;
3337         }
3338         default: {
3339             TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerById state not support");
3340             return false;
3341         }
3342     }
3343     CallRsSetScreenPowerStatusSync(screenId, status);
3344     return true;
3345 }
3346 
SetLastScreenMode(sptr<ScreenSession> firstSession,sptr<ScreenSession> secondarySession)3347 void ScreenSessionManager::SetLastScreenMode(sptr<ScreenSession> firstSession, sptr<ScreenSession> secondarySession)
3348 {
3349 #ifdef WM_MULTI_SCREEN_ENABLE
3350     if (firstSession == nullptr || secondarySession == nullptr) {
3351         TLOGE(WmsLogTag::DMS, "first or second screen is null");
3352         return;
3353     }
3354 
3355     ScreenId mainScreenId = SCREEN_ID_INVALID;
3356     MultiScreenMode secondaryScreenMode = MultiScreenMode::SCREEN_MIRROR;
3357     {
3358         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3359         for (auto sessionIt : screenSessionMap_) {
3360             auto screenSession = sessionIt.second;
3361             if (screenSession == nullptr) {
3362                 TLOGW(WmsLogTag::DMS, "screenSession is nullptr!");
3363                 continue;
3364             }
3365             if (screenSession != firstSession && screenSession != secondarySession) {
3366                 continue;
3367             }
3368             if (!screenSession->GetIsCurrentInUse()) {
3369                 TLOGE(WmsLogTag::DMS, "screenSession not in use!");
3370                 continue;
3371             }
3372             ScreenCombination screenCombination = screenSession->GetScreenCombination();
3373             if (screenCombination == ScreenCombination::SCREEN_MAIN) {
3374                 mainScreenId = sessionIt.first;
3375                 TLOGI(WmsLogTag::DMS, "found main screen");
3376             } else if (screenCombination == ScreenCombination::SCREEN_MIRROR) {
3377                 secondaryScreenMode = MultiScreenMode::SCREEN_MIRROR;
3378                 TLOGI(WmsLogTag::DMS, "found mirror screen");
3379             } else if (screenCombination == ScreenCombination::SCREEN_EXTEND) {
3380                 secondaryScreenMode = MultiScreenMode::SCREEN_EXTEND;
3381                 TLOGI(WmsLogTag::DMS, "found extend screen");
3382             } else {
3383                 TLOGE(WmsLogTag::DMS, "screen id or screen mode error");
3384             }
3385         }
3386     }
3387 
3388     if (mainScreenId == SCREEN_ID_INVALID) {
3389         TLOGE(WmsLogTag::DMS, "param error!");
3390         return;
3391     }
3392     MultiScreenManager::GetInstance().SetLastScreenMode(mainScreenId, secondaryScreenMode);
3393 #endif
3394 }
3395 
IsPreBrightAuthFail(void)3396 bool ScreenSessionManager::IsPreBrightAuthFail(void)
3397 {
3398     return lastWakeUpReason_ == PowerStateChangeReason::
3399         STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF;
3400 }
3401 
BlockSetDisplayState(void)3402 bool ScreenSessionManager::BlockSetDisplayState(void)
3403 {
3404     return prePowerStateChangeReason_ == PowerStateChangeReason::POWER_BUTTON;
3405 }
3406 
SetDisplayState(DisplayState state)3407 bool ScreenSessionManager::SetDisplayState(DisplayState state)
3408 {
3409     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3410         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3411             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3412         return false;
3413     }
3414     if (!sessionDisplayPowerController_) {
3415         TLOGE(WmsLogTag::DMS, "[UL_POWER]sessionDisplayPowerController_ is null");
3416         return false;
3417     }
3418     TLOGI(WmsLogTag::DMS, "[UL_POWER] enter");
3419     auto screenIds = GetAllScreenIds();
3420     if (screenIds.empty()) {
3421         TLOGI(WmsLogTag::DMS, "[UL_POWER]no screen info");
3422         return sessionDisplayPowerController_->SetDisplayState(state);
3423     }
3424 
3425     UpdateDisplayState(screenIds, state);
3426     bool ret = sessionDisplayPowerController_->SetDisplayState(state);
3427     if (!ret && state == DisplayState::OFF) {
3428         state = lastDisplayState_;
3429         UpdateDisplayState(screenIds, state);
3430     }
3431     lastDisplayState_ = state;
3432     return ret;
3433 }
3434 
UpdateDisplayState(std::vector<ScreenId> screenIds,DisplayState state)3435 void ScreenSessionManager::UpdateDisplayState(std::vector<ScreenId> screenIds, DisplayState state)
3436 {
3437     for (auto screenId : screenIds) {
3438         sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3439         if (screenSession == nullptr) {
3440             TLOGW(WmsLogTag::DMS, "[UL_POWER]screenId: %{public}" PRIu64, screenId);
3441             continue;
3442         }
3443         screenSession->UpdateDisplayState(state);
3444         TLOGI(WmsLogTag::DMS, "[UL_POWER]displayState: %{public}u",
3445             screenSession->GetScreenProperty().GetDisplayState());
3446     }
3447 }
3448 
BlockScreenOnByCV(void)3449 void ScreenSessionManager::BlockScreenOnByCV(void)
3450 {
3451     if (keyguardDrawnDone_ == false) {
3452         TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOnCV_ set");
3453         needScreenOnWhenKeyguardNotify_ = true;
3454         std::unique_lock<std::mutex> lock(screenOnMutex_);
3455         if (screenOnCV_.wait_for(lock, std::chrono::milliseconds(screenOnDelay_)) == std::cv_status::timeout) {
3456             TLOGI(WmsLogTag::DMS, "[UL_POWER]wait ScreenOnCV_ timeout");
3457         }
3458     }
3459 }
3460 
BlockScreenOffByCV(void)3461 void ScreenSessionManager::BlockScreenOffByCV(void)
3462 {
3463     if (gotScreenOffNotify_ == false) {
3464         TLOGI(WmsLogTag::DMS, "[UL_POWER]delay:%{public}d", screenOffDelay_);
3465         needScreenOffNotify_ = true;
3466         std::unique_lock<std::mutex> lock(screenOffMutex_);
3467         if (screenOffCV_.wait_for(lock, std::chrono::milliseconds(screenOffDelay_)) == std::cv_status::timeout) {
3468             isScreenLockSuspend_ = false;
3469             needScreenOffNotify_ = false;
3470             TLOGI(WmsLogTag::DMS, "[UL_POWER]wait ScreenOffCV_ timeout, isScreenLockSuspend_ is false");
3471         }
3472     }
3473 }
3474 
TryToCancelScreenOff()3475 bool ScreenSessionManager::TryToCancelScreenOff()
3476 {
3477     std::lock_guard<std::mutex> notifyLock(sessionDisplayPowerController_->notifyMutex_);
3478     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3479         TLOGE(WmsLogTag::DMS, "Permission denied!");
3480         return false;
3481     }
3482     TLOGI(WmsLogTag::DMS, "[UL_POWER]about to cancel suspend, can:%{public}d, got:%{public}d, need:%{public}d",
3483         sessionDisplayPowerController_->canCancelSuspendNotify_, gotScreenOffNotify_, needScreenOffNotify_);
3484     if (sessionDisplayPowerController_->canCancelSuspendNotify_) {
3485         sessionDisplayPowerController_->needCancelNotify_ = true;
3486         TLOGI(WmsLogTag::DMS, "[UL_POWER]notify cancel screenoff");
3487         ScreenSessionManager::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_OFF_CANCELED,
3488             EventStatus::BEGIN, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
3489         return true;
3490     }
3491     if (gotScreenOffNotify_ == false && needScreenOffNotify_ == true) {
3492         std::unique_lock <std::mutex> lock(screenOffMutex_);
3493         sessionDisplayPowerController_->canceledSuspend_ = true;
3494         screenOffCV_.notify_all();
3495         needScreenOffNotify_ = false;
3496         TLOGI(WmsLogTag::DMS, "[UL_POWER]cancel wait and notify cancel screenoff");
3497         ScreenSessionManager::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_OFF_CANCELED,
3498             EventStatus::BEGIN, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
3499         return true;
3500     }
3501     TLOGW(WmsLogTag::DMS, "[UL_POWER]failed to cancel suspend");
3502     return false;
3503 }
3504 
ForceSkipScreenOffAnimation()3505 void ScreenSessionManager::ForceSkipScreenOffAnimation()
3506 {
3507     std::lock_guard<std::mutex> notifyLock(sessionDisplayPowerController_->notifyMutex_);
3508     TLOGI(WmsLogTag::DMS, "[UL_POWER]about to skip animation, can:%{public}d, got:%{public}d, need:%{public}d",
3509         sessionDisplayPowerController_->canCancelSuspendNotify_, gotScreenOffNotify_, needScreenOffNotify_);
3510     if (sessionDisplayPowerController_->canCancelSuspendNotify_) {
3511         sessionDisplayPowerController_->skipScreenOffBlock_ = true;
3512         TLOGI(WmsLogTag::DMS, "[UL_POWER]skip screenoff animation");
3513         return;
3514     }
3515     if (gotScreenOffNotify_ == false && needScreenOffNotify_ == true) {
3516         std::unique_lock <std::mutex> lock(screenOffMutex_);
3517         screenOffCV_.notify_all();
3518         needScreenOffNotify_ = false;
3519         TLOGI(WmsLogTag::DMS, "[UL_POWER]skip wait");
3520         return;
3521     }
3522 }
3523 
SetScreenBrightness(uint64_t screenId,uint32_t level)3524 bool ScreenSessionManager::SetScreenBrightness(uint64_t screenId, uint32_t level)
3525 {
3526     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3527         TLOGE(WmsLogTag::DMS, "set screen brightness permission denied!");
3528         return false;
3529     }
3530     TLOGD(WmsLogTag::DMS, "screenId:%{public}" PRIu64", level:%{public}u,", screenId, level);
3531     RSInterfaces::GetInstance().SetScreenBacklight(screenId, level);
3532     return true;
3533 }
3534 
GetScreenBrightness(uint64_t screenId)3535 uint32_t ScreenSessionManager::GetScreenBrightness(uint64_t screenId)
3536 {
3537     uint32_t level = static_cast<uint32_t>(RSInterfaces::GetInstance().GetScreenBacklight(screenId));
3538     TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", level:%{public}u,", screenId, level);
3539     return level;
3540 }
3541 
SetScreenOffDelayTime(int32_t delay)3542 int32_t ScreenSessionManager::SetScreenOffDelayTime(int32_t delay)
3543 {
3544     DmsXcollie dmsXcollie("DMS:SetScreenOffDelayTime", XCOLLIE_TIMEOUT_10S);
3545     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3546         TLOGE(WmsLogTag::DMS, "set screen off delay time permission denied!");
3547         return 0;
3548     }
3549 
3550     if (delay > SCREEN_OFF_MIN_DELAY_TIME && delay < CV_WAIT_SCREENOFF_MS) {
3551         screenOffDelay_ = CV_WAIT_SCREENOFF_MS;
3552     } else if (delay > CV_WAIT_SCREENOFF_MS_MAX) {
3553         screenOffDelay_ = CV_WAIT_SCREENOFF_MS_MAX;
3554     } else {
3555         screenOffDelay_ = delay;
3556     }
3557     TLOGI(WmsLogTag::DMS, "delay:%{public}d, screenOffDelay_:%{public}d",
3558         delay, screenOffDelay_);
3559     return screenOffDelay_;
3560 }
3561 
SetScreenOnDelayTime(int32_t delay)3562 int32_t ScreenSessionManager::SetScreenOnDelayTime(int32_t delay)
3563 {
3564     DmsXcollie dmsXcollie("DMS:SetScreenOnDelayTime", XCOLLIE_TIMEOUT_10S);
3565     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3566         TLOGE(WmsLogTag::DMS, "set screen on delay time permission denied!");
3567         return 0;
3568     }
3569 
3570     if (delay > CV_WAIT_SCREENON_MS) {
3571         screenOnDelay_ = CV_WAIT_SCREENON_MS;
3572     } else {
3573         screenOnDelay_ = delay;
3574     }
3575     TLOGI(WmsLogTag::DMS, "delay:%{public}d, screenOnDelay_:%{public}d",
3576         delay, screenOnDelay_);
3577     return screenOnDelay_;
3578 }
3579 
SetCameraStatus(int32_t cameraStatus,int32_t cameraPosition)3580 void ScreenSessionManager::SetCameraStatus(int32_t cameraStatus, int32_t cameraPosition)
3581 {
3582 #ifdef WM_CAM_MODE_ABILITY_ENABLE
3583     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3584         TLOGE(WmsLogTag::DMS, "set camera status permission denied!");
3585         return;
3586     }
3587 
3588     if ((cameraStatus_ == cameraStatus) && (cameraPosition_ == cameraPosition)) {
3589         return;  // no need to update
3590     }
3591     cameraStatus_ = cameraStatus;
3592     cameraPosition_ = cameraPosition;
3593     TLOGI(WmsLogTag::DMS, "SetCameraStatus, cameraStatus:%{public}d, cameraPosition:%{public}d",
3594         cameraStatus, cameraPosition);
3595 #endif
3596 }
3597 
IsScreenLockSuspend(void)3598 bool ScreenSessionManager::IsScreenLockSuspend(void)
3599 {
3600     return isScreenLockSuspend_;
3601 }
3602 
NotifyDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)3603 void ScreenSessionManager::NotifyDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
3604     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
3605 {
3606     auto clientProxy = GetClientProxy();
3607     if (clientProxy) {
3608         clientProxy->OnDisplayStateChanged(defaultDisplayId, displayInfo, displayInfoMap, type);
3609     }
3610 }
3611 
NotifyScreenshot(DisplayId displayId)3612 void ScreenSessionManager::NotifyScreenshot(DisplayId displayId)
3613 {
3614     auto clientProxy = GetClientProxy();
3615     if (clientProxy) {
3616         clientProxy->OnScreenshot(displayId);
3617     }
3618 }
3619 
SetSpecifiedScreenPower(ScreenId screenId,ScreenPowerState state,PowerStateChangeReason reason)3620 bool ScreenSessionManager::SetSpecifiedScreenPower(ScreenId screenId, ScreenPowerState state,
3621     PowerStateChangeReason reason)
3622 {
3623     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3624         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3625             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3626         return false;
3627     }
3628     TLOGI(WmsLogTag::DMS, "screen id:%{public}" PRIu64 ", state:%{public}u",
3629         screenId, state);
3630 
3631     ScreenPowerStatus status;
3632     switch (state) {
3633         case ScreenPowerState::POWER_ON: {
3634             status = ScreenPowerStatus::POWER_STATUS_ON;
3635             break;
3636         }
3637         case ScreenPowerState::POWER_OFF: {
3638             status = ScreenPowerStatus::POWER_STATUS_OFF;
3639             break;
3640         }
3641         default: {
3642             TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerStatus state not support");
3643             return false;
3644         }
3645     }
3646 
3647     CallRsSetScreenPowerStatusSync(screenId, status);
3648     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3649         return true;
3650     }
3651     return NotifyDisplayPowerEvent(state == ScreenPowerState::POWER_ON ? DisplayPowerEvent::DISPLAY_ON :
3652         DisplayPowerEvent::DISPLAY_OFF, EventStatus::END, reason);
3653 }
3654 
SetScreenPowerForAll(ScreenPowerState state,PowerStateChangeReason reason)3655 bool ScreenSessionManager::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)
3656 {
3657     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3658         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3659             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3660         return false;
3661     }
3662     TLOGI(WmsLogTag::DMS, "[UL_POWER]state: %{public}u, reason: %{public}u",
3663         static_cast<uint32_t>(state), static_cast<uint32_t>(reason));
3664     ScreenPowerStatus status;
3665 
3666     if (!GetPowerStatus(state, reason, status)) {
3667         return false;
3668     }
3669     if (g_isPcDevice && reason == PowerStateChangeReason::POWER_BUTTON && state == ScreenPowerState::POWER_OFF) {
3670         isDeviceShutDown_ = true;
3671     } else {
3672         isDeviceShutDown_ = false;
3673     }
3674     gotScreenOffNotify_  = false;
3675     keyguardDrawnDone_ = false;
3676     TLOGI(WmsLogTag::DMS, "keyguardDrawnDone_ is false");
3677     prePowerStateChangeReason_ = reason;
3678     return SetScreenPower(status, reason);
3679 }
3680 
GetPowerStatus(ScreenPowerState state,PowerStateChangeReason reason,ScreenPowerStatus & status)3681 bool ScreenSessionManager::GetPowerStatus(ScreenPowerState state, PowerStateChangeReason reason,
3682     ScreenPowerStatus& status)
3683 {
3684     switch (state) {
3685         case ScreenPowerState::POWER_ON: {
3686             if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT) {
3687                 // 预亮屏
3688                 status = ScreenPowerStatus::POWER_STATUS_ON_ADVANCED;
3689                 TLOGI(WmsLogTag::DMS, "[UL_POWER]POWER_STATUS_ON_ADVANCED");
3690             } else {
3691                 status = ScreenPowerStatus::POWER_STATUS_ON;
3692                 TLOGI(WmsLogTag::DMS, "[UL_POWER]POWER_STATUS_ON");
3693             }
3694             break;
3695         }
3696         case ScreenPowerState::POWER_OFF: {
3697             if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
3698                 // 预亮屏时指纹认证失败
3699                 status = ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED;
3700                 TLOGI(WmsLogTag::DMS, "[UL_POWER]POWER_STATUS_OFF_ADVANCED");
3701             } else {
3702                 status = ScreenPowerStatus::POWER_STATUS_OFF;
3703                 TLOGI(WmsLogTag::DMS, "[UL_POWER]POWER_STATUS_OFF");
3704             }
3705             rsInterface_.MarkPowerOffNeedProcessOneFrame();
3706             break;
3707         }
3708         case ScreenPowerState::POWER_SUSPEND: {
3709             status = ScreenPowerStatus::POWER_STATUS_SUSPEND;
3710             TLOGI(WmsLogTag::DMS, "[UL_POWER] POWER_SUSPEND");
3711             rsInterface_.MarkPowerOffNeedProcessOneFrame();
3712             break;
3713         }
3714         case ScreenPowerState::POWER_DOZE: {
3715             status = ScreenPowerStatus::POWER_STATUS_DOZE;
3716             TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_DOZE");
3717             break;
3718         }
3719         case ScreenPowerState::POWER_DOZE_SUSPEND: {
3720             status = ScreenPowerStatus::POWER_STATUS_DOZE_SUSPEND;
3721             TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_DOZE_SUSPEND");
3722             break;
3723         }
3724         default: {
3725             TLOGW(WmsLogTag::DMS, "[UL_POWER]not support");
3726             return false;
3727         }
3728     }
3729     return true;
3730 }
3731 
ExitCoordination(const std::string & reason)3732 void ScreenSessionManager::ExitCoordination(const std::string& reason)
3733 {
3734 #ifdef FOLD_ABILITY_ENABLE
3735     if (GetFoldDisplayMode() != FoldDisplayMode::COORDINATION) {
3736         return;
3737     }
3738     if (foldScreenController_ != nullptr) {
3739         TLOGI(WmsLogTag::DMS, "[UL_POWER] reason:%{public}s", reason.c_str());
3740         foldScreenController_->ExitCoordination();
3741     }
3742 #endif
3743 }
3744 
TryToRecoverFoldDisplayMode(ScreenPowerStatus status)3745 void ScreenSessionManager::TryToRecoverFoldDisplayMode(ScreenPowerStatus status)
3746 {
3747 #ifdef FOLD_ABILITY_ENABLE
3748     if (foldScreenController_ == nullptr) {
3749         TLOGW(WmsLogTag::DMS, "foldScreenController_ is null");
3750         return;
3751     }
3752     if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED ||
3753         status == ScreenPowerStatus::POWER_STATUS_OFF_FAKE || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3754         status == ScreenPowerStatus::POWER_STATUS_DOZE) {
3755         foldScreenController_->RecoverDisplayMode();
3756     }
3757 #endif
3758 }
3759 
SetScreenPower(ScreenPowerStatus status,PowerStateChangeReason reason)3760 bool ScreenSessionManager::SetScreenPower(ScreenPowerStatus status, PowerStateChangeReason reason)
3761 {
3762     TLOGI(WmsLogTag::DMS, "[UL_POWER] enter status:%{public}u, reason:%{public}u", status, reason);
3763     auto screenIds = GetAllScreenIds();
3764     if (screenIds.empty()) {
3765         TLOGI(WmsLogTag::DMS, "[UL_POWER] screenIds empty");
3766         return false;
3767     }
3768 
3769     if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3770         status == ScreenPowerStatus::POWER_STATUS_DOZE) {
3771         ExitCoordination("Press PowerKey");
3772     }
3773     DisplayPowerEvent notifyEvent = DisplayPowerEvent::DISPLAY_OFF;
3774     auto iter = SCREEN_STATUS_POWER_EVENT_MAP.find(status);
3775     if (iter != SCREEN_STATUS_POWER_EVENT_MAP.end()) {
3776         notifyEvent = iter->second;
3777     }
3778     if (((status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3779         status == ScreenPowerStatus::POWER_STATUS_DOZE) &&
3780         gotScreenlockFingerprint_ == true) &&
3781         prePowerStateChangeReason_ != PowerStateChangeReason::STATE_CHANGE_REASON_SHUT_DOWN) {
3782         gotScreenlockFingerprint_ = false;
3783         TLOGI(WmsLogTag::DMS, "[UL_POWER] screenlockFingerprint or shutdown");
3784         return NotifyDisplayPowerEvent(notifyEvent, EventStatus::END, reason);
3785     }
3786 #ifdef FOLD_ABILITY_ENABLE
3787     if (foldScreenController_ != nullptr) {
3788         CallRsSetScreenPowerStatusSyncForFold(status);
3789         CallRsSetScreenPowerStatusSyncForExtend(screenIds, status);
3790         TryToRecoverFoldDisplayMode(status);
3791     } else {
3792         SetRsSetScreenPowerStatusSync(screenIds, status);
3793     }
3794 #else
3795     SetRsSetScreenPowerStatusSync(screenIds, status);
3796 #endif
3797     HandlerSensor(status, reason);
3798     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3799         return true;
3800     }
3801     if ((status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3802         status == ScreenPowerStatus::POWER_STATUS_DOZE) &&
3803         gotScreenlockFingerprint_ == true) {
3804         gotScreenlockFingerprint_ = false;
3805     }
3806 
3807     return NotifyDisplayPowerEvent(notifyEvent, EventStatus::END, reason);
3808 }
3809 
SetRsSetScreenPowerStatusSync(std::vector<ScreenId> & screenIds,ScreenPowerStatus status)3810 void ScreenSessionManager::SetRsSetScreenPowerStatusSync(std::vector<ScreenId>& screenIds,
3811     ScreenPowerStatus status)
3812 {
3813     if (g_isPcDevice && status == ScreenPowerStatus::POWER_STATUS_ON) {
3814         std::sort(screenIds.begin(), screenIds.end(), SortByScreenId);
3815         for (auto screenId : screenIds) {
3816             TLOGI(WmsLogTag::DMS, "[UL_POWER] Power on, screen id is %{public}d", (int)screenId);
3817             if (GetIsOuterOnlyMode() == true && screenId == SCREEN_ID_FULL) {
3818                 TLOGI(WmsLogTag::DMS, "Power on skip");
3819                 continue;
3820             }
3821             CallRsSetScreenPowerStatusSync(screenId, status);
3822         }
3823     } else if (g_isPcDevice && (status == ScreenPowerStatus::POWER_STATUS_OFF ||
3824         status == ScreenPowerStatus::POWER_STATUS_SUSPEND)) {
3825             std::sort(screenIds.begin(), screenIds.end(), SortByScreenId);
3826             std::reverse(screenIds.begin(), screenIds.end());
3827             for (auto screenId : screenIds) {
3828                 TLOGI(WmsLogTag::DMS, "[UL_POWER] Power off, screen id is %{public}d", (int)screenId);
3829                 CallRsSetScreenPowerStatusSync(screenId, status);
3830             }
3831     } else {
3832         for (auto screenId : screenIds) {
3833             CallRsSetScreenPowerStatusSync(screenId, status);
3834         }
3835     }
3836 }
3837 
CallRsSetScreenPowerStatusSyncForExtend(const std::vector<ScreenId> & screenIds,ScreenPowerStatus status)3838 void ScreenSessionManager::CallRsSetScreenPowerStatusSyncForExtend(const std::vector<ScreenId>& screenIds,
3839     ScreenPowerStatus status)
3840 {
3841     for (auto screenId : screenIds) {
3842         auto session = GetScreenSession(screenId);
3843         if (session && session->GetScreenProperty().GetScreenType() == ScreenType::REAL && !session->isInternal_) {
3844             CallRsSetScreenPowerStatusSync(screenId, status);
3845         }
3846     }
3847 }
3848 #ifdef FOLD_ABILITY_ENABLE
SetScreenPowerForFold(ScreenPowerStatus status)3849 void ScreenSessionManager::SetScreenPowerForFold(ScreenPowerStatus status)
3850 {
3851     if (foldScreenController_ == nullptr) {
3852         TLOGW(WmsLogTag::DMS, "foldScreenController_ is null");
3853         return;
3854     }
3855     SetScreenPowerForFold(foldScreenController_->GetCurrentScreenId(), status);
3856 }
3857 
SetScreenPowerForFold(ScreenId screenId,ScreenPowerStatus status)3858 void ScreenSessionManager::SetScreenPowerForFold(ScreenId screenId, ScreenPowerStatus status)
3859 {
3860     if (status != ScreenPowerStatus::POWER_STATUS_OFF) {
3861         SetRSScreenPowerStatus(screenId, status);
3862         return;
3863     }
3864     static bool isNeedScreenOffDevice =
3865         (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() ||
3866         FoldScreenStateInternel::IsDualDisplayFoldDevice() ||
3867         FoldScreenStateInternel::IsSingleDisplayFoldDevice());
3868     if ((lastPowerForAllStatus_.load() == ScreenPowerStatus::POWER_STATUS_ON_ADVANCED ||
3869         lastPowerForAllStatus_.load() == ScreenPowerStatus::POWER_STATUS_SUSPEND) &&
3870         screenId == SCREEN_ID_MAIN && lastScreenId_.load() == SCREEN_ID_MAIN && isNeedScreenOffDevice) {
3871         if (!IsInAod()) {
3872             TLOGW(WmsLogTag::DMS, "preStatus:%{public}d, screenId:%{public}" PRIu64"",
3873                 lastPowerForAllStatus_.load(), screenId);
3874             SetRSScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
3875             lastScreenId_ = SCREEN_ID_INVALID;
3876             lastPowerForAllStatus_ = ScreenPowerStatus::INVALID_POWER_STATUS;
3877         }
3878     }
3879     SetRSScreenPowerStatus(screenId, status);
3880 }
3881 
TriggerDisplayModeUpdate(FoldDisplayMode targetDisplayMode)3882 void ScreenSessionManager::TriggerDisplayModeUpdate(FoldDisplayMode targetDisplayMode)
3883 {
3884     auto updateDisplayModeTask = [=] {
3885         TLOGNI(WmsLogTag::DMS, "start change displaymode to lastest mode");
3886         foldScreenController_->SetDisplayMode(targetDisplayMode);
3887     };
3888     taskScheduler_->PostAsyncTask(updateDisplayModeTask, "updateDisplayModeTask");
3889 }
3890 #endif
CallRsSetScreenPowerStatusSync(ScreenId screenId,ScreenPowerStatus status)3891 void ScreenSessionManager::CallRsSetScreenPowerStatusSync(ScreenId screenId, ScreenPowerStatus status)
3892 {
3893     auto rsSetScreenPowerStatusTask = [=] {
3894         bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
3895         if (phyMirrorEnable && !g_isPcDevice) {
3896             auto screenSession = GetScreenSession(screenId);
3897             if (screenSession == nullptr) {
3898                 return;
3899             }
3900             auto sourceMode = screenSession->GetSourceMode();
3901             if (status != ScreenPowerStatus::POWER_STATUS_ON &&
3902                 powerStateChangeReason_ == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3903                 return;
3904             }
3905             if (sourceMode == ScreenSourceMode::SCREEN_UNIQUE &&
3906                 status != ScreenPowerStatus::POWER_STATUS_ON &&
3907                 powerStateChangeReason_ == PowerStateChangeReason::STATE_CHANGE_REASON_HARD_KEY) {
3908                 return;
3909             }
3910         }
3911         SetRSScreenPowerStatus(screenId, status);
3912     };
3913     screenPowerTaskScheduler_->PostVoidSyncTask(rsSetScreenPowerStatusTask, "rsInterface_.SetScreenPowerStatus task");
3914 }
3915 
CallRsSetScreenPowerStatusSyncForFold(ScreenPowerStatus status)3916 void ScreenSessionManager::CallRsSetScreenPowerStatusSyncForFold(ScreenPowerStatus status)
3917 {
3918 #ifdef FOLD_ABILITY_ENABLE
3919     auto rsSetScreenPowerStatusTask = [=] {
3920         if (foldScreenController_ == nullptr) {
3921             TLOGNW(WmsLogTag::DMS, "foldScreenController_ is null");
3922             return;
3923         }
3924         ScreenId screenId = foldScreenController_->GetCurrentScreenId();
3925         lastPowerForAllStatus_.store(status);
3926         lastScreenId_.store(screenId);
3927         SetRSScreenPowerStatus(screenId, status);
3928     };
3929     screenPowerTaskScheduler_->PostVoidSyncTask(rsSetScreenPowerStatusTask, "rsInterface_.SetScreenPowerStatus task");
3930 #endif
3931 }
3932 
SetKeyguardDrawnDoneFlag(bool flag)3933 void ScreenSessionManager::SetKeyguardDrawnDoneFlag(bool flag)
3934 {
3935     keyguardDrawnDone_ = flag;
3936 }
3937 
HandlerSensor(ScreenPowerStatus status,PowerStateChangeReason reason)3938 void ScreenSessionManager::HandlerSensor(ScreenPowerStatus status, PowerStateChangeReason reason)
3939 {
3940     if (!ScreenSceneConfig::IsSupportRotateWithSensor()) {
3941         TLOGW(WmsLogTag::DMS, "not supportRotateWithSensor.");
3942         return;
3943     }
3944     if (status == ScreenPowerStatus::POWER_STATUS_ON) {
3945         DmsXcollie dmsXcollie("DMS:SubscribeRotationSensor", XCOLLIE_TIMEOUT_10S);
3946         TLOGI(WmsLogTag::DMS, "subscribe rotation and posture sensor when phone turn on");
3947         ScreenSensorConnector::SubscribeRotationSensor();
3948 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
3949         if (g_foldScreenFlag && reason != PowerStateChangeReason::STATE_CHANGE_REASON_DISPLAY_SWITCH) {
3950             if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
3951                 SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
3952                 SecondaryFoldSensorManager::GetInstance().PowerKeySetScreenActiveRect();
3953             } else {
3954                 FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
3955             }
3956         } else {
3957             TLOGI(WmsLogTag::DMS, "not fold product, switch screen reason, failed register posture.");
3958         }
3959 #endif
3960     } else if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3961         status == ScreenPowerStatus::POWER_STATUS_DOZE || status == ScreenPowerStatus::POWER_STATUS_DOZE_SUSPEND) {
3962         UnregisterInHandlerSensorWithPowerOff(reason);
3963     } else {
3964         TLOGI(WmsLogTag::DMS, "SetScreenPower state not support");
3965         screenEventTracker_.RecordEvent("HandlerSensor start!");
3966     }
3967 }
3968 
UnregisterInHandlerSensorWithPowerOff(PowerStateChangeReason reason)3969 void ScreenSessionManager::UnregisterInHandlerSensorWithPowerOff(PowerStateChangeReason reason)
3970 {
3971     TLOGI(WmsLogTag::DMS, "unsubscribe sensor when off");
3972     if (isMultiScreenCollaboration_) {
3973         TLOGI(WmsLogTag::DMS, "[UL_POWER]MultiScreenCollaboration, not unsubscribe rotation sensor");
3974     } else {
3975         DmsXcollie dmsXcollie("DMS:UnsubscribeRotationSensor", XCOLLIE_TIMEOUT_10S);
3976         ScreenSensorConnector::UnsubscribeRotationSensor();
3977     }
3978 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
3979     if (g_foldScreenFlag && reason != PowerStateChangeReason::STATE_CHANGE_REASON_DISPLAY_SWITCH &&
3980         !FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
3981         if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
3982             SecondaryFoldSensorManager::GetInstance().UnRegisterPostureCallback();
3983             SecondaryFoldSensorManager::GetInstance().isPowerRectExe_ = false;
3984         } else {
3985             FoldScreenSensorManager::GetInstance().UnRegisterPostureCallback();
3986         }
3987     } else {
3988         TLOGI(WmsLogTag::DMS, "not fold product, failed unregister posture.");
3989     }
3990 #endif
3991 }
3992 
BootFinishedCallback(const char * key,const char * value,void * context)3993 void ScreenSessionManager::BootFinishedCallback(const char *key, const char *value, void *context)
3994 {
3995     if (strcmp(key, BOOTEVENT_BOOT_COMPLETED.c_str()) == 0 && strcmp(value, "true") == 0) {
3996         TLOGI(WmsLogTag::DMS, "boot animation finished");
3997         auto &that = *reinterpret_cast<ScreenSessionManager *>(context);
3998         that.SetRotateLockedFromSettingData();
3999         that.SetDpiFromSettingData();
4000         that.SetExtendScreenDpi();
4001         that.UpdateDisplayState(that.GetAllScreenIds(), DisplayState::ON);
4002         that.RegisterSettingDpiObserver();
4003         that.RegisterSettingExtendScreenDpiObserver();
4004         if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
4005             that.RegisterSettingDuringCallStateObserver();
4006         }
4007         if (that.foldScreenPowerInit_ != nullptr) {
4008             that.foldScreenPowerInit_();
4009         }
4010         that.RegisterSettingRotationObserver();
4011         if (that.defaultDpi) {
4012             auto ret = ScreenSettingHelper::SetSettingDefaultDpi(that.defaultDpi, SET_SETTING_DPI_KEY);
4013             if (!ret) {
4014                 TLOGE(WmsLogTag::DMS, "set setting defaultDpi failed");
4015             } else {
4016                 TLOGI(WmsLogTag::DMS, "set setting defaultDpi:%{public}d", that.defaultDpi);
4017             }
4018         }
4019 #ifdef FOLD_ABILITY_ENABLE
4020         if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
4021             auto screenSession = that.GetDefaultScreenSession();
4022             if (screenSession == nullptr) {
4023                 TLOGE(WmsLogTag::DMS, "screen session is null!");
4024                 return;
4025             }
4026             ScreenId screenId = screenSession->GetScreenId();
4027             SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
4028             TLOGI(WmsLogTag::DMS, "SuperFoldStatus: %{public}u", status);
4029             that.OnSuperFoldStatusChange(screenId, status);
4030             float sensorRotation = screenSession->GetSensorRotation();
4031             TLOGI(WmsLogTag::DMS, "sensorRotation: %{public}f", sensorRotation);
4032             if (sensorRotation >= 0.0f) {
4033                 that.OnSensorRotationChange(sensorRotation, screenId);
4034             }
4035             screenSession->PropertyChange(screenSession->GetScreenProperty(),
4036                 ScreenPropertyChangeReason::SUPER_FOLD_STATUS_CHANGE);
4037         }
4038 #endif
4039     }
4040 }
4041 
SetFoldScreenPowerInit(std::function<void ()> foldScreenPowerInit)4042 void ScreenSessionManager::SetFoldScreenPowerInit(std::function<void()> foldScreenPowerInit)
4043 {
4044     foldScreenPowerInit_ = foldScreenPowerInit;
4045 }
4046 
SetRotateLockedFromSettingData()4047 void ScreenSessionManager::SetRotateLockedFromSettingData()
4048 {
4049     uint32_t autoRotateStatus = AUTO_ROTATE_OFF;  // 0代表自动旋转关闭,1代表自动旋转打开
4050     bool islocked = true;
4051     // ret为true表示从数据库读到了值,并赋给了autoRotateStatus
4052     bool ret = ScreenSettingHelper::GetSettingValue(autoRotateStatus, SETTING_LOCKED_KEY);
4053     TLOGI(WmsLogTag::DMS, "get autoRotateStatus from settingdata: %{public}u", autoRotateStatus);
4054     if (autoRotateStatus) {
4055         islocked =false;
4056     }
4057     if (ret) {
4058         TLOGI(WmsLogTag::DMS, "get islocked success");
4059         SetScreenRotationLockedFromJs(islocked);
4060     }
4061 }
4062 
RegisterSettingDpiObserver()4063 void ScreenSessionManager::RegisterSettingDpiObserver()
4064 {
4065     TLOGI(WmsLogTag::DMS, "Register Setting Dpi Observer");
4066     SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetDpiFromSettingData(); };
4067     ScreenSettingHelper::RegisterSettingDpiObserver(updateFunc);
4068 }
4069 
SetDpiFromSettingData()4070 void ScreenSessionManager::SetDpiFromSettingData()
4071 {
4072     uint32_t settingDpi;
4073     bool ret = ScreenSettingHelper::GetSettingDpi(settingDpi);
4074     if (!ret) {
4075         settingDpi = defaultDpi;
4076         TLOGW(WmsLogTag::DMS, "get setting dpi failed,use default dpi,defaultDpi: %{public}u", settingDpi);
4077     } else {
4078         TLOGI(WmsLogTag::DMS, "get setting dpi success,settingDpi: %{public}u", settingDpi);
4079     }
4080     if (settingDpi >= DOT_PER_INCH_MINIMUM_VALUE && settingDpi <= DOT_PER_INCH_MAXIMUM_VALUE
4081         && cachedSettingDpi_ != settingDpi) {
4082         cachedSettingDpi_ = settingDpi;
4083         float dpi = static_cast<float>(settingDpi) / BASELINE_DENSITY;
4084         ScreenId defaultScreenId = GetDefaultScreenId();
4085         if (g_isPcDevice) {
4086             ScreenId screenId = screenIdManager_.ConvertToSmsScreenId(RS_ID_DEFAULT);
4087             if (screenId != SCREEN_ID_INVALID) {
4088                 TLOGI(WmsLogTag::DMS, "get ScreenId:%{public}" PRIu64" for rsId successful", screenId);
4089                 defaultScreenId = screenId;
4090             }
4091         }
4092         SetVirtualPixelRatio(defaultScreenId, dpi);
4093         if (g_isPcDevice) {
4094             SetExtendPixelRatio(dpi * g_extendScreenDpiCoef);
4095         }
4096     } else {
4097         TLOGE(WmsLogTag::DMS, "setting dpi error, settingDpi: %{public}d", settingDpi);
4098     }
4099 }
4100 
SetExtendPixelRatio(const float & dpi)4101 void ScreenSessionManager::SetExtendPixelRatio(const float& dpi)
4102 {
4103     auto screenIds = GetAllScreenIds();
4104     if (screenIds.empty()) {
4105         TLOGE(WmsLogTag::DMS, "no screenId");
4106         return;
4107     }
4108     for (auto screenId : screenIds) {
4109         auto screenSession = GetScreenSession(screenId);
4110         if (screenSession == nullptr) {
4111             TLOGE(WmsLogTag::DMS, "screensession is nullptr, screenId: %{public}" PRIu64"", screenId);
4112             continue;
4113         }
4114         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && !screenSession->isInternal_) {
4115             SetVirtualPixelRatio(screenId, dpi);
4116         }
4117     }
4118 }
4119 
GetAllScreenIds()4120 std::vector<ScreenId> ScreenSessionManager::GetAllScreenIds()
4121 {
4122     std::vector<ScreenId> res;
4123     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4124     for (const auto& iter : screenSessionMap_) {
4125         res.emplace_back(iter.first);
4126     }
4127     return res;
4128 }
4129 
GetPhysicalScreenIds(std::vector<ScreenId> & screenIds)4130 DMError ScreenSessionManager::GetPhysicalScreenIds(std::vector<ScreenId>& screenIds)
4131 {
4132     TLOGI(WmsLogTag::DMS, "enter");
4133     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4134         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
4135             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4136         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4137     }
4138 
4139     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4140     for (const auto& iter : screenSessionMap_) {
4141         auto screenSession = iter.second;
4142         auto screenId = iter.first;
4143         if (screenSession == nullptr) {
4144             TLOGE(WmsLogTag::DMS, "screensession is nullptr, screenId: %{public}" PRIu64, screenId);
4145             continue;
4146         }
4147         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL
4148             && screenId != SCREEN_ID_INVALID) {
4149             screenIds.emplace_back(screenId);
4150         }
4151     }
4152     return DMError::DM_OK;
4153 }
4154 
GetDisplayState(DisplayId displayId)4155 DisplayState ScreenSessionManager::GetDisplayState(DisplayId displayId)
4156 {
4157     return sessionDisplayPowerController_->GetDisplayState(displayId);
4158 }
4159 
NotifyDisplayEvent(DisplayEvent event)4160 void ScreenSessionManager::NotifyDisplayEvent(DisplayEvent event)
4161 {
4162     TLOGI(WmsLogTag::DMS, "[UL_POWER] receive keyguardDrawnDone");
4163     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4164         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
4165             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4166         return;
4167     }
4168     sessionDisplayPowerController_->NotifyDisplayEvent(event);
4169     if (event == DisplayEvent::KEYGUARD_DRAWN) {
4170         keyguardDrawnDone_ = true;
4171         TLOGI(WmsLogTag::DMS, "[UL_POWER]keyguardDrawnDone_ is true");
4172         if (needScreenOnWhenKeyguardNotify_) {
4173             std::unique_lock <std::mutex> lock(screenOnMutex_);
4174             screenOnCV_.notify_all();
4175             TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOnCV_ notify one");
4176             needScreenOnWhenKeyguardNotify_ = false;
4177         }
4178     }
4179     if (event == DisplayEvent::SCREEN_LOCK_SUSPEND) {
4180         TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock suspend");
4181         if (isPhyScreenConnected_) {
4182             isScreenLockSuspend_ = false;
4183             TLOGI(WmsLogTag::DMS, "[UL_POWER]isScreenLockSuspend__  is false");
4184         } else {
4185             isScreenLockSuspend_ = true;
4186         }
4187         SetGotScreenOffAndWakeUpBlock();
4188     }
4189     if (event == DisplayEvent::SCREEN_LOCK_OFF) {
4190         TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock off");
4191         isScreenLockSuspend_ = false;
4192         TLOGI(WmsLogTag::DMS, "[UL_POWER]isScreenLockSuspend__  is false");
4193         SetGotScreenOffAndWakeUpBlock();
4194     }
4195     if (event == DisplayEvent::SCREEN_LOCK_FINGERPRINT) {
4196         TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock fingerprint");
4197         gotScreenlockFingerprint_ = true;
4198         SetGotScreenOffAndWakeUpBlock();
4199     }
4200     if (event == DisplayEvent::SCREEN_LOCK_DOZE_FINISH) {
4201         TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock doze finish");
4202         SetGotScreenOffAndWakeUpBlock();
4203     }
4204     WakeUpPictureFrameBlock(event);
4205 }
4206 
SetGotScreenOffAndWakeUpBlock()4207 void ScreenSessionManager::SetGotScreenOffAndWakeUpBlock()
4208 {
4209     gotScreenOffNotify_ = true;
4210     if (needScreenOffNotify_) {
4211         ScreenOffCVNotify();
4212     }
4213 }
4214 
ScreenOffCVNotify(void)4215 void ScreenSessionManager::ScreenOffCVNotify(void)
4216 {
4217     std::unique_lock <std::mutex> lock(screenOffMutex_);
4218     screenOffCV_.notify_all();
4219     needScreenOffNotify_ = false;
4220     TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOffCV_ notify one");
4221 }
4222 
GetScreenPower(ScreenId screenId)4223 ScreenPowerState ScreenSessionManager::GetScreenPower(ScreenId screenId)
4224 {
4225     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4226         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
4227             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4228         return ScreenPowerState::INVALID_STATE;
4229     }
4230     auto state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance().GetScreenPowerStatus(screenId));
4231     std::ostringstream oss;
4232     oss << "GetScreenPower state:" << static_cast<uint32_t>(state) << " screenId:" << static_cast<uint64_t>(screenId);
4233     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
4234     screenEventTracker_.RecordEvent(oss.str());
4235     return state;
4236 }
4237 
GetScreenPower()4238 ScreenPowerState ScreenSessionManager::GetScreenPower()
4239 {
4240     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4241         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
4242             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4243         return ScreenPowerState::INVALID_STATE;
4244     }
4245     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetScreenPower");
4246     ScreenPowerState state = ScreenPowerState::INVALID_STATE;
4247 #ifdef FOLD_ABILITY_ENABLE
4248     if (!g_foldScreenFlag || FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
4249         state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance()
4250             .GetScreenPowerStatus(GetDefaultScreenId()));
4251     } else {
4252         state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance()
4253             .GetScreenPowerStatus(foldScreenController_->GetCurrentScreenId()));
4254     }
4255 #else
4256     state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance()
4257             .GetScreenPowerStatus(foldScreenController_->GetCurrentScreenId()));
4258 #endif
4259     std::ostringstream oss;
4260     oss << "GetScreenPower state:" << static_cast<uint32_t>(state);
4261     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
4262     screenEventTracker_.RecordEvent(oss.str());
4263     return state;
4264 }
4265 
IsScreenRotationLocked(bool & isLocked)4266 DMError ScreenSessionManager::IsScreenRotationLocked(bool& isLocked)
4267 {
4268     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4269         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4270             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4271         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4272     }
4273     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
4274     if (screenSession == nullptr) {
4275         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
4276         return DMError::DM_ERROR_INVALID_PARAM;
4277     }
4278     isLocked = screenSession->IsScreenRotationLocked();
4279     TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
4280     return DMError::DM_OK;
4281 }
4282 
SetScreenRotationLocked(bool isLocked)4283 DMError ScreenSessionManager::SetScreenRotationLocked(bool isLocked)
4284 {
4285     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4286         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4287             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4288         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4289     }
4290     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
4291     if (screenSession == nullptr) {
4292         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
4293         return DMError::DM_ERROR_INVALID_PARAM;
4294     }
4295     screenSession->SetScreenRotationLocked(isLocked);
4296     TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
4297     return DMError::DM_OK;
4298 }
4299 
SetScreenRotationLockedFromJs(bool isLocked)4300 DMError ScreenSessionManager::SetScreenRotationLockedFromJs(bool isLocked)
4301 {
4302     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4303         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4304             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4305         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4306     }
4307     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
4308     if (screenSession == nullptr) {
4309         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
4310         return DMError::DM_ERROR_INVALID_PARAM;
4311     }
4312     screenSession->SetScreenRotationLockedFromJs(isLocked);
4313     TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
4314     return DMError::DM_OK;
4315 }
4316 
NotifyAndPublishEvent(sptr<DisplayInfo> displayInfo,ScreenId screenId,sptr<ScreenSession> screenSession)4317 void ScreenSessionManager::NotifyAndPublishEvent(sptr<DisplayInfo> displayInfo, ScreenId screenId,
4318     sptr<ScreenSession> screenSession)
4319 {
4320     if (displayInfo == nullptr || screenSession == nullptr) {
4321         TLOGE(WmsLogTag::DMS, "error, displayInfo or screenSession is nullptr");
4322         return;
4323     }
4324     NotifyDisplayChanged(displayInfo, DisplayChangeEvent::UPDATE_ROTATION);
4325     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
4326     UpdateDisplayScaleState(screenId);
4327     std::map<DisplayId, sptr<DisplayInfo>> emptyMap;
4328     NotifyDisplayStateChange(GetDefaultScreenId(), screenSession->ConvertToDisplayInfo(),
4329         emptyMap, DisplayStateChangeType::UPDATE_ROTATION);
4330     std::string identity = IPCSkeleton::ResetCallingIdentity();
4331     ScreenSessionPublish::GetInstance().PublishDisplayRotationEvent(
4332         displayInfo->GetScreenId(), displayInfo->GetRotation());
4333     IPCSkeleton::SetCallingIdentity(identity);
4334 }
4335 
UpdateScreenDirectionInfo(ScreenId screenId,const ScreenDirectionInfo & directionInfo,ScreenPropertyChangeType screenPropertyChangeType,const RRect & bounds)4336 void ScreenSessionManager::UpdateScreenDirectionInfo(ScreenId screenId, const ScreenDirectionInfo& directionInfo,
4337     ScreenPropertyChangeType screenPropertyChangeType, const RRect& bounds)
4338 {
4339     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4340         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4341             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4342         return;
4343     }
4344     if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_END) {
4345         TLOGI(WmsLogTag::DMS, "ROTATION_END");
4346         return;
4347     }
4348     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4349     if (screenSession == nullptr) {
4350         TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"",
4351             screenId);
4352         return;
4353     }
4354     float screenComponentRotation = directionInfo.screenRotation_;
4355     float rotation = directionInfo.rotation_;
4356     float phyRotation = directionInfo.phyRotation_;
4357     screenSession->SetPhysicalRotation(phyRotation);
4358     screenSession->SetScreenComponentRotation(screenComponentRotation);
4359     screenSession->UpdateRotationOrientation(rotation, GetFoldDisplayMode(), bounds);
4360     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", rotation: %{public}f, screenComponentRotation: %{public}f",
4361         screenId, rotation, screenComponentRotation);
4362 }
4363 
UpdateScreenRotationProperty(ScreenId screenId,const RRect & bounds,float rotation,ScreenPropertyChangeType screenPropertyChangeType,bool isSwitchUser)4364 void ScreenSessionManager::UpdateScreenRotationProperty(ScreenId screenId, const RRect& bounds, float rotation,
4365     ScreenPropertyChangeType screenPropertyChangeType, bool isSwitchUser)
4366 {
4367     std::ostringstream oss;
4368     std::string changeType = TransferPropertyChangeTypeToString(screenPropertyChangeType);
4369     oss << "screenId: " << screenId << " rotation: " << rotation << " width: " << bounds.rect_.width_ \
4370         << " height: " << bounds.rect_.height_ << " type: " << changeType;
4371     screenEventTracker_.RecordBoundsEvent(oss.str());
4372     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4373         TLOGE(WmsLogTag::DMS, "permission denied!");
4374         return;
4375     }
4376     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4377     if (screenSession == nullptr) {
4378         TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"", screenId);
4379         return;
4380     }
4381     UpdateScreenRotationPropertyForRs(screenSession, screenPropertyChangeType, bounds, rotation, isSwitchUser);
4382     {
4383         std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
4384         screenSession->UpdatePropertyAfterRotation(bounds, rotation, GetFoldDisplayMode());
4385     }
4386     if (g_isPcDevice) {
4387         sptr<ScreenSession> physicalScreen = GetPhysicalScreenSession(screenSession->GetRSScreenId());
4388         if (physicalScreen) {
4389             physicalScreen->UpdatePropertyAfterRotation(bounds, rotation, GetFoldDisplayMode());
4390         }
4391         NotifyScreenModeChange();
4392     }
4393     sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
4394     NotifyAndPublishEvent(displayInfo, screenId, screenSession);
4395 }
4396 
UpdateScreenRotationPropertyForRs(sptr<ScreenSession> & screenSession,ScreenPropertyChangeType screenPropertyChangeType,const RRect & bounds,float rotation,bool isSwitchUser)4397 void ScreenSessionManager::UpdateScreenRotationPropertyForRs(sptr<ScreenSession>& screenSession,
4398     ScreenPropertyChangeType screenPropertyChangeType, const RRect& bounds, float rotation, bool isSwitchUser)
4399 {
4400     DmsXcollie dmsXcollie("DMS:UpdateScreenRotationProperty:CacheForRotation", XCOLLIE_TIMEOUT_10S);
4401     if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_BEGIN) {
4402         // Rs is used to mark the start of the rotation animation
4403         TLOGI(WmsLogTag::DMS, "EnableCacheForRotation");
4404         RSInterfaces::GetInstance().EnableCacheForRotation();
4405     } else if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_END) {
4406         // Rs is used to mark the end of the rotation animation
4407         TLOGI(WmsLogTag::DMS, "DisableCacheForRotation");
4408         RSInterfaces::GetInstance().DisableCacheForRotation();
4409         return;
4410     } else if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY ||
4411         screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY) {
4412         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
4413         TLOGI(WmsLogTag::DMS, "Update Screen Rotation Property Only");
4414         {
4415             std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
4416             screenSession->UpdatePropertyOnly(bounds, rotation, GetFoldDisplayMode());
4417         }
4418         if (screenPropertyChangeType != ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY) {
4419             NotifyDisplayChanged(displayInfo, DisplayChangeEvent::UPDATE_ROTATION);
4420             NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
4421         }
4422         if(!isSwitchUser) {
4423             screenSession->UpdateDisplayNodeRotation(rotation);
4424         }
4425         return;
4426     }
4427 }
4428 
NotifyDisplayChanged(sptr<DisplayInfo> displayInfo,DisplayChangeEvent event)4429 void ScreenSessionManager::NotifyDisplayChanged(sptr<DisplayInfo> displayInfo, DisplayChangeEvent event)
4430 {
4431     if (displayInfo == nullptr) {
4432         TLOGE(WmsLogTag::DMS, "error, displayInfo is nullptr.");
4433         return;
4434     }
4435     auto task = [=] {
4436         auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
4437         if (event == DisplayChangeEvent::UPDATE_REFRESHRATE) {
4438             TLOGND(WmsLogTag::DMS, "evevt:%{public}d, displayId:%{public}" PRIu64", agent size: %{public}u",
4439                 event, displayInfo->GetDisplayId(), static_cast<uint32_t>(agents.size()));
4440         } else {
4441             TLOGNI(WmsLogTag::DMS, "evevt:%{public}d, displayId:%{public}" PRIu64", agent size: %{public}u",
4442                 event, displayInfo->GetDisplayId(), static_cast<uint32_t>(agents.size()));
4443         }
4444         if (agents.empty()) {
4445             return;
4446         }
4447         for (auto& agent : agents) {
4448             int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
4449             if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
4450                 agent->OnDisplayChange(displayInfo, event);
4451             }
4452         }
4453     };
4454     taskScheduler_->PostAsyncTask(task, "NotifyDisplayChanged");
4455 }
4456 
SetOrientation(ScreenId screenId,Orientation orientation)4457 DMError ScreenSessionManager::SetOrientation(ScreenId screenId, Orientation orientation)
4458 {
4459     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4460         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4461             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4462         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4463     }
4464     if (orientation < Orientation::UNSPECIFIED || orientation > Orientation::REVERSE_HORIZONTAL) {
4465         TLOGE(WmsLogTag::DMS, "set: %{public}u", static_cast<uint32_t>(orientation));
4466         return DMError::DM_ERROR_INVALID_PARAM;
4467     }
4468     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetOrientation");
4469     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4470     if (screenSession == nullptr) {
4471         TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"", screenId);
4472         return DMError::DM_ERROR_NULLPTR;
4473     }
4474     // just for get orientation test
4475     screenSession->SetOrientation(orientation);
4476     screenSession->ScreenOrientationChange(orientation, GetFoldDisplayMode());
4477     return DMError::DM_OK;
4478 }
4479 
SetRotation(ScreenId screenId,Rotation rotationAfter,bool isFromWindow)4480 bool ScreenSessionManager::SetRotation(ScreenId screenId, Rotation rotationAfter, bool isFromWindow)
4481 {
4482     TLOGI(WmsLogTag::DMS,
4483         "Enter, screenId: %{public}" PRIu64 ", rotation: %{public}u, isFromWindow: %{public}u,",
4484         screenId, rotationAfter, isFromWindow);
4485     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4486     if (screenSession == nullptr) {
4487         TLOGE(WmsLogTag::DMS, "error, cannot get screen with screenId: %{public}" PRIu64, screenId);
4488         return false;
4489     }
4490     if (rotationAfter == screenSession->GetRotation()) {
4491         TLOGE(WmsLogTag::DMS, "rotation not changed. screen %{public}" PRIu64" rotation %{public}u",
4492             screenId, rotationAfter);
4493         return false;
4494     }
4495     TLOGI(WmsLogTag::DMS, "set orientation. rotation %{public}u", rotationAfter);
4496     screenSession->SetRotation(rotationAfter);
4497     screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::ROTATION);
4498     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
4499     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::UPDATE_ROTATION);
4500     return true;
4501 }
4502 
SetSensorSubscriptionEnabled()4503 void ScreenSessionManager::SetSensorSubscriptionEnabled()
4504 {
4505     isAutoRotationOpen_ = system::GetParameter("persist.display.ar.enabled", "1") == "1";
4506     if (!isAutoRotationOpen_) {
4507         TLOGE(WmsLogTag::DMS, "autoRotation is not open");
4508         return;
4509     }
4510     ScreenSensorConnector::SubscribeRotationSensor();
4511     TLOGI(WmsLogTag::DMS, "subscribe rotation sensor successful");
4512 }
4513 
SetPostureAndHallSensorEnabled()4514 void ScreenSessionManager::SetPostureAndHallSensorEnabled()
4515 {
4516 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
4517     if (!g_foldScreenFlag) {
4518         TLOGI(WmsLogTag::DMS, "current device is not fold phone.");
4519         return;
4520     }
4521     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
4522         SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
4523         SecondaryFoldSensorManager::GetInstance().RegisterHallCallback();
4524     } else {
4525         FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
4526         FoldScreenSensorManager::GetInstance().RegisterHallCallback();
4527     }
4528     if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() &&
4529         !FoldScreenSensorManager::GetInstance().GetSensorRegisterStatus()) {
4530         TLOGI(WmsLogTag::DMS, "subscribe hall and posture failed, force change to full screen!");
4531         TriggerFoldStatusChange(FoldStatus::EXPAND);
4532     }
4533     TLOGI(WmsLogTag::DMS, "successful");
4534     screenEventTracker_.RecordEvent("Dms subscribe Posture and Hall sensor finished.");
4535 #endif
4536 }
4537 
SetRotationFromWindow(Rotation targetRotation)4538 bool ScreenSessionManager::SetRotationFromWindow(Rotation targetRotation)
4539 {
4540     sptr<DisplayInfo> displayInfo = GetDefaultDisplayInfo();
4541     if (displayInfo == nullptr) {
4542         return false;
4543     }
4544     return SetRotation(displayInfo->GetScreenId(), targetRotation, true);
4545 }
4546 
GetScreenModesByDisplayId(DisplayId displayId)4547 sptr<SupportedScreenModes> ScreenSessionManager::GetScreenModesByDisplayId(DisplayId displayId)
4548 {
4549     auto displayInfo = GetDisplayInfoById(displayId);
4550     if (displayInfo == nullptr) {
4551         TLOGE(WmsLogTag::DMS, "can not get display.");
4552         return nullptr;
4553     }
4554     auto screenInfo = GetScreenInfoById(displayInfo->GetScreenId());
4555     if (screenInfo == nullptr) {
4556         TLOGE(WmsLogTag::DMS, "can not get screen.");
4557         return nullptr;
4558     }
4559     auto modes = screenInfo->GetModes();
4560     auto id = screenInfo->GetModeId();
4561     if (id >= modes.size()) {
4562         TLOGE(WmsLogTag::DMS, "can not get screenMode.");
4563         return nullptr;
4564     }
4565     return modes[id];
4566 }
4567 
GetScreenInfoByDisplayId(DisplayId displayId)4568 sptr<ScreenInfo> ScreenSessionManager::GetScreenInfoByDisplayId(DisplayId displayId)
4569 {
4570     auto displayInfo = GetDisplayInfoById(displayId);
4571     if (displayInfo == nullptr) {
4572         TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
4573         return nullptr;
4574     }
4575     return GetScreenInfoById(displayInfo->GetScreenId());
4576 }
4577 
NotifyPowerEventForDualDisplay(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)4578 int ScreenSessionManager::NotifyPowerEventForDualDisplay(DisplayPowerEvent event, EventStatus status,
4579     PowerStateChangeReason reason)
4580 {
4581     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4582     if (screenSessionMap_.empty()) {
4583         TLOGE(WmsLogTag::DMS, "[UL_POWER]screenSessionMap is empty");
4584         return NOTIFY_EVENT_FOR_DUAL_FAILED;
4585     }
4586 #ifdef FOLD_ABILITY_ENABLE
4587     // The on/off screen will send a notification based on the number of screens.
4588     // The dual display device just notify the current screen usage
4589     if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
4590         ScreenId currentScreenId = foldScreenController_->GetCurrentScreenId();
4591         auto iter = screenSessionMap_.find(currentScreenId);
4592         if (iter != screenSessionMap_.end() && iter->second != nullptr) {
4593             iter->second->PowerStatusChange(event, status, reason);
4594         }
4595         return NOTIFY_EVENT_FOR_DUAL_SUCESS;
4596     }
4597 #endif
4598     return NO_NEED_NOTIFY_EVENT_FOR_DUAL;
4599 }
4600 
NotifyDisplayPowerEvent(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)4601 bool ScreenSessionManager::NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status,
4602     PowerStateChangeReason reason)
4603 {
4604     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER);
4605     if (agents.empty()) {
4606         TLOGI(WmsLogTag::DMS, "[UL_POWER] agents is empty");
4607         return false;
4608     }
4609     TLOGD(WmsLogTag::DMS, "[UL_POWER] start");
4610     for (auto& agent : agents) {
4611         agent->NotifyDisplayPowerEvent(event, status);
4612     }
4613     auto ret = NotifyPowerEventForDualDisplay(event, status, reason);
4614     if (ret == NOTIFY_EVENT_FOR_DUAL_FAILED) {
4615         TLOGE(WmsLogTag::DMS, "[UL_POWER]NotifyPowerEventForDualDisplay ret false");
4616         return false;
4617     } else if (ret == NOTIFY_EVENT_FOR_DUAL_SUCESS) {
4618         TLOGD(WmsLogTag::DMS, "[UL_POWER]NotifyPowerEventForDualDisplay ret sucess");
4619         return true;
4620     }
4621     auto screenIds = GetAllScreenIds();
4622     if (screenIds.empty()) {
4623         TLOGI(WmsLogTag::DMS, "[UL_POWER]no screenID");
4624         return false;
4625     }
4626     auto screenId = screenIds[0];
4627     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4628     if (screenSession == nullptr) {
4629         TLOGE(WmsLogTag::DMS, "[UL_POWER]Cannot get ScreenSession, screenId: %{public}" PRIu64"", screenId);
4630         return false;
4631     }
4632     screenSession->PowerStatusChange(event, status, reason);
4633     return true;
4634 }
4635 
NotifyDisplayStateChanged(DisplayId id,DisplayState state)4636 bool ScreenSessionManager::NotifyDisplayStateChanged(DisplayId id, DisplayState state)
4637 {
4638     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_STATE_LISTENER);
4639     if (agents.empty()) {
4640         TLOGI(WmsLogTag::DMS, "agents is empty");
4641         return false;
4642     }
4643     TLOGI(WmsLogTag::DMS, "notify enter!");
4644     for (auto& agent : agents) {
4645         agent->NotifyDisplayStateChanged(id, state);
4646     }
4647     return true;
4648 }
GetAllScreenInfos(std::vector<sptr<ScreenInfo>> & screenInfos)4649 DMError ScreenSessionManager::GetAllScreenInfos(std::vector<sptr<ScreenInfo>>& screenInfos)
4650 {
4651     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4652         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4653             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4654         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4655     }
4656     std::vector<ScreenId> screenIds = GetAllScreenIds();
4657     if (screenIds.empty()) {
4658         TLOGI(WmsLogTag::DMS, "[UL_POWER]no screen info");
4659         return DMError::DM_OK;
4660     }
4661     for (auto screenId : screenIds) {
4662         auto screenInfo = GetScreenInfoById(screenId);
4663         if (screenInfo == nullptr) {
4664             TLOGE(WmsLogTag::DMS, "cannot find screenInfo: %{public}" PRIu64"", screenId);
4665             continue;
4666         }
4667         screenInfos.emplace_back(screenInfo);
4668     }
4669     return DMError::DM_OK;
4670 }
4671 
GetAllScreenIds() const4672 std::vector<ScreenId> ScreenSessionManager::GetAllScreenIds() const
4673 {
4674     std::vector<ScreenId> res;
4675     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4676     for (const auto& iter : screenSessionMap_) {
4677         res.emplace_back(iter.first);
4678     }
4679     return res;
4680 }
4681 
GetScreenSupportedColorGamuts(ScreenId screenId,std::vector<ScreenColorGamut> & colorGamuts)4682 DMError ScreenSessionManager::GetScreenSupportedColorGamuts(ScreenId screenId,
4683     std::vector<ScreenColorGamut>& colorGamuts)
4684 {
4685     TLOGI(WmsLogTag::DMS, "ENTER");
4686     if (!SessionPermission::IsSystemCalling()) {
4687         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4688             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4689         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4690     }
4691     sptr<ScreenSession> screen = GetScreenSession(screenId);
4692     if (screen == nullptr) {
4693         TLOGE(WmsLogTag::DMS, "nullptr");
4694         return DMError::DM_ERROR_INVALID_PARAM;
4695     }
4696     return screen->GetScreenSupportedColorGamuts(colorGamuts);
4697 }
4698 
GetPixelFormat(ScreenId screenId,GraphicPixelFormat & pixelFormat)4699 DMError ScreenSessionManager::GetPixelFormat(ScreenId screenId, GraphicPixelFormat& pixelFormat)
4700 {
4701     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64, screenId);
4702     if (screenId == SCREEN_ID_INVALID) {
4703         TLOGE(WmsLogTag::DMS, "screenId invalid");
4704         return DMError::DM_ERROR_INVALID_PARAM;
4705     }
4706     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4707     if (screenSession == nullptr) {
4708         return DMError::DM_ERROR_INVALID_PARAM;
4709     }
4710     return screenSession->GetPixelFormat(pixelFormat);
4711 }
4712 
SetPixelFormat(ScreenId screenId,GraphicPixelFormat pixelFormat)4713 DMError ScreenSessionManager::SetPixelFormat(ScreenId screenId, GraphicPixelFormat pixelFormat)
4714 {
4715     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4716         TLOGE(WmsLogTag::DMS, "permission denied!");
4717         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4718     }
4719 
4720     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", pixelFormat %{public}d",
4721         screenId, pixelFormat);
4722     if (screenId == SCREEN_ID_INVALID) {
4723         TLOGE(WmsLogTag::DMS, "screenId invalid");
4724         return DMError::DM_ERROR_INVALID_PARAM;
4725     }
4726     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4727     if (screenSession == nullptr) {
4728         return DMError::DM_ERROR_INVALID_PARAM;
4729     }
4730     return screenSession->SetPixelFormat(pixelFormat);
4731 }
4732 
GetSupportedHDRFormats(ScreenId screenId,std::vector<ScreenHDRFormat> & hdrFormats)4733 DMError ScreenSessionManager::GetSupportedHDRFormats(ScreenId screenId,
4734     std::vector<ScreenHDRFormat>& hdrFormats)
4735 {
4736 #ifdef WM_SCREEN_HDR_FORMAT_ENABLE
4737     TLOGI(WmsLogTag::DMS, "start %{public}" PRIu64, screenId);
4738     if (screenId == SCREEN_ID_INVALID) {
4739         TLOGE(WmsLogTag::DMS, "screenId invalid");
4740         return DMError::DM_ERROR_INVALID_PARAM;
4741     }
4742     sptr<ScreenSession> screen = GetScreenSession(screenId);
4743     if (screen == nullptr) {
4744         TLOGE(WmsLogTag::DMS, "nullptr");
4745         return DMError::DM_ERROR_INVALID_PARAM;
4746     }
4747     return screen->GetSupportedHDRFormats(hdrFormats);
4748 #else
4749     return DMError::DM_OK;
4750 #endif
4751 }
4752 
GetScreenHDRFormat(ScreenId screenId,ScreenHDRFormat & hdrFormat)4753 DMError ScreenSessionManager::GetScreenHDRFormat(ScreenId screenId, ScreenHDRFormat& hdrFormat)
4754 {
4755 #ifdef WM_SCREEN_HDR_FORMAT_ENABLE
4756     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64, screenId);
4757     if (screenId == SCREEN_ID_INVALID) {
4758         TLOGE(WmsLogTag::DMS, "screenId invalid");
4759         return DMError::DM_ERROR_INVALID_PARAM;
4760     }
4761     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4762     if (screenSession == nullptr) {
4763         return DMError::DM_ERROR_INVALID_PARAM;
4764     }
4765     return screenSession->GetScreenHDRFormat(hdrFormat);
4766 #else
4767     return DMError::DM_OK;
4768 #endif
4769 }
4770 
SetScreenHDRFormat(ScreenId screenId,int32_t modeIdx)4771 DMError ScreenSessionManager::SetScreenHDRFormat(ScreenId screenId, int32_t modeIdx)
4772 {
4773 #ifdef WM_SCREEN_HDR_FORMAT_ENABLE
4774     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4775         TLOGE(WmsLogTag::DMS, "permission denied!");
4776         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4777     }
4778 
4779     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", modeIdx %{public}d", screenId, modeIdx);
4780     if (screenId == SCREEN_ID_INVALID) {
4781         TLOGE(WmsLogTag::DMS, "screenId invalid");
4782         return DMError::DM_ERROR_INVALID_PARAM;
4783     }
4784     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4785     if (screenSession == nullptr) {
4786         return DMError::DM_ERROR_INVALID_PARAM;
4787     }
4788     return screenSession->SetScreenHDRFormat(modeIdx);
4789 #else
4790     return DMError::DM_OK;
4791 #endif
4792 }
4793 
GetSupportedColorSpaces(ScreenId screenId,std::vector<GraphicCM_ColorSpaceType> & colorSpaces)4794 DMError ScreenSessionManager::GetSupportedColorSpaces(ScreenId screenId,
4795     std::vector<GraphicCM_ColorSpaceType>& colorSpaces)
4796 {
4797 #ifdef WM_SCREEN_COLOR_SPACE_ENABLE
4798     TLOGI(WmsLogTag::DMS, "start %{public}" PRIu64, screenId);
4799     if (screenId == SCREEN_ID_INVALID) {
4800         TLOGE(WmsLogTag::DMS, "screenId invalid");
4801         return DMError::DM_ERROR_INVALID_PARAM;
4802     }
4803     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4804     if (screenSession == nullptr) {
4805         TLOGE(WmsLogTag::DMS, "nullptr");
4806         return DMError::DM_ERROR_INVALID_PARAM;
4807     }
4808     return screenSession->GetSupportedColorSpaces(colorSpaces);
4809 #else
4810     return DMError::DM_OK;
4811 #endif
4812 }
4813 
GetScreenColorSpace(ScreenId screenId,GraphicCM_ColorSpaceType & colorSpace)4814 DMError ScreenSessionManager::GetScreenColorSpace(ScreenId screenId, GraphicCM_ColorSpaceType& colorSpace)
4815 {
4816 #ifdef WM_SCREEN_COLOR_SPACE_ENABLE
4817     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64, screenId);
4818     if (screenId == SCREEN_ID_INVALID) {
4819         TLOGE(WmsLogTag::DMS, "screenId invalid");
4820         return DMError::DM_ERROR_INVALID_PARAM;
4821     }
4822     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4823     if (screenSession == nullptr) {
4824         return DMError::DM_ERROR_INVALID_PARAM;
4825     }
4826     return screenSession->GetScreenColorSpace(colorSpace);
4827 #else
4828     return DMError::DM_OK;
4829 #endif
4830 }
4831 
SetScreenColorSpace(ScreenId screenId,GraphicCM_ColorSpaceType colorSpace)4832 DMError ScreenSessionManager::SetScreenColorSpace(ScreenId screenId, GraphicCM_ColorSpaceType colorSpace)
4833 {
4834 #ifdef WM_SCREEN_COLOR_SPACE_ENABLE
4835     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4836         TLOGE(WmsLogTag::DMS, "permission denied!");
4837         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4838     }
4839 
4840     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", colorSpace %{public}d",
4841         screenId, colorSpace);
4842     if (screenId == SCREEN_ID_INVALID) {
4843         TLOGE(WmsLogTag::DMS, "screenId invalid");
4844         return DMError::DM_ERROR_INVALID_PARAM;
4845     }
4846     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4847     if (screenSession == nullptr) {
4848         return DMError::DM_ERROR_INVALID_PARAM;
4849     }
4850     return screenSession->SetScreenColorSpace(colorSpace);
4851 #else
4852     return DMError::DM_OK;
4853 #endif
4854 }
4855 
AddVirtualScreenDeathRecipient(const sptr<IRemoteObject> & displayManagerAgent,ScreenId smsScreenId)4856 void ScreenSessionManager::AddVirtualScreenDeathRecipient(const sptr<IRemoteObject>& displayManagerAgent,
4857     ScreenId smsScreenId)
4858 {
4859     if (deathRecipient_ == nullptr) {
4860         TLOGW(WmsLogTag::DMS, "Create deathRecipient");
4861         deathRecipient_ =
4862             new(std::nothrow) AgentDeathRecipient([this](const sptr<IRemoteObject>& agent) { OnRemoteDied(agent); });
4863     }
4864     std::lock_guard<std::mutex> lock(screenAgentMapMutex_);
4865     if (deathRecipient_ != nullptr) {
4866         auto agIter = screenAgentMap_.find(displayManagerAgent);
4867         if (agIter == screenAgentMap_.end()) {
4868             displayManagerAgent->AddDeathRecipient(deathRecipient_);
4869         }
4870     }
4871     screenAgentMap_[displayManagerAgent].emplace_back(smsScreenId);
4872 }
4873 
CreateVirtualScreen(VirtualScreenOption option,const sptr<IRemoteObject> & displayManagerAgent)4874 ScreenId ScreenSessionManager::CreateVirtualScreen(VirtualScreenOption option,
4875                                                    const sptr<IRemoteObject>& displayManagerAgent)
4876 {
4877     if (!Permission::IsSystemCalling() && !SessionPermission::IsShellCall() &&
4878         !Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION)) {
4879         return ERROR_ID_NOT_SYSTEM_APP;
4880     }
4881     if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
4882         !SessionPermission::IsShellCall() && !Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION)) {
4883         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4884             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4885         return SCREEN_ID_INVALID;
4886     }
4887     if (option.virtualScreenType_ != VirtualScreenType::SCREEN_RECORDING) {
4888         ExitCoordination("CreateVirtualScreen(cast)");
4889     }
4890     TLOGI(WmsLogTag::DMS, "ENTER, virtualScreenType: %{public}u", static_cast<uint32_t>(option.virtualScreenType_));
4891     if (SessionPermission::IsBetaVersion()) {
4892         CheckAndSendHiSysEvent("CREATE_VIRTUAL_SCREEN", "hmos.screenrecorder");
4893     }
4894     auto clientProxy = GetClientProxy();
4895     if (clientProxy && option.missionIds_.size() > 0) {
4896         std::vector<uint64_t> surfaceNodeIds;
4897         clientProxy->OnGetSurfaceNodeIdsFromMissionIdsChanged(option.missionIds_, surfaceNodeIds, true);
4898         option.missionIds_ = surfaceNodeIds;
4899     }
4900     ScreenId rsId = rsInterface_.CreateVirtualScreen(option.name_, option.width_,
4901         option.height_, option.surface_, SCREEN_ID_INVALID, option.flags_);
4902     if (rsId == SCREEN_ID_INVALID) {
4903         TLOGI(WmsLogTag::DMS, "rsId is invalid");
4904         return SCREEN_ID_INVALID;
4905     }
4906     TLOGW(WmsLogTag::DMS, "rsId: %{public}" PRIu64"", rsId);
4907     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CreateVirtualScreen(%s)", option.name_.c_str());
4908     ScreenId smsScreenId = SCREEN_ID_INVALID;
4909     if (!screenIdManager_.ConvertToSmsScreenId(rsId, smsScreenId)) {
4910         TLOGW(WmsLogTag::DMS, "!ConvertToSmsScreenId(rsId, smsScreenId)");
4911         smsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsId);
4912         auto screenSession = InitVirtualScreen(smsScreenId, rsId, option);
4913         if (screenSession == nullptr) {
4914             TLOGW(WmsLogTag::DMS, "screenSession is nullptr");
4915             screenIdManager_.DeleteScreenId(smsScreenId);
4916             return SCREEN_ID_INVALID;
4917         }
4918         screenSession->SetName(option.name_);
4919         screenSession->SetMirrorScreenType(MirrorScreenType::VIRTUAL_MIRROR);
4920         screenSession->SetSecurity(option.isSecurity_);
4921         {
4922             std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4923             screenSessionMap_.insert(std::make_pair(smsScreenId, screenSession));
4924         }
4925         screenSession->SetVirtualScreenFlag(option.virtualScreenFlag_);
4926         NotifyScreenConnected(screenSession->ConvertToScreenInfo());
4927         TLOGW(WmsLogTag::DMS, "create success. ScreenId: %{public}" PRIu64", rsId: %{public}" PRIu64"",
4928             smsScreenId, rsId);
4929         if (displayManagerAgent == nullptr) {
4930             virtualScreenCount_ = virtualScreenCount_ + 1;
4931             NotifyCaptureStatusChanged();
4932             return smsScreenId;
4933         }
4934         AddVirtualScreenDeathRecipient(displayManagerAgent, smsScreenId);
4935     }
4936     virtualScreenCount_ = virtualScreenCount_ + 1;
4937     NotifyCaptureStatusChanged();
4938     return smsScreenId;
4939 }
4940 
SetVirtualScreenSurface(ScreenId screenId,sptr<IBufferProducer> surface)4941 DMError ScreenSessionManager::SetVirtualScreenSurface(ScreenId screenId, sptr<IBufferProducer> surface)
4942 {
4943     bool isCallingByThirdParty = Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION);
4944     if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
4945         !SessionPermission::IsShellCall() && !isCallingByThirdParty) {
4946         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4947             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4948         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4949     }
4950     if (surface == nullptr) {
4951         TLOGE(WmsLogTag::DMS, "surface is null");
4952         return DMError::DM_ERROR_INVALID_PARAM;
4953     }
4954     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4955     if (screenSession == nullptr) {
4956         TLOGE(WmsLogTag::DMS, "No such screen.");
4957         return isCallingByThirdParty ? DMError::DM_ERROR_NULLPTR : DMError::DM_ERROR_INVALID_PARAM;
4958     }
4959     TLOGW(WmsLogTag::DMS, "enter set virtual screen surface");
4960     ScreenId rsScreenId;
4961     int32_t res = -1;
4962     if (screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4963         sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(surface);
4964         if (pSurface != nullptr) {
4965             res = rsInterface_.SetVirtualScreenSurface(rsScreenId, pSurface);
4966         }
4967     }
4968     if (res != 0) {
4969         TLOGE(WmsLogTag::DMS, "fail to set virtual screen surface in RenderService");
4970         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
4971     }
4972     return DMError::DM_OK;
4973 }
4974 
AddVirtualScreenBlockList(const std::vector<int32_t> & persistentIds)4975 DMError ScreenSessionManager::AddVirtualScreenBlockList(const std::vector<int32_t>& persistentIds)
4976 {
4977     if (!Permission::IsSystemCalling()) {
4978         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4979             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4980         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4981     }
4982     MockSessionManagerService::GetInstance().AddSkipSelfWhenShowOnVirtualScreenList(persistentIds);
4983     return DMError::DM_OK;
4984 }
4985 
RemoveVirtualScreenBlockList(const std::vector<int32_t> & persistentIds)4986 DMError ScreenSessionManager::RemoveVirtualScreenBlockList(const std::vector<int32_t>& persistentIds)
4987 {
4988     if (!Permission::IsSystemCalling()) {
4989         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4990             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4991         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4992     }
4993     MockSessionManagerService::GetInstance().RemoveSkipSelfWhenShowOnVirtualScreenList(persistentIds);
4994     return DMError::DM_OK;
4995 }
4996 
SetScreenPrivacyMaskImage(ScreenId screenId,const std::shared_ptr<Media::PixelMap> & privacyMaskImg)4997 DMError ScreenSessionManager::SetScreenPrivacyMaskImage(ScreenId screenId,
4998     const std::shared_ptr<Media::PixelMap>& privacyMaskImg)
4999 {
5000     if (!Permission::IsSystemCalling()) {
5001         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
5002             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5003         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5004     }
5005     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
5006     if (screenSession == nullptr) {
5007         TLOGE(WmsLogTag::DMS, "No such screen.");
5008         return DMError::DM_ERROR_NULLPTR;
5009     }
5010     ScreenId rsScreenId;
5011     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
5012         TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
5013         return DMError::DM_ERROR_INVALID_PARAM;
5014     }
5015     int32_t res = -1;
5016     if (privacyMaskImg == nullptr) {
5017         TLOGI(WmsLogTag::DMS, "Clearing screen privacy mask image for screenId: %{public}" PRIu64"",
5018             static_cast<uint64_t>(screenId));
5019         res = rsInterface_.SetScreenSecurityMask(rsScreenId, nullptr);
5020         if (res != 0) {
5021             TLOGE(WmsLogTag::DMS, "Fail to set privacy mask image in RenderService");
5022             return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
5023         }
5024         return DMError::DM_OK;
5025     }
5026     TLOGI(WmsLogTag::DMS, "Setting screen privacy mask image for screenId: %{public}" PRIu64"",
5027         static_cast<uint64_t>(screenId));
5028     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetScreenSecurityMask(%" PRIu64")", screenId);
5029     res = rsInterface_.SetScreenSecurityMask(rsScreenId, privacyMaskImg);
5030     if (res != 0) {
5031         TLOGE(WmsLogTag::DMS, "Fail to set privacy mask image in RenderService");
5032         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
5033     }
5034     return DMError::DM_OK;
5035 }
5036 
SetVirtualMirrorScreenScaleMode(ScreenId screenId,ScreenScaleMode scaleMode)5037 DMError ScreenSessionManager::SetVirtualMirrorScreenScaleMode(ScreenId screenId, ScreenScaleMode scaleMode)
5038 {
5039     if (!SessionPermission::IsSystemCalling()) {
5040         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5041             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5042         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5043     }
5044     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
5045     if (screenSession == nullptr) {
5046         TLOGE(WmsLogTag::DMS, "No such screen.");
5047         return DMError::DM_ERROR_INVALID_PARAM;
5048     }
5049     ScreenId rsScreenId;
5050     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
5051         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
5052         return DMError::DM_ERROR_INVALID_PARAM;
5053     }
5054     bool res = rsInterface_.SetVirtualMirrorScreenScaleMode(rsScreenId, scaleMode);
5055     if (!res) {
5056         TLOGE(WmsLogTag::DMS, "failed in RenderService");
5057         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
5058     }
5059     return DMError::DM_OK;
5060 }
5061 
SetVirtualMirrorScreenCanvasRotation(ScreenId screenId,bool autoRotate)5062 DMError ScreenSessionManager::SetVirtualMirrorScreenCanvasRotation(ScreenId screenId, bool autoRotate)
5063 {
5064     if (!SessionPermission::IsSystemCalling()) {
5065         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5066             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5067         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5068     }
5069     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
5070     if (screenSession == nullptr) {
5071         TLOGE(WmsLogTag::DMS, "No such screen.");
5072         return DMError::DM_ERROR_INVALID_PARAM;
5073     }
5074     TLOGW(WmsLogTag::DMS, "enter set virtual mirror screen canvas rotation");
5075     bool res = false;
5076     ScreenId rsScreenId;
5077     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
5078         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
5079         return DMError::DM_ERROR_INVALID_PARAM;
5080     }
5081     res = rsInterface_.SetVirtualMirrorScreenCanvasRotation(rsScreenId, autoRotate);
5082     if (!res) {
5083         TLOGE(WmsLogTag::DMS, "failed in RenderService");
5084         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
5085     }
5086     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
5087         screenSession->SetIsEnableCanvasRotation(autoRotate);
5088     }
5089     TLOGW(WmsLogTag::DMS, "success");
5090     return DMError::DM_OK;
5091 }
5092 
ResizeVirtualScreen(ScreenId screenId,uint32_t width,uint32_t height)5093 DMError ScreenSessionManager::ResizeVirtualScreen(ScreenId screenId, uint32_t width, uint32_t height)
5094 {
5095     if (!SessionPermission::IsSystemCalling()) {
5096         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5097             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5098         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5099     }
5100     TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64", width: %{public}u, height: %{public}u.",
5101         screenId, width, height);
5102     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
5103     if (screenSession == nullptr) {
5104         TLOGE(WmsLogTag::DMS, "No such screen.");
5105         return DMError::DM_ERROR_INVALID_PARAM;
5106     }
5107     ScreenId rsScreenId;
5108     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
5109         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
5110         return DMError::DM_ERROR_INVALID_PARAM;
5111     }
5112     rsInterface_.ResizeVirtualScreen(rsScreenId, width, height);
5113     screenSession->Resize(width, height);
5114     screenSession->PropertyChange(screenSession->GetScreenProperty(),
5115         ScreenPropertyChangeReason::VIRTUAL_SCREEN_RESIZE);
5116     return DMError::DM_OK;
5117 }
5118 
DestroyVirtualScreen(ScreenId screenId)5119 DMError ScreenSessionManager::DestroyVirtualScreen(ScreenId screenId)
5120 {
5121     bool isCallingByThirdParty = Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION);
5122     if (!SessionPermission::IsSystemCalling() && !isCallingByThirdParty) {
5123         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5124             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5125         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5126     }
5127     if (static_cast<uint64_t>(screenId) < static_cast<uint64_t>(MINIMUM_VIRTUAL_SCREEN_ID)) {
5128         TLOGE(WmsLogTag::DMS, "virtual screenId is invalid, id: %{public}" PRIu64"", static_cast<uint64_t>(screenId));
5129         return DMError::DM_ERROR_INVALID_PARAM;
5130     }
5131     // virtual screen destroy callback to notify scb
5132     TLOGW(WmsLogTag::DMS, "start");
5133     OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED);
5134     ScreenId rsScreenId = SCREEN_ID_INVALID;
5135     {
5136         std::lock_guard<std::mutex> lock(screenAgentMapMutex_);
5137         screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
5138         for (auto &agentIter : screenAgentMap_) {
5139             auto iter = std::find(agentIter.second.begin(), agentIter.second.end(), screenId);
5140             if (iter != agentIter.second.end()) {
5141                 iter = agentIter.second.erase(iter);
5142                 if (agentIter.first != nullptr && agentIter.second.empty()) {
5143                     screenAgentMap_.erase(agentIter.first);
5144                 }
5145                 break;
5146             }
5147         }
5148     }
5149     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyVirtualScreen(%" PRIu64")", screenId);
5150     auto screen = GetScreenSession(screenId);
5151     if (rsScreenId != SCREEN_ID_INVALID && screen != nullptr) {
5152         NotifyDisplayDestroy(screenId);
5153         {
5154             std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5155             auto screenGroup = RemoveFromGroupLocked(screen);
5156             if (screenGroup != nullptr) {
5157                 NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
5158             }
5159             screenSessionMap_.erase(screenId);
5160         }
5161         RemoveScreenCastInfo(screenId);
5162         NotifyScreenDisconnected(screenId);
5163         if (auto clientProxy = GetClientProxy()) {
5164             clientProxy->OnVirtualScreenDisconnected(rsScreenId);
5165         }
5166         TLOGW(WmsLogTag::DMS, "destroy success, id: %{public}" PRIu64 ", rsId: %{public}" PRIu64, screenId, rsScreenId);
5167     }
5168     screenIdManager_.DeleteScreenId(screenId);
5169     virtualScreenCount_ = virtualScreenCount_ > 0 ? virtualScreenCount_ - 1 : 0;
5170     NotifyCaptureStatusChanged();
5171     if (rsScreenId == SCREEN_ID_INVALID) {
5172         TLOGE(WmsLogTag::DMS, "No corresponding rsScreenId");
5173         return isCallingByThirdParty ? DMError::DM_ERROR_NULLPTR : DMError::DM_ERROR_INVALID_PARAM;
5174     }
5175     rsInterface_.RemoveVirtualScreen(rsScreenId);
5176     return DMError::DM_OK;
5177 }
5178 
DisableMirror(bool disableOrNot)5179 DMError ScreenSessionManager::DisableMirror(bool disableOrNot)
5180 {
5181     TLOGW(WmsLogTag::DMS, "start %{public}d", disableOrNot);
5182     if (!SessionPermission::IsSystemCalling()) {
5183         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5184             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5185         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5186     }
5187     TLOGI(WmsLogTag::DMS, "enter %{public}d", disableOrNot);
5188     if (disableOrNot) {
5189         std::vector<ScreenId> screenIds;
5190         auto allScreenIds = GetAllScreenIds();
5191         for (auto screenId : allScreenIds) {
5192             auto screen = GetScreenSession(screenId);
5193             if (screen && screen->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
5194                 screenIds.push_back(screenId);
5195             }
5196         }
5197         StopMirror(screenIds);
5198     }
5199     return DMError::DM_OK;
5200 }
5201 
MirrorSwitchNotify(ScreenId screenId)5202 void ScreenSessionManager::MirrorSwitchNotify(ScreenId screenId)
5203 {
5204     auto mirrorScreen = GetScreenSession(screenId);
5205     if (mirrorScreen != nullptr) {
5206         mirrorScreen->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
5207         NotifyScreenChanged(mirrorScreen->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE);
5208     }
5209 }
5210 
DoMakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,DMRect mainScreenRegion,ScreenId & screenGroupId)5211 DMError ScreenSessionManager::DoMakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
5212     DMRect mainScreenRegion, ScreenId& screenGroupId)
5213 {
5214 #ifdef WM_MULTI_SCREEN_ENABLE
5215     TLOGW(WmsLogTag::DMS, "enter!");
5216     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5217         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5218             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5219         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5220     }
5221     if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
5222         TLOGW(WmsLogTag::DMS, "disabled by edm!");
5223         return DMError::DM_ERROR_INVALID_PERMISSION;
5224     }
5225 
5226     TLOGW(WmsLogTag::DMS, "mainScreenId :%{public}" PRIu64"", mainScreenId);
5227     auto allMirrorScreenIds = GetAllValidScreenIds(mirrorScreenIds);
5228     auto iter = std::find(allMirrorScreenIds.begin(), allMirrorScreenIds.end(), mainScreenId);
5229     if (iter != allMirrorScreenIds.end()) {
5230         allMirrorScreenIds.erase(iter);
5231     }
5232     auto mainScreen = GetScreenSession(mainScreenId);
5233     if (mainScreen == nullptr || allMirrorScreenIds.empty()) {
5234         TLOGE(WmsLogTag::DMS, "MakeMirror fail. mainScreen :%{public}" PRIu64", screens size:%{public}u",
5235             mainScreenId, static_cast<uint32_t>(allMirrorScreenIds.size()));
5236         return DMError::DM_ERROR_NULLPTR;
5237     }
5238     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeMirror start");
5239     for (ScreenId screenId : allMirrorScreenIds) {
5240         OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED);
5241     }
5242     DMError makeResult = MultiScreenManager::GetInstance().MirrorSwitch(mainScreenId,
5243         allMirrorScreenIds, mainScreenRegion, screenGroupId);
5244     if (makeResult != DMError::DM_OK) {
5245         TLOGE(WmsLogTag::DMS, "MakeMirror set mirror failed.");
5246         return makeResult;
5247     }
5248     for (ScreenId screenId : allMirrorScreenIds) {
5249         MirrorSwitchNotify(screenId);
5250         auto screenSession = GetScreenSession(screenId);
5251         if (screenSession != nullptr && mainScreen != nullptr) {
5252             screenSession->SetDisplayGroupId(mainScreen->GetDisplayGroupId());
5253             screenSession->SetMainDisplayIdOfGroup(mainScreen->GetMainDisplayIdOfGroup());
5254         }
5255     }
5256     RegisterCastObserver(allMirrorScreenIds);
5257     TLOGW(WmsLogTag::DMS, "make mirror notify scb end makeResult=%{public}d", makeResult);
5258     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeMirror end");
5259     return makeResult;
5260 #else
5261     return DMError::DM_OK;
5262 #endif
5263 }
5264 
MakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,ScreenId & screenGroupId)5265 DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
5266     ScreenId& screenGroupId)
5267 {
5268 #ifdef FOLD_ABILITY_ENABLE
5269     if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
5270         DMRect mainScreenRegion = DMRect::NONE();
5271         foldScreenController_->SetMainScreenRegion(mainScreenRegion);
5272         return DoMakeMirror(mainScreenId, mirrorScreenIds, mainScreenRegion, screenGroupId);
5273     }
5274 #endif
5275     return DoMakeMirror(mainScreenId, mirrorScreenIds, DMRect::NONE(), screenGroupId);
5276 }
5277 
MakeMirrorForRecord(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,ScreenId & screenGroupId)5278 DMError ScreenSessionManager::MakeMirrorForRecord(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
5279     ScreenId& screenGroupId)
5280 {
5281 #ifdef FOLD_ABILITY_ENABLE
5282     TLOGW(WmsLogTag::DMS, "start");
5283     ScreenId realScreenId = mainScreenId;
5284     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && mainScreenId == DISPLAY_ID_FAKE) {
5285         if (!SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
5286             TLOGE(WmsLogTag::DMS, "fake display is not exist!");
5287             return DMError::DM_ERROR_INVALID_PARAM;
5288         }
5289         realScreenId = 0;
5290     }
5291     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
5292         SuperFoldPolicy::GetInstance().IsNeedSetSnapshotRect(mainScreenId)) {
5293         DMRect mainScreenRect = SuperFoldPolicy::GetInstance().GetRecordRect(mainScreenId);
5294         return DoMakeMirror(realScreenId, mirrorScreenIds, mainScreenRect, screenGroupId);
5295     }
5296     if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
5297         DMRect mainScreenRegion = DMRect::NONE();
5298         foldScreenController_->SetMainScreenRegion(mainScreenRegion);
5299         return DoMakeMirror(mainScreenId, mirrorScreenIds, mainScreenRegion, screenGroupId);
5300     }
5301 #endif
5302     return DoMakeMirror(mainScreenId, mirrorScreenIds, DMRect::NONE(), screenGroupId);
5303 }
5304 
5305 
MakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,DMRect mainScreenRegion,ScreenId & screenGroupId)5306 DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
5307                                          DMRect mainScreenRegion, ScreenId& screenGroupId)
5308 {
5309     return DoMakeMirror(mainScreenId, mirrorScreenIds, mainScreenRegion, screenGroupId);
5310 }
5311 
RegisterCastObserver(std::vector<ScreenId> & mirrorScreenIds)5312 void ScreenSessionManager::RegisterCastObserver(std::vector<ScreenId>& mirrorScreenIds)
5313 {
5314     {
5315         std::lock_guard<std::mutex> lock(mirrorScreenIdsMutex_);
5316         mirrorScreenIds_ = mirrorScreenIds;
5317     }
5318     TLOGI(WmsLogTag::DMS, "Register Setting cast Observer");
5319     SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetCastFromSettingData(); };
5320     ScreenSettingHelper::RegisterSettingCastObserver(updateFunc);
5321 }
5322 
SetCastFromSettingData()5323 void ScreenSessionManager::SetCastFromSettingData()
5324 {
5325     bool enable;
5326     bool ret = ScreenSettingHelper::GetSettingCast(enable);
5327     if (!ret) {
5328         TLOGW(WmsLogTag::DMS, "get setting cast failed, default enable");
5329         enable = true;
5330     } else {
5331         TLOGI(WmsLogTag::DMS, "get setting cast success, enable: %{public}u", enable);
5332     }
5333 
5334     std::vector<ScreenId> mirrorScreenIdsCopy;
5335     {
5336         std::lock_guard<std::mutex> lock(mirrorScreenIdsMutex_);
5337         mirrorScreenIdsCopy = mirrorScreenIds_;
5338     }
5339     for (ScreenId screenId : mirrorScreenIdsCopy) {
5340         ScreenId rsScreenId;
5341         if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
5342             TLOGE(WmsLogTag::DMS, "No corresponding rsId");
5343             continue;
5344         }
5345         rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, enable);
5346     }
5347 }
5348 
RegisterSettingRotationObserver()5349 void ScreenSessionManager::RegisterSettingRotationObserver()
5350 {
5351     TLOGI(WmsLogTag::DMS, "start");
5352     SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) {
5353         int32_t rotation = -1;
5354         int32_t screenId = -1;
5355         if (ScreenSettingHelper::GetSettingRotation(rotation) &&
5356             ScreenSettingHelper::GetSettingRotationScreenID(screenId)) {
5357             TLOGNI(WmsLogTag::DMS, "current dms setting rotation:%{public}d, screenId:%{public}d",
5358                 rotation, screenId);
5359         } else {
5360             TLOGNI(WmsLogTag::DMS, "get current dms setting rotation and screenId failed");
5361         }
5362     };
5363     ScreenSettingHelper::RegisterSettingRotationObserver(updateFunc);
5364 }
5365 
StopMirror(const std::vector<ScreenId> & mirrorScreenIds)5366 DMError ScreenSessionManager::StopMirror(const std::vector<ScreenId>& mirrorScreenIds)
5367 {
5368     if (!SessionPermission::IsSystemCalling()) {
5369         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5370             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5371         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5372     }
5373     auto allMirrorScreenIds = GetAllValidScreenIds(mirrorScreenIds);
5374     if (allMirrorScreenIds.empty()) {
5375         TLOGW(WmsLogTag::DMS, "done. screens' size:%{public}u",
5376             static_cast<uint32_t>(allMirrorScreenIds.size()));
5377         return DMError::DM_OK;
5378     }
5379 
5380     DMError ret = StopScreens(allMirrorScreenIds, ScreenCombination::SCREEN_MIRROR);
5381     if (ret != DMError::DM_OK) {
5382         TLOGE(WmsLogTag::DMS, "failed.");
5383         return ret;
5384     }
5385     ScreenSettingHelper::UnregisterSettingCastObserver();
5386 
5387     return DMError::DM_OK;
5388 }
5389 
StopScreens(const std::vector<ScreenId> & screenIds,ScreenCombination stopCombination)5390 DMError ScreenSessionManager::StopScreens(const std::vector<ScreenId>& screenIds, ScreenCombination stopCombination)
5391 {
5392     for (ScreenId screenId : screenIds) {
5393         TLOGW(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64"", screenId);
5394         auto screen = GetScreenSession(screenId);
5395         if (screen == nullptr) {
5396             TLOGW(WmsLogTag::DMS, "screen:%{public}" PRIu64" is nullptr", screenId);
5397             continue;
5398         }
5399         sptr<ScreenSessionGroup> screenGroup = GetAbstractScreenGroup(screen->groupSmsId_);
5400         if (!screenGroup) {
5401             TLOGW(WmsLogTag::DMS, "groupDmsId:%{public}" PRIu64"is not in smsScreenGroupMap_",
5402                 screen->groupSmsId_);
5403             continue;
5404         }
5405         if (screenGroup->combination_ != stopCombination) {
5406             TLOGW(WmsLogTag::DMS, "try to stop screen in another combination");
5407             continue;
5408         }
5409         if (screenGroup->combination_ == ScreenCombination::SCREEN_MIRROR &&
5410             screen->screenId_ == screenGroup->mirrorScreenId_) {
5411             TLOGW(WmsLogTag::DMS, "try to stop main mirror screen");
5412             continue;
5413         }
5414         bool res = RemoveChildFromGroup(screen, screenGroup);
5415         if (res) {
5416             NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
5417         }
5418     }
5419     return DMError::DM_OK;
5420 }
5421 
GetVirtualScreenFlag(ScreenId screenId)5422 VirtualScreenFlag ScreenSessionManager::GetVirtualScreenFlag(ScreenId screenId)
5423 {
5424     if (!SessionPermission::IsSystemCalling()) {
5425         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5426             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5427         return VirtualScreenFlag::DEFAULT;
5428     }
5429     auto screen = GetScreenSession(screenId);
5430     if (screen == nullptr) {
5431         TLOGE(WmsLogTag::DMS, "screen session null");
5432         return VirtualScreenFlag::DEFAULT;
5433     }
5434     return screen->GetVirtualScreenFlag();
5435 }
5436 
SetVirtualScreenFlag(ScreenId screenId,VirtualScreenFlag screenFlag)5437 DMError ScreenSessionManager::SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag)
5438 {
5439     if (!SessionPermission::IsSystemCalling()) {
5440         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5441             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5442         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5443     }
5444     if (screenFlag < VirtualScreenFlag::DEFAULT || screenFlag >= VirtualScreenFlag::MAX) {
5445         TLOGE(WmsLogTag::DMS, "range error");
5446         return DMError::DM_ERROR_INVALID_PARAM;
5447     }
5448     auto screen = GetScreenSession(screenId);
5449     if (screen == nullptr) {
5450         TLOGE(WmsLogTag::DMS, "screen session null");
5451         return DMError::DM_ERROR_INVALID_PARAM;
5452     }
5453     screen->SetVirtualScreenFlag(screenFlag);
5454     return DMError::DM_OK;
5455 }
5456 
SetVirtualScreenRefreshRate(ScreenId screenId,uint32_t refreshInterval)5457 DMError ScreenSessionManager::SetVirtualScreenRefreshRate(ScreenId screenId, uint32_t refreshInterval)
5458 {
5459     if (!SessionPermission::IsSystemCalling()) {
5460         TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
5461             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5462         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5463     }
5464     TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64", refreshInterval:  %{public}u",
5465         screenId, refreshInterval);
5466     if (screenId == GetDefaultScreenId()) {
5467         TLOGE(WmsLogTag::DMS, "cannot set refresh rate of main screen id: %{public}" PRIu64, GetDefaultScreenId());
5468         return DMError::DM_ERROR_INVALID_PARAM;
5469     }
5470     if (refreshInterval == 0) {
5471         TLOGE(WmsLogTag::DMS, "refresh interval is 0.");
5472         return DMError::DM_ERROR_INVALID_PARAM;
5473     }
5474     auto screenSession = GetScreenSession(screenId);
5475     auto defaultScreenSession = GetDefaultScreenSession();
5476     if (screenSession == nullptr || defaultScreenSession == nullptr) {
5477         TLOGE(WmsLogTag::DMS, "screenSession is null.");
5478         return DMError::DM_ERROR_INVALID_PARAM;
5479     }
5480     ScreenId rsScreenId;
5481     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
5482         TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
5483         return DMError::DM_ERROR_INVALID_PARAM;
5484     }
5485     int32_t res = rsInterface_.SetScreenSkipFrameInterval(rsScreenId, refreshInterval);
5486     if (res != StatusCode::SUCCESS) {
5487         TLOGE(WmsLogTag::DMS, "rsInterface error: %{public}d", res);
5488         return DMError::DM_ERROR_INVALID_PARAM;
5489     }
5490     // when skipFrameInterval > 10 means the skipFrameInterval is the virtual screen refresh rate
5491     if (refreshInterval > IRREGULAR_REFRESH_RATE_SKIP_THRETHOLD) {
5492         screenSession->UpdateRefreshRate(refreshInterval);
5493         screenSession->SetSupportedRefreshRate({refreshInterval});
5494     } else {
5495         screenSession->UpdateRefreshRate(defaultScreenSession->GetRefreshRate() / refreshInterval);
5496         screenSession->SetSupportedRefreshRate({defaultScreenSession->GetRefreshRate() / refreshInterval});
5497     }
5498     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::UPDATE_REFRESHRATE);
5499     TLOGW(WmsLogTag::DMS, "refreshInterval is %{public}d", refreshInterval);
5500     return DMError::DM_OK;
5501 }
5502 
VirtualScreenUniqueSwitch(const std::vector<ScreenId> & screenIds)5503 DMError ScreenSessionManager::VirtualScreenUniqueSwitch(const std::vector<ScreenId>& screenIds)
5504 {
5505 #ifdef WM_MULTI_SCREEN_ENABLE
5506     TLOGW(WmsLogTag::DMS, "enter");
5507     auto defaultScreen = GetDefaultScreenSession();
5508     if (!defaultScreen) {
5509         TLOGE(WmsLogTag::DMS, "default screen is nullptr");
5510         return DMError::DM_ERROR_NULLPTR;
5511     }
5512     defaultScreen->groupSmsId_ = 1;
5513     {
5514         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5515         auto iter = smsScreenGroupMap_.find(defaultScreen->groupSmsId_);
5516         if (iter != smsScreenGroupMap_.end()) {
5517             smsScreenGroupMap_.erase(iter);
5518         }
5519     }
5520     DMError uniqueSwitchRet = MultiScreenManager::GetInstance().VirtualScreenUniqueSwitch(defaultScreen, screenIds);
5521     TLOGW(WmsLogTag::DMS, "result: %{public}d", uniqueSwitchRet);
5522     return uniqueSwitchRet;
5523 #else
5524     return DMError::DM_OK;
5525 #endif
5526 }
5527 
MakeUniqueScreen(const std::vector<ScreenId> & screenIds,std::vector<DisplayId> & displayIds)5528 DMError ScreenSessionManager::MakeUniqueScreen(const std::vector<ScreenId>& screenIds,
5529     std::vector<DisplayId>& displayIds)
5530 {
5531 #ifdef WM_MULTI_SCREEN_ENABLE
5532     bool isCallingByThirdParty = Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION);
5533     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd() && !isCallingByThirdParty) {
5534         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5535             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5536         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5537     }
5538     TLOGW(WmsLogTag::DMS, "enter!");
5539     if (screenIds.empty()) {
5540         TLOGE(WmsLogTag::DMS, "screen is empty");
5541         return DMError::DM_ERROR_INVALID_PARAM;
5542     }
5543     std::vector<ScreenId> validScreenIds;
5544     for (auto screenId : screenIds) {
5545         if (!IsDefaultMirrorMode(screenId)) {
5546             continue;
5547         }
5548         validScreenIds.emplace_back(screenId);
5549     }
5550     const auto& allUniqueScreenIds = GetAllValidScreenIds(validScreenIds);
5551     if (allUniqueScreenIds.empty()) {
5552         TLOGE(WmsLogTag::DMS, "screenIds is invalid.");
5553         return DMError::DM_ERROR_NULLPTR;
5554     }
5555     ScreenId uniqueScreenId = validScreenIds[0];
5556     auto uniqueScreen = GetScreenSession(uniqueScreenId);
5557     if (uniqueScreen != nullptr) {
5558         if (uniqueScreen->GetSourceMode() == ScreenSourceMode::SCREEN_UNIQUE) {
5559             TLOGW(WmsLogTag::DMS, "make unique ignore");
5560             return DMError::DM_OK;
5561         }
5562         if (isCallingByThirdParty) {
5563             uniqueScreen->SetInnerName("CustomScbScreen");
5564         }
5565         return MultiScreenManager::GetInstance().UniqueSwitch(allUniqueScreenIds, displayIds);
5566     }
5567     return DoMakeUniqueScreenOld(allUniqueScreenIds, displayIds, isCallingByThirdParty);
5568 #else
5569     return DMError::DM_ERROR_DEVICE_NOT_SUPPORT;
5570 #endif
5571 }
5572 
DoMakeUniqueScreenOld(const std::vector<ScreenId> & allUniqueScreenIds,std::vector<DisplayId> & displayIds,bool isCallingByThirdParty)5573 DMError ScreenSessionManager::DoMakeUniqueScreenOld(const std::vector<ScreenId>& allUniqueScreenIds,
5574     std::vector<DisplayId>& displayIds, bool isCallingByThirdParty)
5575 {
5576 #ifdef WM_MULTI_SCREEN_ENABLE
5577     std::unordered_set<std::shared_ptr<RSUIContext>> rsUIContexts;
5578     for (auto screenId : allUniqueScreenIds) {
5579         ScreenId rsScreenId = SCREEN_ID_INVALID;
5580         bool res = ConvertScreenIdToRsScreenId(screenId, rsScreenId);
5581         TLOGI(WmsLogTag::DMS, "unique screenId: %{public}" PRIu64" rsScreenId: %{public}" PRIu64,
5582             screenId, rsScreenId);
5583         if (!res) {
5584             TLOGE(WmsLogTag::DMS, "convert screenId to rsScreenId failed");
5585             continue;
5586         }
5587         auto screenSession = GetScreenSession(screenId);
5588         if (!screenSession) {
5589             TLOGE(WmsLogTag::DMS, "screen session is nullptr");
5590             continue;
5591         }
5592         displayIds.emplace_back(static_cast<uint64_t>(screenId));
5593         Rosen::RSDisplayNodeConfig rsConfig;
5594         rsConfig.screenId = rsScreenId;
5595         screenSession->CreateDisplayNode(rsConfig);
5596         screenSession->SetDisplayNodeScreenId(rsScreenId);
5597         if (isCallingByThirdParty) {
5598             screenSession->SetInnerName("CustomScbScreen");
5599         }
5600         // notify scb to build Screen widget
5601         OnVirtualScreenChange(screenId, ScreenEvent::CONNECTED);
5602         rsUIContexts.insert(screenSession->GetRSUIContext());
5603     }
5604     TLOGD(WmsLogTag::DMS, "flush data");
5605     RSTransactionAdapter::FlushImplicitTransaction(rsUIContexts);
5606 #endif
5607     return DMError::DM_OK;
5608 }
5609 
NotifyScreenConnectCompletion(ScreenId screenId)5610 void ScreenSessionManager::NotifyScreenConnectCompletion(ScreenId screenId)
5611 {
5612 #ifdef WM_MULTI_SCREEN_ENABLE
5613     TLOGI(WmsLogTag::DMS, "ENTER, screenId:%{public}" PRIu64, screenId);
5614     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5615         TLOGE(WmsLogTag::DMS, "permission denied!");
5616         return;
5617     }
5618     MultiScreenManager::GetInstance().NotifyScreenConnectCompletion(screenId);
5619 #endif
5620 }
5621 
MakeExpand(std::vector<ScreenId> screenId,std::vector<Point> startPoint,ScreenId & screenGroupId)5622 DMError ScreenSessionManager::MakeExpand(std::vector<ScreenId> screenId,
5623                                          std::vector<Point> startPoint,
5624                                          ScreenId& screenGroupId)
5625 {
5626     TLOGI(WmsLogTag::DMS, "enter!");
5627     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5628         TLOGE(WmsLogTag::DMS, "permission denied! pid: %{public}d", IPCSkeleton::GetCallingPid());
5629         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5630     }
5631     if (screenId.empty() || startPoint.empty() || screenId.size() != startPoint.size()) {
5632         TLOGE(WmsLogTag::DMS, "create expand fail, screenId size:%{public}ud,startPoint size:%{public}ud",
5633             static_cast<uint32_t>(screenId.size()), static_cast<uint32_t>(startPoint.size()));
5634         return DMError::DM_ERROR_INVALID_PARAM;
5635     }
5636     std::map<ScreenId, Point> pointsMap;
5637     uint32_t size = screenId.size();
5638     for (uint32_t i = 0; i < size; i++) {
5639         if (pointsMap.find(screenId[i]) != pointsMap.end()) {
5640             continue;
5641         }
5642         pointsMap[screenId[i]] = startPoint[i];
5643     }
5644     ScreenId defaultScreenId = GetDefaultScreenId();
5645     auto allExpandScreenIds = GetAllValidScreenIds(screenId);
5646     auto iter = std::find(allExpandScreenIds.begin(), allExpandScreenIds.end(), defaultScreenId);
5647     if (iter != allExpandScreenIds.end()) {
5648         allExpandScreenIds.erase(iter);
5649     }
5650     if (allExpandScreenIds.empty()) {
5651         TLOGE(WmsLogTag::DMS, "allExpandScreenIds is empty. make expand failed.");
5652         return DMError::DM_ERROR_NULLPTR;
5653     }
5654     std::shared_ptr<RSDisplayNode> rsDisplayNode;
5655     std::vector<Point> points;
5656     for (uint32_t i = 0; i < allExpandScreenIds.size(); i++) {
5657         ScreenId expandScreenId = allExpandScreenIds[i];
5658         if (pointsMap.find(expandScreenId) == pointsMap.end()) {
5659             continue;
5660         }
5661         points.emplace_back(pointsMap[expandScreenId]);
5662         rsDisplayNode = GetRSDisplayNodeByScreenId(expandScreenId);
5663         if (rsDisplayNode != nullptr) {
5664             SetScreenOffset(expandScreenId, pointsMap[expandScreenId].posX_, pointsMap[expandScreenId].posY_);
5665         }
5666     }
5667     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeExpand");
5668     if (!OnMakeExpand(allExpandScreenIds, points)) {
5669         return DMError::DM_ERROR_NULLPTR;
5670     }
5671     auto screen = GetScreenSession(allExpandScreenIds[0]);
5672     if (screen == nullptr || GetAbstractScreenGroup(screen->groupSmsId_) == nullptr) {
5673         return DMError::DM_ERROR_NULLPTR;
5674     }
5675     screenGroupId = screen->groupSmsId_;
5676     return DMError::DM_OK;
5677 }
5678 
OnMakeExpand(std::vector<ScreenId> screenId,std::vector<Point> startPoint)5679 bool ScreenSessionManager::OnMakeExpand(std::vector<ScreenId> screenId, std::vector<Point> startPoint)
5680 {
5681     ScreenId defaultScreenId = GetDefaultScreenId();
5682     TLOGI(WmsLogTag::DMS, "defaultScreenId:%{public}" PRIu64"", defaultScreenId);
5683     auto defaultScreen = GetScreenSession(defaultScreenId);
5684     if (defaultScreen == nullptr) {
5685         TLOGI(WmsLogTag::DMS, "failed.");
5686         return false;
5687     }
5688     auto group = GetAbstractScreenGroup(defaultScreen->groupSmsId_);
5689     if (group == nullptr) {
5690         group = AddToGroupLocked(defaultScreen);
5691         if (group == nullptr) {
5692             TLOGE(WmsLogTag::DMS, "group is nullptr");
5693             return false;
5694         }
5695         NotifyScreenGroupChanged(defaultScreen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
5696     }
5697     bool filterExpandScreen = group->combination_ == ScreenCombination::SCREEN_EXPAND;
5698     ChangeScreenGroup(group, screenId, startPoint, filterExpandScreen, ScreenCombination::SCREEN_EXPAND);
5699     TLOGI(WmsLogTag::DMS, "success");
5700     return true;
5701 }
5702 
StopExpand(const std::vector<ScreenId> & expandScreenIds)5703 DMError ScreenSessionManager::StopExpand(const std::vector<ScreenId>& expandScreenIds)
5704 {
5705     if (!SessionPermission::IsSystemCalling()) {
5706         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5707             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5708         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5709     }
5710     auto allExpandScreenIds = GetAllValidScreenIds(expandScreenIds);
5711     if (allExpandScreenIds.empty()) {
5712         TLOGI(WmsLogTag::DMS, "done. screens' size:%{public}u",
5713             static_cast<uint32_t>(allExpandScreenIds.size()));
5714         return DMError::DM_OK;
5715     }
5716 
5717     DMError ret = StopScreens(allExpandScreenIds, ScreenCombination::SCREEN_EXPAND);
5718     if (ret != DMError::DM_OK) {
5719         TLOGE(WmsLogTag::DMS, "stop expand failed.");
5720         return ret;
5721     }
5722 
5723     return DMError::DM_OK;
5724 }
5725 
ConvertToRsScreenId(ScreenId smsScreenId,ScreenId & rsScreenId) const5726 bool ScreenSessionManager::ScreenIdManager::ConvertToRsScreenId(ScreenId smsScreenId, ScreenId& rsScreenId) const
5727 {
5728     std::shared_lock lock(screenIdMapMutex_);
5729     auto iter = sms2RsScreenIdMap_.find(smsScreenId);
5730     if (iter == sms2RsScreenIdMap_.end()) {
5731         return false;
5732     }
5733     rsScreenId = iter->second;
5734     return true;
5735 }
5736 
ConvertToRsScreenId(ScreenId screenId) const5737 ScreenId ScreenSessionManager::ScreenIdManager::ConvertToRsScreenId(ScreenId screenId) const
5738 {
5739     ScreenId rsScreenId = SCREEN_ID_INVALID;
5740     ConvertToRsScreenId(screenId, rsScreenId);
5741     return rsScreenId;
5742 }
5743 
ConvertToSmsScreenId(ScreenId rsScreenId) const5744 ScreenId ScreenSessionManager::ScreenIdManager::ConvertToSmsScreenId(ScreenId rsScreenId) const
5745 {
5746     ScreenId smsScreenId = SCREEN_ID_INVALID;
5747     ConvertToSmsScreenId(rsScreenId, smsScreenId);
5748     return smsScreenId;
5749 }
5750 
ConvertToSmsScreenId(ScreenId rsScreenId,ScreenId & smsScreenId) const5751 bool ScreenSessionManager::ScreenIdManager::ConvertToSmsScreenId(ScreenId rsScreenId, ScreenId& smsScreenId) const
5752 {
5753     std::shared_lock lock(screenIdMapMutex_);
5754     auto iter = rs2SmsScreenIdMap_.find(rsScreenId);
5755     if (iter == rs2SmsScreenIdMap_.end()) {
5756         return false;
5757     }
5758     smsScreenId = iter->second;
5759     return true;
5760 }
5761 
CreateAndGetNewScreenId(ScreenId rsScreenId)5762 ScreenId ScreenSessionManager::ScreenIdManager::CreateAndGetNewScreenId(ScreenId rsScreenId)
5763 {
5764     std::unique_lock lock(screenIdMapMutex_);
5765     ScreenId smsScreenId = smsScreenCount_++;
5766     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64"", smsScreenId);
5767     if (sms2RsScreenIdMap_.find(smsScreenId) != sms2RsScreenIdMap_.end()) {
5768         TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64" exit", smsScreenId);
5769     }
5770     sms2RsScreenIdMap_[smsScreenId] = rsScreenId;
5771     if (rsScreenId == SCREEN_ID_INVALID) {
5772         return smsScreenId;
5773     }
5774     if (rs2SmsScreenIdMap_.find(rsScreenId) != rs2SmsScreenIdMap_.end()) {
5775         TLOGW(WmsLogTag::DMS, "rsScreenId: %{public}" PRIu64" exit", rsScreenId);
5776     }
5777     rs2SmsScreenIdMap_[rsScreenId] = smsScreenId;
5778     return smsScreenId;
5779 }
5780 
UpdateScreenId(ScreenId rsScreenId,ScreenId smsScreenId)5781 void ScreenSessionManager::ScreenIdManager::UpdateScreenId(ScreenId rsScreenId, ScreenId smsScreenId)
5782 {
5783     std::unique_lock lock(screenIdMapMutex_);
5784     rs2SmsScreenIdMap_[rsScreenId] = smsScreenId;
5785     sms2RsScreenIdMap_[smsScreenId] = rsScreenId;
5786 }
5787 
DeleteScreenId(ScreenId smsScreenId)5788 bool ScreenSessionManager::ScreenIdManager::DeleteScreenId(ScreenId smsScreenId)
5789 {
5790     std::unique_lock lock(screenIdMapMutex_);
5791     auto iter = sms2RsScreenIdMap_.find(smsScreenId);
5792     if (iter == sms2RsScreenIdMap_.end()) {
5793         return false;
5794     }
5795     ScreenId rsScreenId = iter->second;
5796     sms2RsScreenIdMap_.erase(smsScreenId);
5797     rs2SmsScreenIdMap_.erase(rsScreenId);
5798     return true;
5799 }
5800 
HasRsScreenId(ScreenId smsScreenId) const5801 bool ScreenSessionManager::ScreenIdManager::HasRsScreenId(ScreenId smsScreenId) const
5802 {
5803     std::shared_lock lock(screenIdMapMutex_);
5804     return rs2SmsScreenIdMap_.find(smsScreenId) != rs2SmsScreenIdMap_.end();
5805 }
5806 
InitVirtualScreen(ScreenId smsScreenId,ScreenId rsId,VirtualScreenOption option)5807 sptr<ScreenSession> ScreenSessionManager::InitVirtualScreen(ScreenId smsScreenId, ScreenId rsId,
5808     VirtualScreenOption option)
5809 {
5810     TLOGI(WmsLogTag::DMS, "Enter");
5811     ScreenSessionConfig config = {
5812         .screenId = smsScreenId,
5813         .rsId = rsId,
5814         .defaultScreenId = GetDefaultScreenId(),
5815         .name = option.name_,
5816     };
5817     sptr<ScreenSession> screenSession =
5818         new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
5819     sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
5820     if (screenSession == nullptr || info == nullptr) {
5821         TLOGI(WmsLogTag::DMS, "new screenSession or info failed");
5822         screenIdManager_.DeleteScreenId(smsScreenId);
5823         rsInterface_.RemoveVirtualScreen(rsId);
5824         return nullptr;
5825     }
5826     info->width_ = option.width_;
5827     info->height_ = option.height_;
5828     auto defaultScreen = GetScreenSession(GetDefaultScreenId());
5829     if (defaultScreen != nullptr) {
5830         info->refreshRate_ = defaultScreen->GetRefreshRate();
5831         screenSession->UpdateRefreshRate(info->refreshRate_);
5832         std::vector<uint32_t> virtualRefreshRateVec = {info->refreshRate_};
5833         screenSession->SetSupportedRefreshRate(std::move(virtualRefreshRateVec));
5834     }
5835     screenSession->modes_.emplace_back(info);
5836     screenSession->activeIdx_ = 0;
5837     screenSession->SetScreenType(ScreenType::VIRTUAL);
5838     screenSession->SetVirtualPixelRatio(option.density_);
5839     screenSession->SetIsPcUse(g_isPcDevice ? true : false);
5840     screenSession->SetDisplayBoundary(RectF(0, 0, option.width_, option.height_), 0);
5841     screenSession->RegisterScreenChangeListener(this);
5842     screenSession->SetValidWidth(option.width_);
5843     screenSession->SetValidHeight(option.height_);
5844     screenSession->SetRealWidth(option.width_);
5845     screenSession->SetRealHeight(option.height_);
5846     screenSession->SetScreenAreaWidth(option.width_);
5847     screenSession->SetScreenAreaHeight(option.height_);
5848     return screenSession;
5849 }
5850 
InitAbstractScreenModesInfo(sptr<ScreenSession> & screenSession)5851 bool ScreenSessionManager::InitAbstractScreenModesInfo(sptr<ScreenSession>& screenSession)
5852 {
5853     TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenSupportedModes");
5854     std::vector<RSScreenModeInfo> allModes = rsInterface_.GetScreenSupportedModes(
5855         screenIdManager_.ConvertToRsScreenId(screenSession->screenId_));
5856     if (allModes.size() == 0) {
5857         TLOGE(WmsLogTag::DMS, "allModes.size() == 0, screenId=%{public}" PRIu64"", screenSession->rsId_);
5858         return false;
5859     }
5860     for (const RSScreenModeInfo& rsScreenModeInfo : allModes) {
5861         sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
5862         if (info == nullptr) {
5863             TLOGE(WmsLogTag::DMS, "create SupportedScreenModes failed");
5864             return false;
5865         }
5866         info->id_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenModeId());
5867         info->width_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenWidth());
5868         info->height_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenHeight());
5869         info->refreshRate_ = rsScreenModeInfo.GetScreenRefreshRate();
5870         screenSession->modes_.push_back(info);
5871         TLOGW(WmsLogTag::DMS, "fill screen idx:%{public}d w/h:%{public}d/%{public}d",
5872             rsScreenModeInfo.GetScreenModeId(), info->width_, info->height_);
5873     }
5874     TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenActiveMode");
5875     int32_t activeModeId = rsInterface_.GetScreenActiveMode(screenSession->rsId_).GetScreenModeId();
5876     TLOGW(WmsLogTag::DMS, "fill screen activeModeId:%{public}d", activeModeId);
5877     if (static_cast<std::size_t>(activeModeId) >= allModes.size()) {
5878         TLOGE(WmsLogTag::DMS, "activeModeId exceed, screenId=%{public}" PRIu64", activeModeId:%{public}d/%{public}ud",
5879             screenSession->rsId_, activeModeId, static_cast<uint32_t>(allModes.size()));
5880         return false;
5881     }
5882     screenSession->activeIdx_ = activeModeId;
5883     return true;
5884 }
5885 
InitAndGetScreen(ScreenId rsScreenId)5886 sptr<ScreenSession> ScreenSessionManager::InitAndGetScreen(ScreenId rsScreenId)
5887 {
5888     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5889     ScreenId smsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsScreenId);
5890     RSScreenCapability screenCapability = rsInterface_.GetScreenCapability(rsScreenId);
5891     TLOGI(WmsLogTag::DMS, "Screen name is %{public}s, phyWidth is %{public}u, phyHeight is %{public}u",
5892         screenCapability.GetName().c_str(), screenCapability.GetPhyWidth(), screenCapability.GetPhyHeight());
5893     ScreenSessionConfig config = {
5894         .screenId = smsScreenId,
5895         .rsId = rsScreenId,
5896         .defaultScreenId = GetDefaultScreenId(),
5897         .name = screenCapability.GetName(),
5898     };
5899     sptr<ScreenSession> screenSession =
5900         new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_VIRTUAL);
5901     if (screenSession == nullptr) {
5902         TLOGE(WmsLogTag::DMS, "screenSession == nullptr.");
5903         screenIdManager_.DeleteScreenId(smsScreenId);
5904         return nullptr;
5905     }
5906     if (!InitAbstractScreenModesInfo(screenSession)) {
5907         screenIdManager_.DeleteScreenId(smsScreenId);
5908         TLOGE(WmsLogTag::DMS, "failed.");
5909         return nullptr;
5910     }
5911     TLOGI(WmsLogTag::DMS, "screenSessionMap_ add screenId=%{public}" PRIu64"", smsScreenId);
5912     screenSessionMap_.insert(std::make_pair(smsScreenId, screenSession));
5913     return screenSession;
5914 }
5915 
IsExtendMode()5916 bool ScreenSessionManager::IsExtendMode()
5917 {
5918     std::vector<ScreenId> mainVector;
5919     std::vector<ScreenId> extendVector;
5920     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5921     for (const auto& pair : screenSessionMap_) {
5922         sptr<ScreenSession> session = pair.second;
5923         if (!session) {
5924             TLOGE(WmsLogTag::DMS, "screenId=%{public}" PRIu64", session is null", pair.first);
5925             continue;
5926         }
5927         if (session->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
5928             extendVector.push_back(session->GetScreenId());
5929         }
5930         if (session->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
5931             mainVector.push_back(session->GetScreenId());
5932         }
5933     }
5934     std::ostringstream oss;
5935     oss << "main screenId:";
5936     for (const auto& screenId : mainVector) {
5937         oss << static_cast<uint64_t>(screenId);
5938     }
5939     oss << ", extend screenId:";
5940     for (const auto& screenId : extendVector) {
5941         oss << static_cast<uint64_t>(screenId);
5942     }
5943     oss << std::endl;
5944     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
5945     return mainVector.size() > 0 && extendVector.size() > 0;
5946 }
5947 
AddToGroupLocked(sptr<ScreenSession> newScreen,bool isUnique)5948 sptr<ScreenSessionGroup> ScreenSessionManager::AddToGroupLocked(sptr<ScreenSession> newScreen, bool isUnique)
5949 {
5950     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5951     sptr<ScreenSessionGroup> res;
5952     if (smsScreenGroupMap_.empty()) {
5953         TLOGI(WmsLogTag::DMS, "connect the first screen");
5954         res = AddAsFirstScreenLocked(newScreen, isUnique);
5955     } else {
5956         res = AddAsSuccedentScreenLocked(newScreen);
5957     }
5958     return res;
5959 }
5960 
AddAsFirstScreenLocked(sptr<ScreenSession> newScreen,bool isUnique)5961 sptr<ScreenSessionGroup> ScreenSessionManager::AddAsFirstScreenLocked(sptr<ScreenSession> newScreen, bool isUnique)
5962 {
5963     ScreenId smsGroupScreenId(1);
5964     std::ostringstream buffer;
5965     buffer << "ScreenGroup_" << smsGroupScreenId;
5966     std::string name = buffer.str();
5967     // default ScreenCombination is mirror
5968     isExpandCombination_ = system::GetParameter("persist.display.expand.enabled", "0") == "1";
5969     sptr<ScreenSessionGroup> screenGroup;
5970     if (isExpandCombination_) {
5971         screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
5972             SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_EXPAND);
5973     } else if (isUnique) {
5974         screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
5975             SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_UNIQUE);
5976     } else {
5977         screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
5978             SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_MIRROR);
5979     }
5980     if (screenGroup == nullptr) {
5981         TLOGE(WmsLogTag::DMS, "new ScreenSessionGroup failed");
5982         screenIdManager_.DeleteScreenId(smsGroupScreenId);
5983         return nullptr;
5984     }
5985     screenGroup->groupSmsId_ = 1;
5986     Point point;
5987     if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none") {
5988         if (IsExtendMode()) {
5989             point = {newScreen->GetScreenProperty().GetStartX(), newScreen->GetScreenProperty().GetStartY()};
5990         }
5991     }
5992     if (!screenGroup->AddChild(newScreen, point, GetScreenSession(GetDefaultScreenId()), g_isPcDevice)) {
5993         TLOGE(WmsLogTag::DMS, "fail to add screen to group. screen=%{public}" PRIu64"", newScreen->screenId_);
5994         screenIdManager_.DeleteScreenId(smsGroupScreenId);
5995         return nullptr;
5996     }
5997     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5998     auto iter = smsScreenGroupMap_.find(smsGroupScreenId);
5999     if (iter != smsScreenGroupMap_.end()) {
6000         TLOGE(WmsLogTag::DMS, "group screen existed. id=%{public}" PRIu64"", smsGroupScreenId);
6001         smsScreenGroupMap_.erase(iter);
6002     }
6003     smsScreenGroupMap_.insert(std::make_pair(smsGroupScreenId, screenGroup));
6004     screenGroup->mirrorScreenId_ = newScreen->screenId_;
6005     TLOGI(WmsLogTag::DMS, "connect new group screen, screenId: %{public}" PRIu64", screenGroupId: %{public}" PRIu64", "
6006         "combination:%{public}u", newScreen->screenId_, smsGroupScreenId,
6007         newScreen->GetScreenProperty().GetScreenType());
6008     return screenGroup;
6009 }
6010 
AddAsSuccedentScreenLocked(sptr<ScreenSession> newScreen)6011 sptr<ScreenSessionGroup> ScreenSessionManager::AddAsSuccedentScreenLocked(sptr<ScreenSession> newScreen)
6012 {
6013     ScreenId defaultScreenId = GetDefaultScreenId();
6014     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6015     auto iter = screenSessionMap_.find(defaultScreenId);
6016     if (iter == screenSessionMap_.end()) {
6017         TLOGE(WmsLogTag::DMS, "defaultScreenId:%{public}" PRIu64" is not in screenSessionMap_.",
6018             defaultScreenId);
6019         return nullptr;
6020     }
6021     auto screen = iter->second;
6022     auto screenGroupIter = smsScreenGroupMap_.find(screen->groupSmsId_);
6023     if (screenGroupIter == smsScreenGroupMap_.end()) {
6024         TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64" is not in smsScreenGroupMap_.",
6025             screen->groupSmsId_);
6026         return nullptr;
6027     }
6028     auto screenGroup = screenGroupIter->second;
6029     Point point;
6030     if (screenGroup->combination_ == ScreenCombination::SCREEN_EXPAND) {
6031         point = {screen->GetActiveScreenMode()->width_, 0};
6032     }
6033     screenGroup->AddChild(newScreen, point, screen);
6034     return screenGroup;
6035 }
6036 
RemoveFromGroupLocked(sptr<ScreenSession> screen)6037 sptr<ScreenSessionGroup> ScreenSessionManager::RemoveFromGroupLocked(sptr<ScreenSession> screen)
6038 {
6039     TLOGI(WmsLogTag::DMS, "start");
6040     auto groupSmsId = screen->groupSmsId_;
6041     sptr<ScreenSessionGroup> screenGroup = GetAbstractScreenGroup(groupSmsId);
6042     if (!screenGroup) {
6043         TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64"is not in smsScreenGroupMap_.",
6044             groupSmsId);
6045         return nullptr;
6046     }
6047     if (!RemoveChildFromGroup(screen, screenGroup)) {
6048         return nullptr;
6049     }
6050     return screenGroup;
6051 }
6052 
RemoveChildFromGroup(sptr<ScreenSession> screen,sptr<ScreenSessionGroup> screenGroup)6053 bool ScreenSessionManager::RemoveChildFromGroup(sptr<ScreenSession> screen, sptr<ScreenSessionGroup> screenGroup)
6054 {
6055     auto rsUIContext = screen ? screen->GetRSUIContext() : nullptr;
6056     bool res = screenGroup->RemoveChild(screen);
6057     RSTransactionAdapter::FlushImplicitTransaction(rsUIContext);
6058     TLOGI(WmsLogTag::DMS, "remove child and call flush.");
6059     if (!res) {
6060         TLOGE(WmsLogTag::DMS, "remove screen:%{public}" PRIu64" failed from screenGroup:%{public}" PRIu64".",
6061             screen->screenId_, screen->groupSmsId_);
6062         return false;
6063     }
6064     if (screenGroup->GetChildCount() == 0) {
6065         // Group removed, need to do something.
6066         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6067         smsScreenGroupMap_.erase(screenGroup->screenId_);
6068         screenSessionMap_.erase(screenGroup->screenId_);
6069         TLOGE(WmsLogTag::DMS, "screenSessionMap_ remove screen:%{public}" PRIu64, screenGroup->screenId_);
6070     }
6071     return true;
6072 }
6073 
SetMirror(ScreenId screenId,std::vector<ScreenId> screens,DMRect mainScreenRegion)6074 DMError ScreenSessionManager::SetMirror(ScreenId screenId, std::vector<ScreenId> screens, DMRect mainScreenRegion)
6075 {
6076     TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64"", screenId);
6077     sptr<ScreenSession> screen = GetScreenSession(screenId);
6078     if (screen == nullptr || screen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
6079         TLOGE(WmsLogTag::DMS, "screen is nullptr, or screenCommbination is mirror.");
6080         return DMError::DM_ERROR_NULLPTR;
6081     }
6082     screen->groupSmsId_ = 1;
6083     auto group = GetAbstractScreenGroup(screen->groupSmsId_);
6084     if (group == nullptr) {
6085         group = AddToGroupLocked(screen);
6086         if (group == nullptr) {
6087             TLOGE(WmsLogTag::DMS, "group is nullptr");
6088             return DMError::DM_ERROR_NULLPTR;
6089         }
6090         NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
6091     }
6092     Point point;
6093     std::vector<Point> startPoints;
6094     startPoints.insert(startPoints.begin(), screens.size(), point);
6095     bool filterMirroredScreen =
6096         group->combination_ == ScreenCombination::SCREEN_MIRROR && group->mirrorScreenId_ == screen->screenId_;
6097     group->mirrorScreenId_ = screen->screenId_;
6098     ChangeScreenGroup(group, screens, startPoints, filterMirroredScreen, ScreenCombination::SCREEN_MIRROR,
6099         mainScreenRegion);
6100     TLOGI(WmsLogTag::DMS, "success");
6101     return DMError::DM_OK;
6102 }
6103 
GetAbstractScreenGroup(ScreenId smsScreenId)6104 sptr<ScreenSessionGroup> ScreenSessionManager::GetAbstractScreenGroup(ScreenId smsScreenId)
6105 {
6106     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6107     auto iter = smsScreenGroupMap_.find(smsScreenId);
6108     if (iter == smsScreenGroupMap_.end()) {
6109         TLOGE(WmsLogTag::DMS, "did not find screen:%{public}" PRIu64"", smsScreenId);
6110         return nullptr;
6111     }
6112     return iter->second;
6113 }
6114 
CheckScreenInScreenGroup(sptr<ScreenSession> screen) const6115 bool ScreenSessionManager::CheckScreenInScreenGroup(sptr<ScreenSession> screen) const
6116 {
6117     if (screen == nullptr) {
6118         TLOGE(WmsLogTag::DMS, "screen is nullptr");
6119         return false;
6120     }
6121     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6122     auto groupSmsId = screen->groupSmsId_;
6123     auto iter = smsScreenGroupMap_.find(groupSmsId);
6124     if (iter == smsScreenGroupMap_.end()) {
6125         TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64"is not in smsScreenGroupMap_.", groupSmsId);
6126         return false;
6127     }
6128     sptr<ScreenSessionGroup> screenGroup = iter->second;
6129     return screenGroup->HasChild(screen->screenId_);
6130 }
6131 
ChangeScreenGroup(sptr<ScreenSessionGroup> group,const std::vector<ScreenId> & screens,const std::vector<Point> & startPoints,bool filterScreen,ScreenCombination combination,DMRect mainScreenRegion)6132 void ScreenSessionManager::ChangeScreenGroup(sptr<ScreenSessionGroup> group, const std::vector<ScreenId>& screens,
6133     const std::vector<Point>& startPoints, bool filterScreen, ScreenCombination combination, DMRect mainScreenRegion)
6134 {
6135     std::map<ScreenId, bool> removeChildResMap;
6136     std::vector<ScreenId> addScreens;
6137     std::vector<Point> addChildPos;
6138     for (uint64_t i = 0; i != screens.size(); i++) {
6139         ScreenId screenId = screens[i];
6140         TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64"", screenId);
6141         auto screen = GetScreenSession(screenId);
6142         if (screen == nullptr) {
6143             TLOGE(WmsLogTag::DMS, "screen:%{public}" PRIu64" is nullptr", screenId);
6144             continue;
6145         }
6146         TLOGI(WmsLogTag::DMS, "Screen->groupSmsId_: %{public}" PRIu64"", screen->groupSmsId_);
6147         screen->groupSmsId_ = 1;
6148         if (!HasSameScreenCastInfo(screen->GetScreenId(), group->mirrorScreenId_, combination)) {
6149             TLOGI(WmsLogTag::DMS, "has not same cast info");
6150             filterScreen = false;
6151         }
6152         if (filterScreen && screen->groupSmsId_ == group->screenId_ && group->HasChild(screen->screenId_)) {
6153             // screen already in group
6154             if (combination != ScreenCombination::SCREEN_MIRROR ||
6155                 (screen->GetMirrorScreenRegion().second == mainScreenRegion &&
6156                 screen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR)) {
6157                 continue;
6158             }
6159             // mirror mode and mirror area change
6160             TLOGI(WmsLogTag::DMS, "Screen: %{public}" PRIu64
6161                 ", apply new region, x:%{public}d y:%{public}d w:%{public}u h:%{public}u", screenId,
6162                 mainScreenRegion.posX_, mainScreenRegion.posY_, mainScreenRegion.width_, mainScreenRegion.height_);
6163         }
6164         if (CheckScreenInScreenGroup(screen)) {
6165             NotifyDisplayDestroy(screenId);
6166         }
6167         auto originGroup = RemoveFromGroupLocked(screen);
6168         addChildPos.emplace_back(startPoints[i]);
6169         removeChildResMap[screenId] = originGroup != nullptr;
6170         addScreens.emplace_back(screenId);
6171         if (combination == ScreenCombination::SCREEN_MIRROR) {
6172             ChangeMirrorScreenConfig(group, mainScreenRegion, screen);
6173         }
6174         NotifyScreenChanged(screen->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SOURCE_MODE_CHANGE);
6175         NotifyDisplayChanged(screen->ConvertToDisplayInfo(), DisplayChangeEvent::SOURCE_MODE_CHANGED);
6176         SetScreenCastInfo(screen->GetScreenId(), group->mirrorScreenId_, combination);
6177     }
6178     group->combination_ = combination;
6179     AddScreenToGroup(group, addScreens, addChildPos, removeChildResMap);
6180 }
6181 
ChangeMirrorScreenConfig(const sptr<ScreenSessionGroup> & group,const DMRect & mainScreenRegion,sptr<ScreenSession> & screen)6182 void ScreenSessionManager::ChangeMirrorScreenConfig(const sptr<ScreenSessionGroup>& group,
6183         const DMRect& mainScreenRegion, sptr<ScreenSession>& screen)
6184 {
6185     if (screen == nullptr) {
6186         return;
6187     }
6188     auto screenId = screen->GetScreenId();
6189     if (group == nullptr) {
6190         return;
6191     }
6192     auto mirrorScreenId = group->mirrorScreenId_;
6193     ScreenId rsScreenId = SCREEN_ID_INVALID;
6194     if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
6195         TLOGE(WmsLogTag::DMS, "Screen: %{public}" PRIu64" convert to rs id failed", mirrorScreenId);
6196         return;
6197     }
6198     screen->SetMirrorScreenRegion(rsScreenId, mainScreenRegion);
6199     screen->SetIsPhysicalMirrorSwitch(false);
6200     IsEnableRegionRotation(screen);
6201     TLOGI(WmsLogTag::DMS, "Screen: %{public}" PRIu64" mirror to %{public}"
6202         PRIu64" with region, x:%{public}d y:%{public}d w:%{public}u h:%{public}u",
6203         screenId, mirrorScreenId, mainScreenRegion.posX_, mainScreenRegion.posY_,
6204         mainScreenRegion.width_, mainScreenRegion.height_);
6205 }
6206 
HasSameScreenCastInfo(ScreenId screenId,ScreenId castScreenId,ScreenCombination screenCombination)6207 bool ScreenSessionManager::HasSameScreenCastInfo(ScreenId screenId,
6208     ScreenId castScreenId, ScreenCombination screenCombination)
6209 {
6210     std::shared_lock<std::shared_mutex> lock(screenCastInfoMapMutex_);
6211     auto iter = screenCastInfoMap_.find(screenId);
6212     if (iter != screenCastInfoMap_.end() && iter->second.first == castScreenId &&
6213         iter->second.second == screenCombination) {
6214         return true;
6215     }
6216     return false;
6217 }
6218 
SetScreenCastInfo(ScreenId screenId,ScreenId castScreenId,ScreenCombination screenCombination)6219 void ScreenSessionManager::SetScreenCastInfo(ScreenId screenId,
6220     ScreenId castScreenId, ScreenCombination screenCombination)
6221 {
6222     std::unique_lock<std::shared_mutex> lock(screenCastInfoMapMutex_);
6223     screenCastInfoMap_.insert(std::make_pair(screenId, std::make_pair(castScreenId, screenCombination)));
6224     TLOGI(WmsLogTag::DMS,
6225         "screenId:%{public}" PRIu64 ",castScreenId:%{public}" PRIu64 ",screenCombination:%{public}d",
6226         screenId, castScreenId, screenCombination);
6227 }
6228 
RemoveScreenCastInfo(ScreenId screenId)6229 void ScreenSessionManager::RemoveScreenCastInfo(ScreenId screenId)
6230 {
6231     std::unique_lock<std::shared_mutex> lock(screenCastInfoMapMutex_);
6232     auto iter = screenCastInfoMap_.find(screenId);
6233     if (iter == screenCastInfoMap_.end()) {
6234         return;
6235     }
6236     screenCastInfoMap_.erase(iter);
6237     TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 "", screenId);
6238 }
6239 
IsEnableRegionRotation(sptr<ScreenSession> screenSession)6240 void ScreenSessionManager::IsEnableRegionRotation(sptr<ScreenSession> screenSession)
6241 {
6242     if (!FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
6243         screenSession->SetIsEnableRegionRotation(false);
6244         TLOGI(WmsLogTag::DMS, "Region rotation is not supported");
6245         return;
6246     }
6247     if (screenSession->GetName() == "screen_capture_file" || screenSession->GetName() == "screen_capture") {
6248         screenSession->SetIsEnableRegionRotation(false);
6249     } else {
6250         screenSession->SetIsEnableRegionRotation(true);
6251     }
6252     TLOGI(WmsLogTag::DMS, "Screen session name: %{public}s", screenSession->GetName().c_str());
6253 }
6254 
AddScreenToGroup(sptr<ScreenSessionGroup> group,const std::vector<ScreenId> & addScreens,const std::vector<Point> & addChildPos,std::map<ScreenId,bool> & removeChildResMap)6255 void ScreenSessionManager::AddScreenToGroup(sptr<ScreenSessionGroup> group,
6256     const std::vector<ScreenId>& addScreens, const std::vector<Point>& addChildPos,
6257     std::map<ScreenId, bool>& removeChildResMap)
6258 {
6259     std::vector<sptr<ScreenInfo>> addToGroup;
6260     std::vector<sptr<ScreenInfo>> removeFromGroup;
6261     std::vector<sptr<ScreenInfo>> changeGroup;
6262     for (uint64_t i = 0; i != addScreens.size(); i++) {
6263         ScreenId screenId = addScreens[i];
6264         sptr<ScreenSession> screen = GetScreenSession(screenId);
6265         if (screen == nullptr) {
6266             continue;
6267         }
6268         Point expandPoint = addChildPos[i];
6269         TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64", Point: %{public}d, %{public}d",
6270             screen->screenId_, expandPoint.posX_, expandPoint.posY_);
6271         bool addChildRes = group->AddChild(screen, expandPoint, GetScreenSession(group->mirrorScreenId_));
6272         if (removeChildResMap[screenId] && addChildRes) {
6273             changeGroup.emplace_back(screen->ConvertToScreenInfo());
6274             TLOGD(WmsLogTag::DMS, "changeGroup");
6275         } else if (removeChildResMap[screenId]) {
6276             TLOGD(WmsLogTag::DMS, "removeChild");
6277             removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
6278         } else if (addChildRes) {
6279             TLOGD(WmsLogTag::DMS, "AddChild");
6280             addToGroup.emplace_back(screen->ConvertToScreenInfo());
6281         } else {
6282             TLOGD(WmsLogTag::DMS, "default, AddChild failed");
6283         }
6284         NotifyDisplayCreate(screen->ConvertToDisplayInfo());
6285     }
6286 
6287     NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
6288     NotifyScreenGroupChanged(changeGroup, ScreenGroupChangeEvent::CHANGE_GROUP);
6289     NotifyScreenGroupChanged(addToGroup, ScreenGroupChangeEvent::ADD_TO_GROUP);
6290 }
6291 
RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)6292 void ScreenSessionManager::RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)
6293 {
6294     TLOGW(WmsLogTag::DMS, "enter!");
6295     if (!SessionPermission::IsSystemCalling()) {
6296         TLOGE(WmsLogTag::DMS, "permission denied calling: %{public}s, pid: %{public}d",
6297             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6298         return;
6299     }
6300     if (screens.empty()) {
6301         return;
6302     }
6303     std::vector<sptr<ScreenInfo>> removeFromGroup;
6304     for (ScreenId screenId : screens) {
6305         auto screen = GetScreenSession(screenId);
6306         if (screen == nullptr || screen->GetScreenProperty().GetScreenType() != ScreenType::VIRTUAL) {
6307             continue;
6308         }
6309         auto originGroup = GetAbstractScreenGroup(screen->groupSmsId_);
6310         if (originGroup == nullptr) {
6311             continue;
6312         }
6313         if (!originGroup->HasChild(screenId)) {
6314             continue;
6315         }
6316         RemoveFromGroupLocked(screen);
6317         removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
6318     }
6319     NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
6320 }
6321 
GetRSDisplayNodeByScreenId(ScreenId smsScreenId) const6322 const std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetRSDisplayNodeByScreenId(ScreenId smsScreenId) const
6323 {
6324     static std::shared_ptr<RSDisplayNode> notFound = nullptr;
6325     sptr<ScreenSession> screen = GetScreenSession(smsScreenId);
6326     if (screen == nullptr) {
6327         TLOGE(WmsLogTag::DMS, "screen == nullptr!");
6328         return notFound;
6329     }
6330     if (screen->GetDisplayNode() == nullptr) {
6331         TLOGE(WmsLogTag::DMS, "displayNode_ == nullptr!");
6332         return notFound;
6333     }
6334     TLOGI(WmsLogTag::DMS, "screen: %{public}" PRIu64", nodeId: %{public}" PRIu64" ",
6335         screen->screenId_, screen->GetDisplayNode()->GetId());
6336     return screen->GetDisplayNode();
6337 }
6338 
GetDisplayNodeByDisplayId(DisplayId displayId)6339 std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetDisplayNodeByDisplayId(DisplayId displayId)
6340 {
6341     std::shared_ptr<RSDisplayNode> displayNode = nullptr;
6342     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6343     for (auto sessionIt : screenSessionMap_) {
6344         auto screenSession = sessionIt.second;
6345         if (screenSession == nullptr) {
6346             TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
6347             continue;
6348         }
6349         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
6350         if (displayInfo == nullptr) {
6351             TLOGE(WmsLogTag::DMS, "displayInfo is nullptr!");
6352             continue;
6353         }
6354         if (displayId == displayInfo->GetDisplayId()) {
6355             if (sessionIt.first == SCREEN_ID_INVALID) {
6356                 TLOGE(WmsLogTag::DMS, "screenId is invalid!");
6357                 continue;
6358             }
6359             displayNode = screenSession->GetDisplayNode();
6360             break;
6361         }
6362     }
6363     return displayNode;
6364 }
6365 
IsFakeDisplayExist()6366 bool ScreenSessionManager::IsFakeDisplayExist()
6367 {
6368     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
6369         SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
6370         return true;
6371     }
6372     return false;
6373 }
6374 
GetScreenSnapshot(DisplayId displayId,bool isUseDma,bool isCaptureFullOfScreen,const std::vector<NodeId> & surfaceNodesList)6375 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetScreenSnapshot(DisplayId displayId, bool isUseDma,
6376     bool isCaptureFullOfScreen, const std::vector<NodeId>& surfaceNodesList)
6377 {
6378     DisplayId realDisplayId = displayId;
6379     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && displayId == DISPLAY_ID_FAKE) {
6380         if (!SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
6381             TLOGE(WmsLogTag::DMS, "fake display is not exist!");
6382             return nullptr;
6383         }
6384         realDisplayId = 0;
6385     }
6386     TLOGW(WmsLogTag::DMS, "dma=%{public}d, displayId:%{public}" PRIu64, isUseDma, realDisplayId);
6387     std::shared_ptr<RSDisplayNode> displayNode = GetDisplayNodeByDisplayId(realDisplayId);
6388     if (displayNode == nullptr) {
6389         TLOGE(WmsLogTag::DMS, "displayNode is null!");
6390         return nullptr;
6391     }
6392     std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
6393     RSSurfaceCaptureConfig config;
6394     config.isHdrCapture = false;
6395     config.useDma = isUseDma;
6396 #ifdef FOLD_ABILITY_ENABLE
6397     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
6398         SuperFoldPolicy::GetInstance().IsNeedSetSnapshotRect(displayId)) {
6399         config.mainScreenRect = SuperFoldPolicy::GetInstance().GetSnapshotRect(displayId, isCaptureFullOfScreen);
6400     }
6401 #endif
6402     config.blackList = surfaceNodesList;
6403     if (surfaceNodesList.size() > 0) {
6404         TLOGI(WmsLogTag::DMS, "Snapshot filtering surfaceNodesList surfaceNodes, size:%{public}ud",
6405             static_cast<uint32_t>(surfaceNodesList.size()));
6406     }
6407     bool ret = rsInterface_.TakeSurfaceCapture(displayNode, callback, config);
6408     if (!ret) {
6409         TLOGE(WmsLogTag::DMS, "TakeSurfaceCapture failed");
6410         return nullptr;
6411     }
6412     std::shared_ptr<Media::PixelMap> screenshot = callback->GetResult(GET_HDR_PIXELMAP_TIMEOUT);  // wait for <= 2000ms
6413     if (screenshot == nullptr) {
6414         TLOGE(WmsLogTag::DMS, "Failed to get pixelmap from RS, return nullptr!");
6415     } else {
6416         TLOGD(WmsLogTag::DMS, "Sucess to get pixelmap from RS!");
6417     }
6418     // notify dm listener
6419     sptr<ScreenshotInfo> snapshotInfo = new ScreenshotInfo();
6420     snapshotInfo->SetTrigger(SysCapUtil::GetClientName());
6421     snapshotInfo->SetDisplayId(displayId);
6422     OnScreenshot(snapshotInfo);
6423     return screenshot;
6424 }
6425 
GetScreenHDRSnapshot(DisplayId displayId,bool isUseDma,bool isCaptureFullOfScreen,const std::vector<NodeId> & surfaceNodesList)6426 std::vector<std::shared_ptr<Media::PixelMap>> ScreenSessionManager::GetScreenHDRSnapshot(
6427     DisplayId displayId, bool isUseDma, bool isCaptureFullOfScreen, const std::vector<NodeId>& surfaceNodesList)
6428 {
6429     DisplayId realDisplayId = displayId;
6430 #ifdef FOLD_ABILITY_ENABLE
6431     static bool isSuperFoldDisplayDevice = FoldScreenStateInternel::IsSuperFoldDisplayDevice();
6432     if (isSuperFoldDisplayDevice && displayId == DISPLAY_ID_FAKE) {
6433         if (!SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
6434             TLOGE(WmsLogTag::DMS, "fake display is not exist!");
6435             return {nullptr, nullptr};
6436         }
6437         realDisplayId = 0;
6438     }
6439 #endif
6440     std::shared_ptr<RSDisplayNode> displayNode = GetDisplayNodeByDisplayId(realDisplayId);
6441     if (displayNode == nullptr) {
6442         TLOGE(WmsLogTag::DMS, "displayNode is null!");
6443         return {nullptr, nullptr};
6444     }
6445     std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
6446     RSSurfaceCaptureConfig config;
6447     config.isHdrCapture = true;
6448     config.useDma = isUseDma;
6449     TLOGI(WmsLogTag::DMS, "take surface capture with dma=%{public}d", isUseDma);
6450 #ifdef FOLD_ABILITY_ENABLE
6451     if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
6452         config.mainScreenRect = foldScreenController_->GetScreenSnapshotRect();
6453     }
6454     if (isSuperFoldDisplayDevice && SuperFoldPolicy::GetInstance().IsNeedSetSnapshotRect(displayId)) {
6455         config.mainScreenRect = SuperFoldPolicy::GetInstance().GetSnapshotRect(displayId, isCaptureFullOfScreen);
6456     }
6457 #endif
6458     config.blackList = surfaceNodesList;
6459     if (surfaceNodesList.size() > 0) {
6460         TLOGI(WmsLogTag::DMS, "Snapshot filter, size:%{public}ud", static_cast<uint32_t>(surfaceNodesList.size()));
6461     }
6462     bool ret = rsInterface_.TakeSurfaceCapture(displayNode, callback, config);
6463     if (!ret) {
6464         TLOGE(WmsLogTag::DMS, "TakeSurfaceCapture failed");
6465         return {nullptr, nullptr};
6466     }
6467     // wait for <= 2000ms
6468     std::vector<std::shared_ptr<Media::PixelMap>> screenshotVec = callback->GetHDRResult(GET_HDR_PIXELMAP_TIMEOUT);
6469     if (screenshotVec.size() != PIXMAP_VECTOR_SIZE || screenshotVec[0] == nullptr) {
6470         TLOGE(WmsLogTag::DMS, "Failed to get pixelmap vector from RS, return nullptr!");
6471         return {nullptr, nullptr};
6472     }
6473     // notify dm listener
6474     sptr<ScreenshotInfo> snapshotInfo = new ScreenshotInfo();
6475     snapshotInfo->SetTrigger(SysCapUtil::GetClientName());
6476     snapshotInfo->SetDisplayId(displayId);
6477     OnScreenshot(snapshotInfo);
6478     return screenshotVec;
6479 }
6480 
GetDisplaySnapshot(DisplayId displayId,DmErrorCode * errorCode,bool isUseDma,bool isCaptureFullOfScreen)6481 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetDisplaySnapshot(DisplayId displayId,
6482     DmErrorCode* errorCode, bool isUseDma, bool isCaptureFullOfScreen)
6483 {
6484     TLOGD(WmsLogTag::DMS, "enter!");
6485     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall() && errorCode) {
6486         *errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
6487         return nullptr;
6488     }
6489     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false) && errorCode) {
6490         TLOGI(WmsLogTag::DMS, "snapshot disabled by edm!");
6491         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6492         return nullptr;
6493     }
6494     if (displayId == DISPLAY_ID_FAKE && !IsFakeDisplayExist() && errorCode) {
6495         *errorCode = DmErrorCode::DM_ERROR_INVALID_SCREEN;
6496         TLOGE(WmsLogTag::DMS, "fake display not exist!");
6497         return nullptr;
6498     }
6499     if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
6500         SessionPermission::IsShellCall()) {
6501         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplaySnapshot(%" PRIu64")", displayId);
6502         auto res = GetScreenSnapshot(displayId, isUseDma, isCaptureFullOfScreen);
6503         if (res != nullptr) {
6504             NotifyScreenshot(displayId);
6505             if (SessionPermission::IsBetaVersion()) {
6506                 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
6507             }
6508         }
6509         isScreenShot_ = true;
6510         NotifyCaptureStatusChanged();
6511         return res;
6512     } else if (errorCode) {
6513         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6514     }
6515     return nullptr;
6516 }
6517 
GetDisplayHDRSnapshot(DisplayId displayId,DmErrorCode & errorCode,bool isUseDma,bool isCaptureFullOfScreen)6518 std::vector<std::shared_ptr<Media::PixelMap>> ScreenSessionManager::GetDisplayHDRSnapshot(DisplayId displayId,
6519     DmErrorCode& errorCode, bool isUseDma, bool isCaptureFullOfScreen)
6520 {
6521     TLOGI(WmsLogTag::DMS, "enter!");
6522     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall()) {
6523         errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
6524         return {nullptr, nullptr};
6525     }
6526     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
6527         TLOGE(WmsLogTag::DMS, "snapshot disabled by edm!");
6528         errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6529         return {nullptr, nullptr};
6530     }
6531     if (displayId == DISPLAY_ID_FAKE && !IsFakeDisplayExist()) {
6532         TLOGE(WmsLogTag::DMS, "fake display not exist!");
6533         errorCode = DmErrorCode::DM_ERROR_INVALID_SCREEN;
6534         return {nullptr, nullptr};
6535     }
6536     if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
6537         SessionPermission::IsShellCall()) {
6538         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplayHDRSnapshot(%" PRIu64")", displayId);
6539         std::vector<std::shared_ptr<Media::PixelMap>> res = GetScreenHDRSnapshot(
6540             displayId, isUseDma, isCaptureFullOfScreen);
6541         if (res.size() == PIXMAP_VECTOR_SIZE && res[SDR_PIXMAP] != nullptr) {
6542             NotifyScreenshot(displayId);
6543             if (SessionPermission::IsBetaVersion()) {
6544                 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
6545             }
6546         } else {
6547             TLOGE(WmsLogTag::DMS, "GetScreenHDRSnapshot get PixelMap vector failed");
6548         }
6549         isScreenShot_ = true;
6550         NotifyCaptureStatusChanged();
6551         return res;
6552     } else {
6553         errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6554     }
6555     return {nullptr, nullptr};
6556 }
6557 
GetDisplaySnapshotWithOption(const CaptureOption & option,DmErrorCode * errorCode)6558 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetDisplaySnapshotWithOption(const CaptureOption& option,
6559     DmErrorCode* errorCode)
6560 {
6561     TLOGD(WmsLogTag::DMS, "enter!");
6562     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall() &&
6563         !SessionPermission::IsSACalling()) {
6564         if (errorCode != nullptr) {
6565             *errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
6566         }
6567         return nullptr;
6568     }
6569     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
6570         TLOGI(WmsLogTag::DMS, "snapshot was disabled by edm!");
6571         return nullptr;
6572     }
6573     if (option.displayId_ == DISPLAY_ID_FAKE && !IsFakeDisplayExist() && errorCode) {
6574         TLOGE(WmsLogTag::DMS, "fake display not exist!");
6575         *errorCode = DmErrorCode::DM_ERROR_INVALID_SCREEN;
6576         return nullptr;
6577     }
6578     if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
6579         SessionPermission::IsShellCall()) {
6580         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplaySnapshot(%" PRIu64")", option.displayId_);
6581         auto res = GetScreenSnapshot(option.displayId_, true, option.isCaptureFullOfScreen_, option.surfaceNodesList_);
6582         if (res != nullptr) {
6583             if (SessionPermission::IsBetaVersion()) {
6584                 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
6585             }
6586             TLOGI(WmsLogTag::DMS, "isNeedNotify_:%{public}d", option.isNeedNotify_);
6587             if (option.isNeedNotify_) {
6588                 isScreenShot_ = true;
6589                 NotifyScreenshot(option.displayId_);
6590                 NotifyCaptureStatusChanged();
6591             }
6592         }
6593         return res;
6594     } else if (errorCode) {
6595         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6596     }
6597     return nullptr;
6598 }
6599 
GetDisplayHDRSnapshotWithOption(const CaptureOption & option,DmErrorCode & errorCode)6600 std::vector<std::shared_ptr<Media::PixelMap>> ScreenSessionManager::GetDisplayHDRSnapshotWithOption(
6601     const CaptureOption& option, DmErrorCode& errorCode)
6602 {
6603     TLOGD(WmsLogTag::DMS, "enter!");
6604     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall() &&
6605         !SessionPermission::IsSACalling()) {
6606         errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
6607         return {nullptr, nullptr};
6608     }
6609     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
6610         TLOGE(WmsLogTag::DMS, "snapshot was disabled by edm!");
6611         errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6612         return {nullptr, nullptr};
6613     }
6614     if (option.displayId_ == DISPLAY_ID_FAKE && !IsFakeDisplayExist()) {
6615         TLOGE(WmsLogTag::DMS, "fake display not exist!");
6616         errorCode = DmErrorCode::DM_ERROR_INVALID_SCREEN;
6617         return {nullptr, nullptr};
6618     }
6619     if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
6620         SessionPermission::IsShellCall()) {
6621         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
6622             "ssm:GetDisplayHDRSnapshotWithOption(%" PRIu64")", option.displayId_);
6623         std::vector<std::shared_ptr<Media::PixelMap>> res = GetScreenHDRSnapshot(
6624             option.displayId_, true, option.isCaptureFullOfScreen_, option.surfaceNodesList_);
6625         if (res.size() == PIXMAP_VECTOR_SIZE && res[SDR_PIXMAP] != nullptr) {
6626             if (SessionPermission::IsBetaVersion()) {
6627                 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
6628             }
6629             TLOGI(WmsLogTag::DMS, "isNeedNotify_:%{public}d", option.isNeedNotify_);
6630             if (option.isNeedNotify_) {
6631                 isScreenShot_ = true;
6632                 NotifyScreenshot(option.displayId_);
6633                 NotifyCaptureStatusChanged();
6634             }
6635         }
6636         return res;
6637     } else {
6638         errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6639     }
6640     return {nullptr, nullptr};
6641 }
6642 
GetSnapshotByPicker(Media::Rect & rect,DmErrorCode * errorCode)6643 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetSnapshotByPicker(Media::Rect &rect, DmErrorCode* errorCode)
6644 {
6645     TLOGD(WmsLogTag::DMS, "ENTER!");
6646     *errorCode = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
6647     std::lock_guard<std::mutex> lock(snapBypickerMutex_);
6648 
6649     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
6650         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6651         TLOGI(WmsLogTag::DMS, "snapshot was disabled by edm!");
6652         return nullptr;
6653     }
6654     ScreenId screenId = SCREEN_ID_INVALID;
6655     // get snapshot area frome Screenshot extension
6656     if (!GetSnapshotArea(rect, errorCode, screenId)) {
6657         return nullptr;
6658     }
6659     auto screenSession = GetScreenSession(screenId);
6660     if (screenSession == nullptr) {
6661         TLOGE(WmsLogTag::DMS, "can not get screen session");
6662         return nullptr;
6663     }
6664     sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
6665     if (displayInfo == nullptr) {
6666         TLOGE(WmsLogTag::DMS, "can not get default display");
6667         return nullptr;
6668     }
6669     DisplayId displayId = displayInfo->GetDisplayId();
6670     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSnapshotByPicker(%" PRIu64")", displayId);
6671     auto pixelMap = GetScreenSnapshot(displayId, false);
6672     if (pixelMap != nullptr && SessionPermission::IsBetaVersion()) {
6673         CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
6674     }
6675     isScreenShot_ = true;
6676     NotifyCaptureStatusChanged();
6677     *errorCode = DmErrorCode::DM_OK;
6678     return pixelMap;
6679 }
6680 
GetSnapshotArea(Media::Rect & rect,DmErrorCode * errorCode,ScreenId & screenId)6681 bool ScreenSessionManager::GetSnapshotArea(Media::Rect &rect, DmErrorCode* errorCode, ScreenId &screenId)
6682 {
6683     ConfigureScreenSnapshotParams();
6684     if (ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerConnectExtension()) {
6685         int32_t ret = ScreenSnapshotPickerConnection::GetInstance().GetScreenSnapshotInfo(rect, screenId);
6686         if (ret != 0) {
6687             TLOGE(WmsLogTag::DMS, "GetScreenSnapshotInfo failed");
6688             ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerDisconnectExtension();
6689             if (ret == RES_FAILURE_FOR_PRIVACY_WINDOW) {
6690                 *errorCode = DmErrorCode::DM_ERROR_INVALID_CALLING;
6691             } else {
6692                 *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
6693             }
6694             return false;
6695         }
6696         ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerDisconnectExtension();
6697     } else {
6698         *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
6699         TLOGE(WmsLogTag::DMS, "SnapshotPickerConnectExtension failed");
6700         return false;
6701     }
6702     return true;
6703 }
6704 
OnRemoteDied(const sptr<IRemoteObject> & agent)6705 bool ScreenSessionManager::OnRemoteDied(const sptr<IRemoteObject>& agent)
6706 {
6707     if (agent == nullptr) {
6708         return false;
6709     }
6710     std::vector<ScreenId> screenVecCopy;
6711     {
6712         std::lock_guard<std::mutex> lock(screenAgentMapMutex_);
6713         auto agentIter = screenAgentMap_.find(agent);
6714         if (agentIter != screenAgentMap_.end()) {
6715             screenVecCopy = agentIter->second;
6716         }
6717     }
6718     bool ret = true;
6719     for (const auto screenId : screenVecCopy) {
6720         auto screenSession = GetScreenSession(screenId);
6721         if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
6722             TLOGI(WmsLogTag::DMS, "stop mirror in OnRemoteDied: %{public}" PRIu64, screenId);
6723             StopMirror(std::vector<ScreenId>(1, screenId));
6724         }
6725         TLOGI(WmsLogTag::DMS, "destroy screenId in OnRemoteDied: %{public}" PRIu64, screenId);
6726         DMError res = DestroyVirtualScreen(screenId);
6727         if (res != DMError::DM_OK) {
6728             TLOGE(WmsLogTag::DMS, "destroy failed in OnRemoteDied: %{public}" PRIu64, screenId);
6729             ret = false;
6730         }
6731     }
6732     return ret;
6733 }
6734 
GetAllValidScreenIds(const std::vector<ScreenId> & screenIds) const6735 std::vector<ScreenId> ScreenSessionManager::GetAllValidScreenIds(const std::vector<ScreenId>& screenIds) const
6736 {
6737     std::vector<ScreenId> validScreenIds;
6738     for (ScreenId screenId : screenIds) {
6739         auto screenIdIter = std::find(validScreenIds.begin(), validScreenIds.end(), screenId);
6740         if (screenIdIter != validScreenIds.end()) {
6741             continue;
6742         }
6743         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6744         auto iter = screenSessionMap_.find(screenId);
6745         if (iter != screenSessionMap_.end() && iter->second != nullptr &&
6746                 iter->second->GetScreenProperty().GetScreenType() != ScreenType::UNDEFINED) {
6747             validScreenIds.emplace_back(screenId);
6748         }
6749     }
6750     return validScreenIds;
6751 }
6752 
GetScreenGroupInfoById(ScreenId screenId)6753 sptr<ScreenGroupInfo> ScreenSessionManager::GetScreenGroupInfoById(ScreenId screenId)
6754 {
6755     if (!SessionPermission::IsSystemCalling()) {
6756         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
6757             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6758         return nullptr;
6759     }
6760     auto screenSessionGroup = GetAbstractScreenGroup(screenId);
6761     if (screenSessionGroup == nullptr) {
6762         TLOGE(WmsLogTag::DMS, "cannot find screenGroupInfo: %{public}" PRIu64"", screenId);
6763         return nullptr;
6764     }
6765     return screenSessionGroup->ConvertToScreenGroupInfo();
6766 }
6767 
NotifyScreenConnected(sptr<ScreenInfo> screenInfo)6768 void ScreenSessionManager::NotifyScreenConnected(sptr<ScreenInfo> screenInfo)
6769 {
6770     if (screenInfo == nullptr) {
6771         TLOGE(WmsLogTag::DMS, "error, screenInfo is nullptr.");
6772         return;
6773     }
6774     auto task = [=] {
6775         TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64"", screenInfo->GetScreenId());
6776         OnScreenConnect(screenInfo);
6777     };
6778     taskScheduler_->PostAsyncTask(task, "NotifyScreenConnected");
6779 }
6780 
NotifyScreenDisconnected(ScreenId screenId)6781 void ScreenSessionManager::NotifyScreenDisconnected(ScreenId screenId)
6782 {
6783     auto task = [=] {
6784         TLOGNI(WmsLogTag::DMS, "notify screenId:%{public}" PRIu64"", screenId);
6785         OnScreenDisconnect(screenId);
6786     };
6787     taskScheduler_->PostAsyncTask(task, "NotifyScreenDisconnected");
6788 }
6789 
NotifyDisplayCreate(sptr<DisplayInfo> displayInfo)6790 void ScreenSessionManager::NotifyDisplayCreate(sptr<DisplayInfo> displayInfo)
6791 {
6792     if (displayInfo == nullptr) {
6793         return;
6794     }
6795     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
6796     TLOGI(WmsLogTag::DMS, "start, agent size: %{public}u", static_cast<uint32_t>(agents.size()));
6797     if (agents.empty()) {
6798         return;
6799     }
6800     for (auto& agent : agents) {
6801         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6802         if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
6803             agent->OnDisplayCreate(displayInfo);
6804         }
6805     }
6806 }
6807 
NotifyDisplayDestroy(DisplayId displayId)6808 void ScreenSessionManager::NotifyDisplayDestroy(DisplayId displayId)
6809 {
6810     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
6811     TLOGI(WmsLogTag::DMS, "agent size: %{public}u", static_cast<uint32_t>(agents.size()));
6812     if (agents.empty()) {
6813         return;
6814     }
6815     for (auto& agent : agents) {
6816         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6817         if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
6818             agent->OnDisplayDestroy(displayId);
6819         }
6820     }
6821 }
6822 
NotifyScreenGroupChanged(const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent event)6823 void ScreenSessionManager::NotifyScreenGroupChanged(
6824     const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent event)
6825 {
6826     if (screenInfo == nullptr) {
6827         TLOGE(WmsLogTag::DMS, "screenInfo is nullptr.");
6828         return;
6829     }
6830     std::string trigger = SysCapUtil::GetClientName();
6831     auto task = [=] {
6832         TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", trigger:[%{public}s]",
6833             screenInfo->GetScreenId(), trigger.c_str());
6834         OnScreenGroupChange(trigger, screenInfo, event);
6835     };
6836     taskScheduler_->PostAsyncTask(task, "NotifyScreenGroupChanged:PID");
6837 }
6838 
NotifyScreenGroupChanged(const std::vector<sptr<ScreenInfo>> & screenInfo,ScreenGroupChangeEvent event)6839 void ScreenSessionManager::NotifyScreenGroupChanged(
6840     const std::vector<sptr<ScreenInfo>>& screenInfo, ScreenGroupChangeEvent event)
6841 {
6842     if (screenInfo.empty()) {
6843         return;
6844     }
6845     std::string trigger = SysCapUtil::GetClientName();
6846     auto task = [=] {
6847         TLOGNI(WmsLogTag::DMS, "trigger:[%{public}s]", trigger.c_str());
6848         OnScreenGroupChange(trigger, screenInfo, event);
6849     };
6850     taskScheduler_->PostAsyncTask(task, "NotifyScreenGroupChanged");
6851 }
6852 
NotifyPrivateSessionStateChanged(bool hasPrivate)6853 void ScreenSessionManager::NotifyPrivateSessionStateChanged(bool hasPrivate)
6854 {
6855     if (hasPrivate == screenPrivacyStates) {
6856         TLOGD(WmsLogTag::DMS, "screen session state is not changed, return");
6857         return;
6858     }
6859     TLOGI(WmsLogTag::DMS, "status : %{public}u", hasPrivate);
6860     screenPrivacyStates = hasPrivate;
6861     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::PRIVATE_WINDOW_LISTENER);
6862     if (agents.empty()) {
6863         return;
6864     }
6865     for (auto& agent : agents) {
6866         agent->NotifyPrivateWindowStateChanged(hasPrivate);
6867     }
6868 }
6869 
SetScreenPrivacyState(bool hasPrivate)6870 void ScreenSessionManager::SetScreenPrivacyState(bool hasPrivate)
6871 {
6872     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6873         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
6874             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6875         return;
6876     }
6877     TLOGI(WmsLogTag::DMS, "enter, hasPrivate: %{public}d", hasPrivate);
6878     ScreenId id = GetDefaultScreenId();
6879     auto screenSession = GetScreenSession(id);
6880     if (screenSession == nullptr) {
6881         TLOGE(WmsLogTag::DMS, "can not get default screen now");
6882         return;
6883     }
6884     screenSession->SetPrivateSessionForeground(hasPrivate);
6885     NotifyPrivateSessionStateChanged(hasPrivate);
6886 }
6887 
SetPrivacyStateByDisplayId(DisplayId id,bool hasPrivate)6888 void ScreenSessionManager::SetPrivacyStateByDisplayId(DisplayId id, bool hasPrivate)
6889 {
6890     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6891         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
6892             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6893         return;
6894     }
6895     TLOGI(WmsLogTag::DMS, "enter, hasPrivate: %{public}d", hasPrivate);
6896     std::vector<ScreenId> screenIds = GetAllScreenIds();
6897     auto iter = std::find(screenIds.begin(), screenIds.end(), id);
6898     if (iter == screenIds.end()) {
6899         TLOGE(WmsLogTag::DMS, "invalid displayId");
6900         return;
6901     }
6902     auto screenSession = GetScreenSession(id);
6903     if (screenSession == nullptr) {
6904         TLOGE(WmsLogTag::DMS, "can not get id: %{public}" PRIu64" screen now", id);
6905         return;
6906     }
6907     screenSession->SetPrivateSessionForeground(hasPrivate);
6908     NotifyPrivateSessionStateChanged(hasPrivate);
6909 }
6910 
SetScreenPrivacyWindowList(DisplayId id,std::vector<std::string> privacyWindowList)6911 void ScreenSessionManager::SetScreenPrivacyWindowList(DisplayId id, std::vector<std::string> privacyWindowList)
6912 {
6913     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6914         TLOGE(WmsLogTag::DMS, "Permmission Denied! calling: %{public}s, pid: %{public}d",
6915             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6916         return;
6917     }
6918     TLOGW(WmsLogTag::DMS, "enter");
6919     std::vector<ScreenId> screenIds = GetAllScreenIds();
6920     auto iter = std::find(screenIds.begin(), screenIds.end(), id);
6921     if (iter == screenIds.end()) {
6922         TLOGE(WmsLogTag::DMS, "invalid displayId");
6923         return;
6924     }
6925     auto screenSession = GetScreenSession(id);
6926     if (screenSession == nullptr) {
6927         TLOGE(WmsLogTag::DMS, "can not get id: %{public}" PRIu64" screen now", id);
6928         return;
6929     }
6930     NotifyPrivateWindowListChanged(id, privacyWindowList);
6931 }
6932 
NotifyPrivateWindowListChanged(DisplayId id,std::vector<std::string> privacyWindowList)6933 void ScreenSessionManager::NotifyPrivateWindowListChanged(DisplayId id, std::vector<std::string> privacyWindowList)
6934 {
6935     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::PRIVATE_WINDOW_LIST_LISTENER);
6936     if (agents.empty()) {
6937         return;
6938     }
6939     for (auto& agent : agents) {
6940         agent->NotifyPrivateStateWindowListChanged(id, privacyWindowList);
6941     }
6942 }
6943 
HasPrivateWindow(DisplayId id,bool & hasPrivateWindow)6944 DMError ScreenSessionManager::HasPrivateWindow(DisplayId id, bool& hasPrivateWindow)
6945 {
6946     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6947         TLOGE(WmsLogTag::DMS, "Permmision Denied! calling: %{public}s, pid: %{public}d",
6948             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6949         return DMError::DM_ERROR_NOT_SYSTEM_APP;
6950     }
6951     if (id == DISPLAY_ID_FAKE) {
6952         auto displayInfo = GetDefaultDisplayInfo();
6953         if (displayInfo) {
6954             id = displayInfo->GetDisplayId();
6955             TLOGI(WmsLogTag::DMS, "change displayId: %{public}" PRIu64" to displayId: %{public}" PRIu64,
6956                 DISPLAY_ID_FAKE, id);
6957         }
6958     }
6959     std::vector<ScreenId> screenIds = GetAllScreenIds();
6960     auto iter = std::find(screenIds.begin(), screenIds.end(), id);
6961     if (iter == screenIds.end()) {
6962         TLOGE(WmsLogTag::DMS, "invalid displayId");
6963         return DMError::DM_ERROR_INVALID_PARAM;
6964     }
6965     auto screenSession = GetScreenSession(id);
6966     if (screenSession == nullptr) {
6967         return DMError::DM_ERROR_NULLPTR;
6968     }
6969     hasPrivateWindow = screenSession->HasPrivateSessionForeground();
6970     TLOGI(WmsLogTag::DMS, "id: %{public}" PRIu64" has private window: %{public}u",
6971         id, static_cast<uint32_t>(hasPrivateWindow));
6972     return DMError::DM_OK;
6973 }
6974 
OnScreenGroupChange(const std::string & trigger,const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent groupEvent)6975 void ScreenSessionManager::OnScreenGroupChange(const std::string& trigger,
6976     const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent groupEvent)
6977 {
6978     if (screenInfo == nullptr) {
6979         return;
6980     }
6981     std::vector<sptr<ScreenInfo>> screenInfos;
6982     screenInfos.push_back(screenInfo);
6983     OnScreenGroupChange(trigger, screenInfos, groupEvent);
6984 }
6985 
OnScreenGroupChange(const std::string & trigger,const std::vector<sptr<ScreenInfo>> & screenInfos,ScreenGroupChangeEvent groupEvent)6986 void ScreenSessionManager::OnScreenGroupChange(const std::string& trigger,
6987     const std::vector<sptr<ScreenInfo>>& screenInfos, ScreenGroupChangeEvent groupEvent)
6988 {
6989     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
6990     std::vector<sptr<ScreenInfo>> infos;
6991     for (auto& screenInfo : screenInfos) {
6992         if (screenInfo != nullptr) {
6993             infos.emplace_back(screenInfo);
6994         }
6995     }
6996     if (agents.empty() || infos.empty()) {
6997         return;
6998     }
6999     for (auto& agent : agents) {
7000         agent->OnScreenGroupChange(trigger, infos, groupEvent);
7001     }
7002 }
7003 
OnScreenConnect(const sptr<ScreenInfo> screenInfo)7004 void ScreenSessionManager::OnScreenConnect(const sptr<ScreenInfo> screenInfo)
7005 {
7006     if (screenInfo == nullptr) {
7007         TLOGE(WmsLogTag::DMS, "screenInfo nullptr");
7008         return;
7009     }
7010     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
7011     if (agents.empty()) {
7012         TLOGI(WmsLogTag::DMS, "agents empty");
7013         return;
7014     }
7015     TLOGI(WmsLogTag::DMS, "start");
7016     for (auto& agent : agents) {
7017         agent->OnScreenConnect(screenInfo);
7018     }
7019     NotifyScreenModeChange();
7020 }
7021 
OnScreenDisconnect(ScreenId screenId)7022 void ScreenSessionManager::OnScreenDisconnect(ScreenId screenId)
7023 {
7024     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
7025     if (agents.empty()) {
7026         TLOGI(WmsLogTag::DMS, "agents empty");
7027         return;
7028     }
7029     TLOGI(WmsLogTag::DMS, "start");
7030     for (auto& agent : agents) {
7031         agent->OnScreenDisconnect(screenId);
7032     }
7033     NotifyScreenModeChange(screenId);
7034 }
7035 
OnScreenshot(sptr<ScreenshotInfo> info)7036 void ScreenSessionManager::OnScreenshot(sptr<ScreenshotInfo> info)
7037 {
7038     if (info == nullptr) {
7039         TLOGE(WmsLogTag::DMS, "info is null");
7040         return;
7041     }
7042     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREENSHOT_EVENT_LISTENER);
7043     if (agents.empty()) {
7044         TLOGD(WmsLogTag::DMS, "agents empty");
7045         return;
7046     }
7047     TLOGI(WmsLogTag::DMS, "start");
7048     for (auto& agent : agents) {
7049         agent->OnScreenshot(info);
7050     }
7051 }
7052 
GetCutoutInfo(DisplayId displayId)7053 sptr<CutoutInfo> ScreenSessionManager::GetCutoutInfo(DisplayId displayId)
7054 {
7055     DmsXcollie dmsXcollie("DMS:GetCutoutInfo", XCOLLIE_TIMEOUT_10S);
7056     return screenCutoutController_ ? screenCutoutController_->GetScreenCutoutInfo(displayId) : nullptr;
7057 }
7058 
GetCutoutInfo(DisplayId displayId,int32_t width,int32_t height,Rotation rotation)7059 sptr<CutoutInfo> ScreenSessionManager::GetCutoutInfo(DisplayId displayId, int32_t width,
7060                                                     int32_t height, Rotation rotation)
7061 {
7062     DmsXcollie dmsXcollie("DMS:GetCutoutInfo", XCOLLIE_TIMEOUT_10S);
7063     return screenCutoutController_ ? screenCutoutController_->GetScreenCutoutInfo(displayId, width, height, rotation) :
7064             nullptr;
7065 }
7066 
HasImmersiveWindow(ScreenId screenId,bool & immersive)7067 DMError ScreenSessionManager::HasImmersiveWindow(ScreenId screenId, bool& immersive)
7068 {
7069     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7070         TLOGE(WmsLogTag::DMS, "permission denied!");
7071         return DMError::DM_ERROR_NOT_SYSTEM_APP;
7072     }
7073     auto clientProxy = GetClientProxy();
7074     if (!clientProxy) {
7075         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
7076         return DMError::DM_ERROR_NULLPTR;
7077     }
7078     clientProxy->OnImmersiveStateChanged(screenId, immersive);
7079     return DMError::DM_OK;
7080 }
7081 
TransferTypeToString(ScreenType type) const7082 std::string ScreenSessionManager::TransferTypeToString(ScreenType type) const
7083 {
7084     std::string screenType;
7085     switch (type) {
7086         case ScreenType::REAL:
7087             screenType = "REAL";
7088             break;
7089         case ScreenType::VIRTUAL:
7090             screenType = "VIRTUAL";
7091             break;
7092         default:
7093             screenType = "UNDEFINED";
7094             break;
7095     }
7096     return screenType;
7097 }
7098 
TransferPropertyChangeTypeToString(ScreenPropertyChangeType type) const7099 std::string ScreenSessionManager::TransferPropertyChangeTypeToString(ScreenPropertyChangeType type) const
7100 {
7101     std::string screenType;
7102     switch (type) {
7103         case ScreenPropertyChangeType::UNSPECIFIED:
7104             screenType = "UNSPECIFIED";
7105             break;
7106         case ScreenPropertyChangeType::ROTATION_BEGIN:
7107             screenType = "ROTATION_BEGIN";
7108             break;
7109         case ScreenPropertyChangeType::ROTATION_END:
7110             screenType = "ROTATION_END";
7111             break;
7112         case ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY:
7113             screenType = "ROTATION_UPDATE_PROPERTY_ONLY";
7114             break;
7115         case ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY:
7116             screenType = "ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY";
7117             break;
7118         default:
7119             screenType = "UNDEFINED";
7120             break;
7121     }
7122     return screenType;
7123 }
7124 
DumpAllScreensInfo(std::string & dumpInfo)7125 void ScreenSessionManager::DumpAllScreensInfo(std::string& dumpInfo)
7126 {
7127     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
7128         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
7129             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7130         return;
7131     }
7132     std::ostringstream oss;
7133     oss << "--------------------------------------Free Screen"
7134         << "--------------------------------------"
7135         << std::endl;
7136     oss << "ScreenName           Type     IsGroup DmsId RsId                 ActiveIdx VPR Rotation Orientation "
7137         << "RequestOrientation NodeId               "
7138         << std::endl;
7139     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
7140     for (auto sessionIt : screenSessionMap_) {
7141         auto screenSession = sessionIt.second;
7142         if (screenSession == nullptr) {
7143             continue;
7144         }
7145         sptr<ScreenInfo> screenInfo = screenSession->ConvertToScreenInfo();
7146         if (screenInfo == nullptr) {
7147             continue;
7148         }
7149         std::string screenType = TransferTypeToString(screenInfo->GetType());
7150         NodeId nodeId = (screenSession->GetDisplayNode() == nullptr) ?
7151             SCREEN_ID_INVALID : screenSession->GetDisplayNode()->GetId();
7152         oss << std::left << std::setw(21) << screenInfo->GetName()  // 21 is width
7153             << std::left << std::setw(9) << screenType  // 9 is width
7154             << std::left << std::setw(8) << (screenSession->isScreenGroup_ ? "true" : "false")  // 8 is width
7155             << std::left << std::setw(6) << screenSession->screenId_  // 6 is width
7156             << std::left << std::setw(21) << screenSession->rsId_  // 21 is width
7157             << std::left << std::setw(10) << screenSession->activeIdx_  // 10 is width
7158             << std::left << std::setw(4) << screenInfo->GetVirtualPixelRatio()  // 4 is width
7159             << std::left << std::setw(9) << static_cast<uint32_t>(screenInfo->GetRotation())  // 9 is width
7160             << std::left << std::setw(12) << static_cast<uint32_t>(screenInfo->GetOrientation())  // 12 is width
7161             << std::left << std::setw(19)  // 19 is width
7162                 << static_cast<uint32_t>(screenSession->GetScreenRequestedOrientation())
7163             << std::left << std::setw(21) << nodeId  // 21 is width
7164             << std::endl;
7165     }
7166     oss << "total screen num: " << screenSessionMap_.size() << std::endl;
7167     dumpInfo.append(oss.str());
7168 }
7169 
DumpSpecialScreenInfo(ScreenId id,std::string & dumpInfo)7170 void ScreenSessionManager::DumpSpecialScreenInfo(ScreenId id, std::string& dumpInfo)
7171 {
7172     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
7173         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
7174             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7175         return;
7176     }
7177     std::ostringstream oss;
7178     sptr<ScreenSession> session = GetScreenSession(id);
7179     if (!session) {
7180         TLOGE(WmsLogTag::DMS, "Get screen session failed.");
7181         oss << "This screen id is invalid.";
7182         dumpInfo.append(oss.str());
7183         return;
7184     }
7185     sptr<ScreenInfo> screenInfo = GetScreenInfoById(id);
7186     if (screenInfo == nullptr) {
7187         return;
7188     }
7189     std::string screenType = TransferTypeToString(screenInfo->GetType());
7190     NodeId nodeId = (session->GetDisplayNode() == nullptr) ?
7191         SCREEN_ID_INVALID : session->GetDisplayNode()->GetId();
7192     oss << "ScreenName: " << screenInfo->GetName() << std::endl;
7193     oss << "Type: " << screenType << std::endl;
7194     oss << "IsGroup: " << (session->isScreenGroup_ ? "true" : "false") << std::endl;
7195     oss << "DmsId: " << id << std::endl;
7196     oss << "RsId: " << session->rsId_ << std::endl;
7197     oss << "ActiveIdx: " << session->activeIdx_ << std::endl;
7198     oss << "VPR: " << screenInfo->GetVirtualPixelRatio() << std::endl;
7199     oss << "Rotation: " << static_cast<uint32_t>(screenInfo->GetRotation()) << std::endl;
7200     oss << "Orientation: " << static_cast<uint32_t>(screenInfo->GetOrientation()) << std::endl;
7201     oss << "RequestOrientation: " << static_cast<uint32_t>(session->GetScreenRequestedOrientation()) << std::endl;
7202     oss << "NodeId: " << nodeId << std::endl;
7203     dumpInfo.append(oss.str());
7204 }
7205 
7206 // --- Fold Screen ---
GetPhyScreenProperty(ScreenId screenId)7207 ScreenProperty ScreenSessionManager::GetPhyScreenProperty(ScreenId screenId)
7208 {
7209     std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
7210     ScreenProperty property;
7211     auto iter = phyScreenPropMap_.find(screenId);
7212     if (iter == phyScreenPropMap_.end()) {
7213         TLOGI(WmsLogTag::DMS, "Error found physic screen config with id: %{public}" PRIu64, screenId);
7214         return property;
7215     }
7216     return iter->second;
7217 }
7218 
UpdateCameraBackSelfie(bool isCameraBackSelfie)7219 void ScreenSessionManager::UpdateCameraBackSelfie(bool isCameraBackSelfie)
7220 {
7221     if (isCameraBackSelfie_ == isCameraBackSelfie) {
7222         return;
7223     }
7224     isCameraBackSelfie_ = isCameraBackSelfie;
7225 
7226     auto screenSession = GetDefaultScreenSession();
7227     if (!screenSession) {
7228         TLOGW(WmsLogTag::DMS, "screenSession is null, notify camera back selfie failed");
7229         return;
7230     }
7231     screenSession->HandleCameraBackSelfieChange(isCameraBackSelfie);
7232 
7233     if (isCameraBackSelfie) {
7234         TLOGI(WmsLogTag::DMS, "isBackSelfie, SetScreenCorrection MAIN to 270");
7235         rsInterface_.SetScreenCorrection(SCREEN_ID_MAIN, static_cast<ScreenRotation>(ROTATION_270));
7236     } else {
7237         TLOGI(WmsLogTag::DMS, "exit BackSelfie, SetScreenCorrection MAIN to 90");
7238         SetScreenCorrection();
7239     }
7240 }
7241 
SetFoldDisplayMode(const FoldDisplayMode displayMode)7242 void ScreenSessionManager::SetFoldDisplayMode(const FoldDisplayMode displayMode)
7243 {
7244     SetFoldDisplayModeInner(displayMode);
7245 }
7246 
SetFoldDisplayModeInner(const FoldDisplayMode displayMode,std::string reason)7247 DMError ScreenSessionManager::SetFoldDisplayModeInner(const FoldDisplayMode displayMode, std::string reason)
7248 {
7249 #ifdef FOLD_ABILITY_ENABLE
7250     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7251         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d, reason: %{public}s",
7252             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid(), reason.c_str());
7253         return DMError::DM_ERROR_NOT_SYSTEM_APP;
7254     }
7255     if (!g_foldScreenFlag) {
7256         return DMError::DM_ERROR_INVALID_MODE_ID;
7257     }
7258     if (foldScreenController_ == nullptr) {
7259         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
7260         return DMError::DM_ERROR_INVALID_MODE_ID;
7261     }
7262     if (!SessionPermission::IsSystemCalling()) {
7263         TLOGE(WmsLogTag::DMS, "permission denied!");
7264         return DMError::DM_ERROR_NOT_SYSTEM_APP;
7265     }
7266     TLOGI(WmsLogTag::DMS, "calling clientName: %{public}s, calling pid: %{public}d, setmode: %{public}d",
7267         SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid(), displayMode);
7268     if (foldScreenController_->GetTentMode() &&
7269         (displayMode == FoldDisplayMode::FULL || displayMode == FoldDisplayMode::COORDINATION)) {
7270         TLOGW(WmsLogTag::DMS, "in TentMode, SetFoldDisplayMode to %{public}d failed", displayMode);
7271         return DMError::DM_ERROR_INVALID_MODE_ID;
7272     } else if ((FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() ||
7273         FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) && IsScreenCasting() &&
7274         displayMode == FoldDisplayMode::COORDINATION) {
7275         TLOGW(WmsLogTag::DMS, "is phone casting, SetFoldDisplayMode to %{public}d is not allowed", displayMode);
7276         return DMError::DM_ERROR_INVALID_MODE_ID;
7277     }
7278     if (reason.compare("backSelfie") == 0) {
7279         UpdateCameraBackSelfie(true);
7280     }
7281     foldScreenController_->SetDisplayMode(displayMode);
7282     NotifyClientProxyUpdateFoldDisplayMode(displayMode);
7283 #endif
7284     return DMError::DM_OK;
7285 }
7286 
SetFoldDisplayModeFromJs(const FoldDisplayMode displayMode,std::string reason)7287 DMError ScreenSessionManager::SetFoldDisplayModeFromJs(const FoldDisplayMode displayMode, std::string reason)
7288 {
7289     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7290         TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
7291             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7292         return DMError::DM_ERROR_NOT_SYSTEM_APP;
7293     }
7294     return SetFoldDisplayModeInner(displayMode, reason);
7295 }
7296 
UpdateDisplayScaleState(ScreenId screenId)7297 void ScreenSessionManager::UpdateDisplayScaleState(ScreenId screenId)
7298 {
7299     auto session = GetScreenSession(screenId);
7300     if (session == nullptr) {
7301         TLOGE(WmsLogTag::DMS, "session is null");
7302         return;
7303     }
7304     const ScreenProperty& property = session->GetScreenProperty();
7305     if (std::fabs(property.GetScaleX() - DEFAULT_SCALE) < FLT_EPSILON &&
7306         std::fabs(property.GetScaleY() - DEFAULT_SCALE) < FLT_EPSILON &&
7307         std::fabs(property.GetPivotX() - DEFAULT_PIVOT) < FLT_EPSILON &&
7308         std::fabs(property.GetPivotY() - DEFAULT_PIVOT) < FLT_EPSILON) {
7309         TLOGD(WmsLogTag::DMS, "The scale and pivot is default value now. There is no need to update");
7310         return;
7311     }
7312     SetDisplayScaleInner(screenId, property.GetScaleX(), property.GetScaleY(), property.GetPivotX(),
7313                          property.GetPivotY());
7314 }
7315 
SetDisplayScaleInner(ScreenId screenId,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY)7316 void ScreenSessionManager::SetDisplayScaleInner(ScreenId screenId, const float& scaleX, const float& scaleY,
7317                                                 const float& pivotX, const float& pivotY)
7318 {
7319     auto session = GetScreenSession(screenId);
7320     if (session == nullptr) {
7321         TLOGE(WmsLogTag::DMS, "session is null");
7322         return;
7323     }
7324     if (pivotX > 1.0f || pivotX < 0.0f || pivotY > 1.0f || pivotY < 0.0f) {
7325         TLOGE(WmsLogTag::DMS, "pivotX [%{public}f] and pivotY [%{public}f] should be in [0.0~1.0f]", pivotX, pivotY);
7326         return;
7327     }
7328     float translateX = 0.0f;
7329     float translateY = 0.0f;
7330     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7331         CalcDisplayNodeTranslateOnPocketFoldRotation(session, scaleX, scaleY, pivotX, pivotY,
7332             translateX, translateY);
7333     } else if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
7334         if (FoldDisplayMode::MAIN == GetFoldDisplayMode()) {
7335             CalcDisplayNodeTranslateOnPocketFoldRotation(session, scaleX, scaleY, pivotX, pivotY,
7336                 translateX, translateY);
7337         } else {
7338             CalcDisplayNodeTranslateOnRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
7339         }
7340     } else if (ROTATE_POLICY == FOLDABLE_DEVICE && FoldDisplayMode::FULL == GetFoldDisplayMode()) {
7341         CalcDisplayNodeTranslateOnFoldableRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
7342     } else if (SCREEN_SCAN_TYPE == SCAN_TYPE_VERTICAL) {
7343         CalcDisplayNodeTranslateOnVerticalScanRotation(session, ScaleProperty(scaleX, scaleY, pivotX, pivotY),
7344                                                        translateX, translateY);
7345     } else {
7346         CalcDisplayNodeTranslateOnRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
7347     }
7348     TLOGW(WmsLogTag::DMS,
7349           "screenId %{public}" PRIu64 ", scale [%{public}f, %{public}f], "
7350           "pivot [%{public}f, %{public}f], translate [%{public}f, %{public}f]",
7351           screenId, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
7352     session->SetScreenScale(scaleX, scaleY, pivotX, pivotY, translateX, translateY);
7353     NotifyDisplayStateChange(GetDefaultScreenId(), session->ConvertToDisplayInfo(), {},
7354                              DisplayStateChangeType::UPDATE_SCALE);
7355 }
7356 
CalcDisplayNodeTranslateOnFoldableRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)7357 void ScreenSessionManager::CalcDisplayNodeTranslateOnFoldableRotation(sptr<ScreenSession>& session, const float& scaleX,
7358                                                                       const float& scaleY, const float& pivotX,
7359                                                                       const float& pivotY, float& translateX,
7360                                                                       float& translateY)
7361 {
7362     if (session == nullptr) {
7363         TLOGE(WmsLogTag::DMS, "session is nullptr");
7364         return;
7365     }
7366     const ScreenProperty& screenProperty = session->GetScreenProperty();
7367     auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
7368     auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
7369     Rotation rotation = session->GetRotation();
7370     float rotatedPivotX = DEFAULT_PIVOT;
7371     float rotatedPivotY = DEFAULT_PIVOT;
7372     float width = 0.0f;
7373     float height = 0.0f;
7374     switch (rotation) {
7375         case Rotation::ROTATION_0:
7376             rotatedPivotX = pivotY;
7377             rotatedPivotY = 1.0f - pivotX;
7378             width = screenHeight;
7379             height = screenWidth;
7380             break;
7381         case Rotation::ROTATION_90:
7382             rotatedPivotX = 1.0f - pivotX;
7383             rotatedPivotY = 1.0f - pivotY;
7384             width = screenWidth;
7385             height = screenHeight;
7386             break;
7387         case Rotation::ROTATION_180:
7388             rotatedPivotX = 1.0f - pivotY;
7389             rotatedPivotY = pivotX;
7390             width = screenHeight;
7391             height = screenWidth;
7392             break;
7393         case Rotation::ROTATION_270:
7394             rotatedPivotX = pivotX;
7395             rotatedPivotY = pivotY;
7396             width = screenWidth;
7397             height = screenHeight;
7398             break;
7399         default:
7400             TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
7401             break;
7402     }
7403     translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
7404     translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
7405 }
7406 
CalcDisplayNodeTranslateOnPocketFoldRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)7407 void ScreenSessionManager::CalcDisplayNodeTranslateOnPocketFoldRotation(sptr<ScreenSession>& session,
7408                                                                         const float& scaleX, const float& scaleY,
7409                                                                         const float& pivotX, const float& pivotY,
7410                                                                         float& translateX, float& translateY)
7411 {
7412     if (session == nullptr) {
7413         TLOGE(WmsLogTag::DMS, "session is nullptr");
7414         return;
7415     }
7416     const ScreenProperty& screenProperty = session->GetScreenProperty();
7417     auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
7418     auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
7419     Rotation rotation = session->GetRotation();
7420     float rotatedPivotX = DEFAULT_PIVOT;
7421     float rotatedPivotY = DEFAULT_PIVOT;
7422     float width = 0.0f;
7423     float height = 0.0f;
7424     switch (rotation) {
7425         case Rotation::ROTATION_0:
7426             rotatedPivotX = 1.0f - pivotY;
7427             rotatedPivotY = pivotX;
7428             width = screenHeight;
7429             height = screenWidth;
7430             break;
7431         case Rotation::ROTATION_90:
7432             rotatedPivotX = pivotX;
7433             rotatedPivotY = pivotY;
7434             width = screenWidth;
7435             height = screenHeight;
7436             break;
7437         case Rotation::ROTATION_180:
7438             rotatedPivotX = pivotY;
7439             rotatedPivotY = 1.0f - pivotX;
7440             width = screenHeight;
7441             height = screenWidth;
7442             break;
7443         case Rotation::ROTATION_270:
7444             rotatedPivotX = 1.0f - pivotX;
7445             rotatedPivotY = 1.0f - pivotY;
7446             width = screenWidth;
7447             height = screenHeight;
7448             break;
7449         default:
7450             TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
7451             break;
7452     }
7453     translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
7454     translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
7455 }
7456 
CalcDisplayNodeTranslateOnVerticalScanRotation(const sptr<ScreenSession> & session,const ScaleProperty & scalep,float & translateX,float & translateY)7457 void ScreenSessionManager::CalcDisplayNodeTranslateOnVerticalScanRotation(const sptr<ScreenSession>& session,
7458                                                                           const ScaleProperty& scalep,
7459                                                                           float& translateX, float& translateY)
7460 {
7461     if (session == nullptr) {
7462         TLOGE(WmsLogTag::DMS, "session is nullptr");
7463         return;
7464     }
7465     auto screenProperty = session->GetScreenProperty();
7466     auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
7467     auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
7468     Rotation rotation = session->GetRotation();
7469     float rotatedPivotX = DEFAULT_PIVOT;
7470     float rotatedPivotY = DEFAULT_PIVOT;
7471     float width = 0.0f;
7472     float height = 0.0f;
7473     switch (rotation) {
7474         case Rotation::ROTATION_90:
7475             rotatedPivotX = scalep.pivotX;
7476             rotatedPivotY = scalep.pivotY;
7477             width = screenWidth;
7478             height = screenHeight;
7479             break;
7480         case Rotation::ROTATION_180:
7481             rotatedPivotX = scalep.pivotY;
7482             rotatedPivotY = 1.0f - scalep.pivotX;
7483             width = screenHeight;
7484             height = screenWidth;
7485             break;
7486         case Rotation::ROTATION_270:
7487             rotatedPivotX = 1.0f - scalep.pivotX;
7488             rotatedPivotY = 1.0f - scalep.pivotY;
7489             width = screenWidth;
7490             height = screenHeight;
7491             break;
7492         case Rotation::ROTATION_0:
7493             rotatedPivotX = 1.0f - scalep.pivotY;
7494             rotatedPivotY = scalep.pivotX;
7495             width = screenHeight;
7496             height = screenWidth;
7497             break;
7498         default:
7499             TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
7500             break;
7501     }
7502     translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scalep.scaleX - DEFAULT_SCALE) * width;
7503     translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scalep.scaleY - DEFAULT_SCALE) * height;
7504 }
7505 
CalcDisplayNodeTranslateOnRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)7506 void ScreenSessionManager::CalcDisplayNodeTranslateOnRotation(sptr<ScreenSession>& session, const float& scaleX,
7507                                                               const float& scaleY, const float& pivotX,
7508                                                               const float& pivotY, float& translateX, float& translateY)
7509 {
7510     if (session == nullptr) {
7511         TLOGE(WmsLogTag::DMS, "session is nullptr");
7512         return;
7513     }
7514     const ScreenProperty& screenProperty = session->GetScreenProperty();
7515     auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
7516     auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
7517     Rotation rotation = session->GetRotation();
7518     float rotatedPivotX = DEFAULT_PIVOT;
7519     float rotatedPivotY = DEFAULT_PIVOT;
7520     float width = 0.0f;
7521     float height = 0.0f;
7522     switch (rotation) {
7523         case Rotation::ROTATION_0:
7524             rotatedPivotX = pivotX;
7525             rotatedPivotY = pivotY;
7526             width = screenWidth;
7527             height = screenHeight;
7528             break;
7529         case Rotation::ROTATION_90:
7530             rotatedPivotX = pivotY;
7531             rotatedPivotY = 1.0f - pivotX;
7532             width = screenHeight;
7533             height = screenWidth;
7534             break;
7535         case Rotation::ROTATION_180:
7536             rotatedPivotX = 1.0f - pivotX;
7537             rotatedPivotY = 1.0f - pivotY;
7538             width = screenWidth;
7539             height = screenHeight;
7540             break;
7541         case Rotation::ROTATION_270:
7542             rotatedPivotX = 1.0f - pivotY;
7543             rotatedPivotY = pivotX;
7544             width = screenHeight;
7545             height = screenWidth;
7546             break;
7547         default:
7548             TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
7549             break;
7550     }
7551     translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
7552     translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
7553 }
7554 
SetDisplayScale(ScreenId screenId,float scaleX,float scaleY,float pivotX,float pivotY)7555 void ScreenSessionManager::SetDisplayScale(ScreenId screenId, float scaleX, float scaleY, float pivotX,
7556     float pivotY)
7557 {
7558     if (!SessionPermission::IsSACalling()) {
7559         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
7560             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7561         return;
7562     }
7563     SetDisplayScaleInner(screenId, scaleX, scaleY, pivotX, pivotY);
7564 }
7565 
SetFoldStatusLocked(bool locked)7566 void ScreenSessionManager::SetFoldStatusLocked(bool locked)
7567 {
7568 #ifdef FOLD_ABILITY_ENABLE
7569     HandleSuperFoldStatusLocked(locked);
7570     if (!g_foldScreenFlag) {
7571         return;
7572     }
7573     if (foldScreenController_ == nullptr) {
7574         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
7575         return;
7576     }
7577     if (!SessionPermission::IsSystemCalling()) {
7578         TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
7579             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7580         return;
7581     }
7582     foldScreenController_->LockDisplayStatus(locked);
7583 #endif
7584 }
7585 
SetFoldStatusLockedFromJs(bool locked)7586 DMError ScreenSessionManager::SetFoldStatusLockedFromJs(bool locked)
7587 {
7588     if (!SessionPermission::IsSystemCalling()) {
7589         TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
7590             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7591         return DMError::DM_ERROR_NOT_SYSTEM_APP;
7592     }
7593     SetFoldStatusLocked(locked);
7594     return DMError::DM_OK;
7595 }
7596 
GetFoldDisplayMode()7597 FoldDisplayMode ScreenSessionManager::GetFoldDisplayMode()
7598 {
7599 #ifdef FOLD_ABILITY_ENABLE
7600     DmsXcollie dmsXcollie("DMS:GetFoldDisplayMode", XCOLLIE_TIMEOUT_10S);
7601     if (!g_foldScreenFlag) {
7602         return FoldDisplayMode::UNKNOWN;
7603     }
7604     if (foldScreenController_ == nullptr) {
7605         TLOGD(WmsLogTag::DMS, "foldScreenController_ is null");
7606         return FoldDisplayMode::UNKNOWN;
7607     }
7608     if (IsSpecialApp()) {
7609         return FoldDisplayMode::MAIN;
7610     }
7611     return foldScreenController_->GetDisplayMode();
7612 #else
7613     return FoldDisplayMode::UNKNOWN;
7614 #endif
7615 }
7616 
IsFoldable()7617 bool ScreenSessionManager::IsFoldable()
7618 {
7619 #ifdef FOLD_ABILITY_ENABLE
7620     // Most applications do not adapt to Lem rotation and are temporarily treated as non fold device
7621     if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
7622         return false;
7623     }
7624 
7625     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7626         return true;
7627     }
7628 
7629     if (!g_foldScreenFlag) {
7630         return false;
7631     }
7632     if (foldScreenController_ == nullptr) {
7633         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
7634         return false;
7635     }
7636     if (IsSpecialApp()) {
7637         return false;
7638     }
7639     return foldScreenController_->IsFoldable();
7640 #else
7641     return false;
7642 #endif
7643 }
7644 
IsCaptured()7645 bool ScreenSessionManager::IsCaptured()
7646 {
7647     if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none") {
7648         // 如果当前是PC拓展模式,非截屏,录屏,投屏,则返回false
7649         return isScreenShot_ || virtualScreenCount_ > 0 || (hdmiScreenCount_ > 0 && !IsExtendMode());
7650     } else {
7651         return isScreenShot_ || virtualScreenCount_ > 0 || hdmiScreenCount_ > 0;
7652     }
7653 }
7654 
IsMultiScreenCollaboration()7655 bool ScreenSessionManager::IsMultiScreenCollaboration()
7656 {
7657     return isMultiScreenCollaboration_;
7658 }
7659 
HasCastEngineOrPhyMirror(const std::vector<ScreenId> & screenIdsToExclude)7660 bool ScreenSessionManager::HasCastEngineOrPhyMirror(const std::vector<ScreenId>& screenIdsToExclude)
7661 {
7662     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
7663     for (auto sessionItem : screenSessionMap_) {
7664         auto screenId = sessionItem.first;
7665         auto screenSession = sessionItem.second;
7666         if (screenSession == nullptr) {
7667             TLOGI(WmsLogTag::DMS, "screenSession is null");
7668             continue;
7669         }
7670         if (std::find(screenIdsToExclude.begin(), screenIdsToExclude.end(), screenId) != screenIdsToExclude.end()) {
7671             continue;
7672         }
7673         auto screenType = screenSession->GetScreenProperty().GetScreenType();
7674         if (screenType == ScreenType::VIRTUAL
7675             && screenSession->GetName() == SCREEN_NAME_CAST) {
7676             return true;
7677         }
7678 
7679         if (IsDefaultMirrorMode(screenId) && screenType == ScreenType::REAL &&
7680             screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
7681             return true;
7682         }
7683     }
7684     return false;
7685 }
7686 
GetFoldStatus()7687 FoldStatus ScreenSessionManager::GetFoldStatus()
7688 {
7689 #ifdef FOLD_ABILITY_ENABLE
7690     DmsXcollie dmsXcollie("DMS:GetFoldStatus", XCOLLIE_TIMEOUT_10S);
7691     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7692         SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
7693         return SuperFoldStateManager::GetInstance().MatchSuperFoldStatusToFoldStatus(status);
7694     }
7695     if (!g_foldScreenFlag) {
7696         return FoldStatus::UNKNOWN;
7697     }
7698     if (foldScreenController_ == nullptr) {
7699         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
7700         return FoldStatus::UNKNOWN;
7701     }
7702     if (IsSpecialApp()) {
7703         return FoldStatus::UNKNOWN;
7704     }
7705     return foldScreenController_->GetFoldStatus();
7706 #else
7707     return FoldStatus::UNKNOWN;
7708 #endif
7709 }
7710 
GetSuperFoldStatus()7711 SuperFoldStatus ScreenSessionManager::GetSuperFoldStatus()
7712 {
7713 #ifdef FOLD_ABILITY_ENABLE
7714     DmsXcollie dmsXcollie("DMS:GetSuperFoldStatus", XCOLLIE_TIMEOUT_10S);
7715     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7716         return SuperFoldStatus::UNKNOWN;
7717     }
7718     SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
7719     return status;
7720 #else
7721     return SuperFoldStatus::UNKNOWN;
7722 #endif
7723 }
7724 
GetSuperRotation()7725 float ScreenSessionManager::GetSuperRotation()
7726 {
7727     DmsXcollie dmsXcollie("DMS:GetSuperRotation", XCOLLIE_TIMEOUT_10S);
7728     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7729         return -1.f;
7730     }
7731     {
7732         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
7733         for (auto sessionIt : screenSessionMap_) {
7734             auto screenSession = sessionIt.second;
7735             if (screenSession == nullptr) {
7736                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
7737                 continue;
7738             }
7739             if (screenSession->GetIsInternal()) {
7740                 float rotation = static_cast<int>(screenSession->GetRotation()) * 90.f;
7741                 TLOGI(WmsLogTag::DMS, "is internal, screenId = %{public}" PRIu64 ", rotation = %{public}f",
7742                     sessionIt.first, rotation);
7743                 return rotation;
7744             } else {
7745                 TLOGI(WmsLogTag::DMS, "not internal, screenId = %{public}" PRIu64"", sessionIt.first);
7746             }
7747         }
7748     }
7749     TLOGE(WmsLogTag::DMS, "all screenSession is nullptr or not internal");
7750     return -1.f;
7751 }
7752 
GetIsLandscapeLockStatus()7753 bool ScreenSessionManager::GetIsLandscapeLockStatus()
7754 {
7755     return isLandscapeLockStatus_;
7756 }
7757 
SetIsLandscapeLockStatus(bool isLandscapeLockStatus)7758 void ScreenSessionManager::SetIsLandscapeLockStatus(bool isLandscapeLockStatus)
7759 {
7760     isLandscapeLockStatus_ = isLandscapeLockStatus;
7761 }
7762 
SetLandscapeLockStatus(bool isLocked)7763 void ScreenSessionManager::SetLandscapeLockStatus(bool isLocked)
7764 {
7765 #ifdef FOLD_ABILITY_ENABLE
7766     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7767         TLOGE(WmsLogTag::DMS, "permission denied! pid: %{public}d", IPCSkeleton::GetCallingPid());
7768         return;
7769     }
7770     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7771         TLOGI(WmsLogTag::DMS, "not super fold display device.");
7772         return;
7773     }
7774     if (isLocked) {
7775         SetIsLandscapeLockStatus(true);
7776         SuperFoldSensorManager::GetInstance().HandleScreenConnectChange();
7777     } else {
7778         SetIsLandscapeLockStatus(false);
7779         SuperFoldSensorManager::GetInstance().HandleScreenDisconnectChange();
7780     }
7781 #endif
7782 }
7783 
GetExtendScreenConnectStatus()7784 ExtendScreenConnectStatus ScreenSessionManager::GetExtendScreenConnectStatus()
7785 {
7786 #ifdef WM_MULTI_SCREEN_ENABLE
7787     DmsXcollie dmsXcollie("DMS:GetExtendScreenConnectStatus", XCOLLIE_TIMEOUT_10S);
7788     return extendScreenConnectStatus_.load();
7789 #else
7790     return ExtendScreenConnectStatus::UNKNOWN;
7791 #endif
7792 }
7793 
GetIsExtendScreenConnected()7794 bool ScreenSessionManager::GetIsExtendScreenConnected()
7795 {
7796     return isExtendScreenConnected_;
7797 }
7798 
SetIsExtendScreenConnected(bool isExtendScreenConnected)7799 void ScreenSessionManager::SetIsExtendScreenConnected(bool isExtendScreenConnected)
7800 {
7801     isExtendScreenConnected_ = isExtendScreenConnected;
7802 }
7803 
HandleExtendScreenConnect(ScreenId screenId)7804 void ScreenSessionManager::HandleExtendScreenConnect(ScreenId screenId)
7805 {
7806 #ifdef FOLD_ABILITY_ENABLE
7807     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7808         TLOGI(WmsLogTag::DMS, "not super fold display device.");
7809         return;
7810     }
7811     SetIsExtendScreenConnected(true);
7812     extendScreenConnectStatus_.store(ExtendScreenConnectStatus::CONNECT);
7813     OnExtendScreenConnectStatusChange(screenId, ExtendScreenConnectStatus::CONNECT);
7814 #endif
7815 }
7816 
HandleExtendScreenDisconnect(ScreenId screenId)7817 void ScreenSessionManager::HandleExtendScreenDisconnect(ScreenId screenId)
7818 {
7819 #ifdef FOLD_ABILITY_ENABLE
7820     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7821         TLOGI(WmsLogTag::DMS, "not super fold display device.");
7822         return;
7823     }
7824     SetIsExtendScreenConnected(false);
7825     SuperFoldSensorManager::GetInstance().HandleScreenDisconnectChange();
7826     OnExtendScreenConnectStatusChange(screenId, ExtendScreenConnectStatus::DISCONNECT);
7827     extendScreenConnectStatus_.store(ExtendScreenConnectStatus::DISCONNECT);
7828 #endif
7829 }
7830 
GetIsFoldStatusLocked()7831 bool ScreenSessionManager::GetIsFoldStatusLocked()
7832 {
7833     return isFoldStatusLocked_;
7834 }
7835 
SetIsFoldStatusLocked(bool isFoldStatusLocked)7836 void ScreenSessionManager::SetIsFoldStatusLocked(bool isFoldStatusLocked)
7837 {
7838     isFoldStatusLocked_ = isFoldStatusLocked;
7839 }
7840 
SetFoldStatusExpandAndLocked(bool isLocked)7841 void ScreenSessionManager::SetFoldStatusExpandAndLocked(bool isLocked)
7842 {
7843     if (!SessionPermission::IsSystemCalling()) {
7844         TLOGE(WmsLogTag::DMS, "permission denied!");
7845         return;
7846     }
7847 #ifdef FOLD_ABILITY_ENABLE
7848     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7849         TLOGI(WmsLogTag::DMS, "not super fold display device.");
7850         return;
7851     }
7852     SetIsFoldStatusLocked(isLocked);
7853     if (isLocked == true) {
7854         SuperFoldSensorManager::GetInstance().HandleFoldStatusLockedToExpand();
7855     } else {
7856         SuperFoldSensorManager::GetInstance().HandleFoldStatusUnlocked();
7857     }
7858 #endif
7859 }
7860 
HandleSuperFoldStatusLocked(bool isLocked)7861 void ScreenSessionManager::HandleSuperFoldStatusLocked(bool isLocked)
7862 {
7863 #ifdef FOLD_ABILITY_ENABLE
7864     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7865         TLOGI(WmsLogTag::DMS, "not super fold display device.");
7866         return;
7867     }
7868     SetIsFoldStatusLocked(isLocked);
7869     if (isLocked == true) {
7870         TLOGI(WmsLogTag::DMS, "Fold status is locked.");
7871     } else {
7872         SuperFoldSensorManager::GetInstance().HandleFoldStatusUnlocked();
7873     }
7874 #endif
7875 }
7876 
GetIsOuterOnlyMode()7877 bool ScreenSessionManager::GetIsOuterOnlyMode()
7878 {
7879     return isOuterOnlyMode_;
7880 }
7881 
SetIsOuterOnlyMode(bool isOuterOnlyMode)7882 void ScreenSessionManager::SetIsOuterOnlyMode(bool isOuterOnlyMode)
7883 {
7884     isOuterOnlyMode_ = isOuterOnlyMode;
7885 }
7886 
GetIsOuterOnlyModeBeforePowerOff()7887 bool ScreenSessionManager::GetIsOuterOnlyModeBeforePowerOff()
7888 {
7889     return isOuterOnlyModeBeforePowerOff_;
7890 }
7891 
SetIsOuterOnlyModeBeforePowerOff(bool isOuterOnlyModeBeforePowerOff)7892 void ScreenSessionManager::SetIsOuterOnlyModeBeforePowerOff(bool isOuterOnlyModeBeforePowerOff)
7893 {
7894     isOuterOnlyModeBeforePowerOff_ = isOuterOnlyModeBeforePowerOff;
7895 }
7896 
GetTentMode()7897 bool ScreenSessionManager::GetTentMode()
7898 {
7899 #ifdef FOLD_ABILITY_ENABLE
7900     if (!g_foldScreenFlag) {
7901         return false;
7902     }
7903     if (foldScreenController_ == nullptr) {
7904         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
7905         return false;
7906     }
7907     return foldScreenController_->GetTentMode();
7908 #else
7909     return false;
7910 #endif
7911 }
7912 
GetCurrentFoldCreaseRegion()7913 sptr<FoldCreaseRegion> ScreenSessionManager::GetCurrentFoldCreaseRegion()
7914 {
7915 #ifdef FOLD_ABILITY_ENABLE
7916     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7917         return SuperFoldStateManager::GetInstance().GetCurrentFoldCreaseRegion();
7918     }
7919     if (!g_foldScreenFlag) {
7920         return nullptr;
7921     }
7922     if (foldScreenController_ == nullptr) {
7923         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
7924         return nullptr;
7925     }
7926     return foldScreenController_->GetCurrentFoldCreaseRegion();
7927 #else
7928     return nullptr;
7929 #endif
7930 }
7931 
GetLiveCreaseRegion(FoldCreaseRegion & region)7932 DMError ScreenSessionManager::GetLiveCreaseRegion(FoldCreaseRegion& region)
7933 {
7934 #ifdef FOLD_ABILITY_ENABLE
7935     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7936         region = SuperFoldStateManager::GetInstance().GetLiveCreaseRegion();
7937         return DMError::DM_OK;
7938     }
7939     if (!g_foldScreenFlag) {
7940         region = FoldCreaseRegion(0, {});
7941         return DMError::DM_OK;
7942     }
7943     if (foldScreenController_ == nullptr) {
7944         TLOGE(WmsLogTag::DMS, "foldScreenController_ is null");
7945         return DMError::DM_ERROR_INVALID_MODE_ID;
7946     }
7947     region = foldScreenController_->GetLiveCreaseRegion();
7948     return DMError::DM_OK;
7949 #else
7950     region = FoldCreaseRegion(0, {});
7951     return DMError::DM_OK;
7952 #endif
7953 }
7954 
GetCurvedCompressionArea()7955 uint32_t ScreenSessionManager::GetCurvedCompressionArea()
7956 {
7957     return ScreenSceneConfig::GetCurvedCompressionAreaInLandscape();
7958 }
7959 
NotifyFoldStatusChanged(FoldStatus foldStatus)7960 void ScreenSessionManager::NotifyFoldStatusChanged(FoldStatus foldStatus)
7961 {
7962 #ifdef FOLD_ABILITY_ENABLE
7963     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
7964     if (screenSession != nullptr) {
7965         if (foldStatus == FoldStatus::FOLDED && !FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7966             screenSession->SetDefaultDeviceRotationOffset(0);
7967         } else {
7968             screenSession->SetDefaultDeviceRotationOffset(defaultDeviceRotationOffset_);
7969         }
7970     }
7971     if (screenSession != nullptr && FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
7972         // 维护外屏独立dpi
7973         if (foldStatus == FoldStatus::FOLDED) {
7974             // sub screen default rotation offset is 270
7975             screenSession->SetDefaultDeviceRotationOffset(270);
7976             auto property = screenSession->GetScreenProperty();
7977             densityDpi_ = property.GetDensity();
7978             SetVirtualPixelRatio(GetDefaultScreenId(), subDensityDpi_);
7979         } else {
7980             SetVirtualPixelRatio(GetDefaultScreenId(), densityDpi_);
7981         }
7982     }
7983     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER);
7984     TLOGI(WmsLogTag::DMS, "foldStatus:%{public}d, agent size: %{public}u",
7985         foldStatus, static_cast<uint32_t>(agents.size()));
7986     if (agents.empty()) {
7987         return;
7988     }
7989     for (auto& agent : agents) {
7990         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
7991         if (!IsFreezed(agentPid, DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER)) {
7992             agent->NotifyFoldStatusChanged(foldStatus);
7993         }
7994     }
7995     if (lowTemp_ == LowTempMode::LOW_TEMP_ON) {
7996         ScreenSessionPublish::GetInstance().PublishSmartNotificationEvent(FAULT_DESCRIPTION, FAULT_SUGGESTION);
7997     }
7998 #endif
7999 }
8000 
SetLowTemp(LowTempMode lowTemp)8001 void ScreenSessionManager::SetLowTemp(LowTempMode lowTemp)
8002 {
8003     std::lock_guard<std::mutex> lock(lowTempMutex_);
8004     if (lowTemp == LowTempMode::LOW_TEMP_ON && lowTemp_ != lowTemp) {
8005         TLOGI(WmsLogTag::DMS, "device enter low temperature mode.");
8006         ScreenSessionPublish::GetInstance().PublishSmartNotificationEvent(FAULT_DESCRIPTION, FAULT_SUGGESTION);
8007     }
8008     if (lowTemp == LowTempMode::LOW_TEMP_OFF) {
8009         TLOGI(WmsLogTag::DMS, "device exit low temperature mode.");
8010     }
8011     lowTemp_ = lowTemp;
8012 }
8013 
NotifyFoldAngleChanged(std::vector<float> foldAngles)8014 void ScreenSessionManager::NotifyFoldAngleChanged(std::vector<float> foldAngles)
8015 {
8016     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER);
8017     if (agents.empty()) {
8018         TLOGI(WmsLogTag::DMS, "agents is empty");
8019         return;
8020     }
8021     {
8022         std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
8023         lastFoldAngles_ = foldAngles;
8024     }
8025     for (auto& agent : agents) {
8026         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8027         if (!IsFreezed(agentPid, DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER)) {
8028             agent->NotifyFoldAngleChanged(foldAngles);
8029         }
8030     }
8031 }
8032 
NotifyCaptureStatusChanged()8033 void ScreenSessionManager::NotifyCaptureStatusChanged()
8034 {
8035     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER);
8036     bool isCapture = IsCaptured();
8037     isScreenShot_ = false;
8038     if (agents.empty()) {
8039         return;
8040     }
8041     for (auto& agent : agents) {
8042         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8043         if (!IsFreezed(agentPid, DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER)) {
8044             agent->NotifyCaptureStatusChanged(isCapture);
8045         }
8046     }
8047 }
8048 
NotifyCaptureStatusChanged(bool isCapture)8049 void ScreenSessionManager::NotifyCaptureStatusChanged(bool isCapture)
8050 {
8051     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER);
8052     if (agents.empty()) {
8053         return;
8054     }
8055     for (auto& agent : agents) {
8056         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8057         if (!IsFreezed(agentPid, DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER)) {
8058             agent->NotifyCaptureStatusChanged(isCapture);
8059         }
8060     }
8061 }
8062 
NotifyDisplayChangeInfoChanged(const sptr<DisplayChangeInfo> & info)8063 void ScreenSessionManager::NotifyDisplayChangeInfoChanged(const sptr<DisplayChangeInfo>& info)
8064 {
8065     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER);
8066     if (agents.empty()) {
8067         return;
8068     }
8069     {
8070         std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
8071         lastDisplayChangeInfo_ = info;
8072     }
8073     for (auto& agent : agents) {
8074         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8075         if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER)) {
8076             agent->NotifyDisplayChangeInfoChanged(info);
8077         }
8078     }
8079 }
8080 
RefreshMirrorScreenRegion(ScreenId screenId)8081 void ScreenSessionManager::RefreshMirrorScreenRegion(ScreenId screenId)
8082 {
8083 #if defined(FOLD_ABILITY_ENABLE) && defined(WM_MULTI_SCREEN_ENABLE)
8084     auto screenSession = GetScreenSession(screenId);
8085     if (screenSession == nullptr) {
8086         TLOGE(WmsLogTag::DMS, "can not get screen session");
8087         return;
8088     }
8089     DMRect mainScreenRegion = {0, 0, 0, 0};
8090     foldScreenController_->SetMainScreenRegion(mainScreenRegion);
8091     ScreenId rsScreenId = SCREEN_ID_INVALID;
8092     if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
8093         TLOGE(WmsLogTag::DMS, "Screen: %{public}" PRIu64" convert to rs id failed", screenId);
8094     } else {
8095         screenSession->SetMirrorScreenRegion(rsScreenId, mainScreenRegion);
8096         screenSession->EnableMirrorScreenRegion();
8097     }
8098 #endif
8099 }
8100 
NotifyDisplayModeChanged(FoldDisplayMode displayMode)8101 void ScreenSessionManager::NotifyDisplayModeChanged(FoldDisplayMode displayMode)
8102 {
8103     NotifyClientProxyUpdateFoldDisplayMode(displayMode);
8104     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER);
8105     TLOGI(WmsLogTag::DMS, "DisplayMode:%{public}d, agent size: %{public}u",
8106         displayMode, static_cast<uint32_t>(agents.size()));
8107     if (agents.empty()) {
8108         return;
8109     }
8110     for (auto& agent : agents) {
8111         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8112         if (!IsFreezed(agentPid,
8113             DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER)) {
8114             agent->NotifyDisplayModeChanged(displayMode);
8115         }
8116     }
8117 #ifdef FOLD_ABILITY_ENABLE
8118     if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
8119         auto screenIds = GetAllScreenIds();
8120         for (auto screenId : screenIds) {
8121             RefreshMirrorScreenRegion(screenId);
8122         }
8123     }
8124 #endif
8125 }
8126 
NotifyScreenMagneticStateChanged(bool isMagneticState)8127 void ScreenSessionManager::NotifyScreenMagneticStateChanged(bool isMagneticState)
8128 {
8129     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_MAGNETIC_STATE_CHANGED_LISTENER);
8130     TLOGI(WmsLogTag::DMS, "IsScreenMagneticState:%{public}u, agent size: %{public}u",
8131         static_cast<uint32_t>(isMagneticState), static_cast<uint32_t>(agents.size()));
8132     if (agents.empty()) {
8133         return;
8134     }
8135     for (auto& agent : agents) {
8136         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8137         if (!IsFreezed(agentPid,
8138             DisplayManagerAgentType::SCREEN_MAGNETIC_STATE_CHANGED_LISTENER)) {
8139             agent->NotifyScreenMagneticStateChanged(isMagneticState);
8140         }
8141     }
8142 }
8143 
SetDisplayNodeScreenId(ScreenId screenId,ScreenId displayNodeScreenId)8144 void ScreenSessionManager::SetDisplayNodeScreenId(ScreenId screenId, ScreenId displayNodeScreenId)
8145 {
8146     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " displayNodeScreenId: %{public}" PRIu64,
8147         screenId, displayNodeScreenId);
8148     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetDisplayNodeScreenId");
8149     auto clientProxy = GetClientProxy();
8150     if (!clientProxy) {
8151         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8152         return;
8153     }
8154     clientProxy->SetDisplayNodeScreenId(screenId, displayNodeScreenId);
8155 #ifdef DEVICE_STATUS_ENABLE
8156     SetDragWindowScreenId(screenId, displayNodeScreenId);
8157 #endif // DEVICE_STATUS_ENABLE
8158     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SetMultiWindowScreenId");
8159     MMI::InputManager::GetInstance()->SetMultiWindowScreenId(screenId, displayNodeScreenId);
8160 }
8161 
8162 #ifdef DEVICE_STATUS_ENABLE
SetDragWindowScreenId(ScreenId screenId,ScreenId displayNodeScreenId)8163 void ScreenSessionManager::SetDragWindowScreenId(ScreenId screenId, ScreenId displayNodeScreenId)
8164 {
8165     auto interactionManager = Msdp::DeviceStatus::InteractionManager::GetInstance();
8166     if (interactionManager != nullptr) {
8167         interactionManager->SetDragWindowScreenId(screenId, displayNodeScreenId);
8168     }
8169 }
8170 #endif // DEVICE_STATUS_ENABLE
8171 
OnPropertyChange(const ScreenProperty & newProperty,ScreenPropertyChangeReason reason,ScreenId screenId)8172 void ScreenSessionManager::OnPropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason,
8173     ScreenId screenId)
8174 {
8175     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " reason: %{public}d", screenId, static_cast<int>(reason));
8176     auto clientProxy = GetClientProxy();
8177     if (!clientProxy) {
8178         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8179         if (foldScreenController_ != nullptr && !FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
8180             foldScreenController_->SetdisplayModeChangeStatus(false);
8181         }
8182         return;
8183     }
8184     clientProxy->OnPropertyChanged(screenId, newProperty, reason);
8185 }
8186 
OnPowerStatusChange(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)8187 void ScreenSessionManager::OnPowerStatusChange(DisplayPowerEvent event, EventStatus status,
8188     PowerStateChangeReason reason)
8189 {
8190     TLOGI(WmsLogTag::DMS, "[UL_POWER]event: %{public}d, status: %{public}d, reason: %{public}d",
8191         static_cast<int>(event),
8192         static_cast<int>(status), static_cast<int>(reason));
8193     auto clientProxy = GetClientProxy();
8194     if (!clientProxy) {
8195         TLOGI(WmsLogTag::DMS, "[UL_POWER] clientProxy_ is null");
8196         return;
8197     }
8198     clientProxy->OnPowerStatusChanged(event, status, reason);
8199 }
8200 
OnSensorRotationChange(float sensorRotation,ScreenId screenId)8201 void ScreenSessionManager::OnSensorRotationChange(float sensorRotation, ScreenId screenId)
8202 {
8203     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " sensorRotation: %{public}f", screenId, sensorRotation);
8204     auto clientProxy = GetClientProxy();
8205     if (!clientProxy) {
8206         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8207         return;
8208     }
8209     clientProxy->OnSensorRotationChanged(screenId, sensorRotation);
8210 }
8211 
OnHoverStatusChange(int32_t hoverStatus,bool needRotate,ScreenId screenId)8212 void ScreenSessionManager::OnHoverStatusChange(int32_t hoverStatus, bool needRotate, ScreenId screenId)
8213 {
8214     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " hoverStatus: %{public}d", screenId, hoverStatus);
8215     auto clientProxy = GetClientProxy();
8216     if (!clientProxy) {
8217         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8218         return;
8219     }
8220     clientProxy->OnHoverStatusChanged(screenId, hoverStatus, needRotate);
8221 }
8222 
OnScreenOrientationChange(float screenOrientation,ScreenId screenId)8223 void ScreenSessionManager::OnScreenOrientationChange(float screenOrientation, ScreenId screenId)
8224 {
8225     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " screenOrientation: %{public}f", screenId, screenOrientation);
8226     auto clientProxy = GetClientProxy();
8227     if (!clientProxy) {
8228         TLOGI(WmsLogTag::DMS, "ClientProxy_ is null");
8229         return;
8230     }
8231     clientProxy->OnScreenOrientationChanged(screenId, screenOrientation);
8232 }
8233 
OnScreenRotationLockedChange(bool isLocked,ScreenId screenId)8234 void ScreenSessionManager::OnScreenRotationLockedChange(bool isLocked, ScreenId screenId)
8235 {
8236     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " isLocked: %{public}d", screenId, isLocked);
8237     auto clientProxy = GetClientProxy();
8238     if (!clientProxy) {
8239         TLOGI(WmsLogTag::DMS, "ClientProxy_ is null");
8240         return;
8241     }
8242     clientProxy->OnScreenRotationLockedChanged(screenId, isLocked);
8243 }
8244 
OnCameraBackSelfieChange(bool isCameraBackSelfie,ScreenId screenId)8245 void ScreenSessionManager::OnCameraBackSelfieChange(bool isCameraBackSelfie, ScreenId screenId)
8246 {
8247     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " isCameraBackSelfie: %{public}d", screenId, isCameraBackSelfie);
8248     auto clientProxy = GetClientProxy();
8249     if (!clientProxy) {
8250         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8251         return;
8252     }
8253     clientProxy->OnCameraBackSelfieChanged(screenId, isCameraBackSelfie);
8254 }
8255 
NotifyClientProxyUpdateFoldDisplayMode(FoldDisplayMode displayMode)8256 void ScreenSessionManager::NotifyClientProxyUpdateFoldDisplayMode(FoldDisplayMode displayMode)
8257 {
8258     auto clientProxy = GetClientProxy();
8259     if (clientProxy) {
8260         TLOGI(WmsLogTag::DMS, "displayMode = %{public}d",
8261             static_cast<int>(displayMode));
8262         clientProxy->OnUpdateFoldDisplayMode(displayMode);
8263     }
8264 }
8265 
ScbClientDeathCallback(int32_t deathScbPid)8266 void ScreenSessionManager::ScbClientDeathCallback(int32_t deathScbPid)
8267 {
8268     std::unique_lock<std::mutex> lock(oldScbPidsMutex_);
8269     if (deathScbPid == currentScbPId_ || currentScbPId_ == INVALID_SCB_PID) {
8270         SetClientProxy(nullptr);
8271         TLOGE(WmsLogTag::DMS, "death callback and set clientProxy null");
8272     }
8273     if (scbSwitchCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_SCBSWITCH_MS))
8274         == std::cv_status::timeout) {
8275         TLOGE(WmsLogTag::DMS, "set client task deathScbPid:%{public}d, timeout: %{public}d",
8276             deathScbPid, CV_WAIT_SCBSWITCH_MS);
8277     }
8278     std::ostringstream oss;
8279     oss << "Scb client death: " << deathScbPid;
8280     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
8281     screenEventTracker_.RecordEvent(oss.str());
8282     oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), deathScbPid), oldScbPids_.end());
8283 }
8284 
AddScbClientDeathRecipient(const sptr<IScreenSessionManagerClient> & scbClient,int32_t scbPid)8285 void ScreenSessionManager::AddScbClientDeathRecipient(const sptr<IScreenSessionManagerClient>& scbClient,
8286     int32_t scbPid)
8287 {
8288     sptr<ScbClientListenerDeathRecipient> scbClientDeathListener =
8289         new (std::nothrow) ScbClientListenerDeathRecipient(scbPid);
8290     if (scbClientDeathListener == nullptr) {
8291         TLOGE(WmsLogTag::DMS, "add scb: %{public}d death listener failed", scbPid);
8292         return;
8293     }
8294     if (scbClient != nullptr && scbClient->AsObject() != nullptr) {
8295         TLOGI(WmsLogTag::DMS, "add scb: %{public}d death listener", scbPid);
8296         scbClient->AsObject()->AddDeathRecipient(scbClientDeathListener);
8297     }
8298 }
8299 
SwitchUser()8300 void ScreenSessionManager::SwitchUser()
8301 {
8302 #ifdef WM_MULTI_USR_ABILITY_ENABLE
8303     if (!SessionPermission::IsSystemCalling()) {
8304         TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
8305             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8306         return;
8307     }
8308     auto userId = GetUserIdByCallingUid();
8309     auto newScbPid = IPCSkeleton::GetCallingPid();
8310     currentUserIdForSettings_ = userId;
8311     if (g_isPcDevice && userSwitching_) {
8312         std::unique_lock<std::mutex> lock(switchUserMutex_);
8313         if (switchUserCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_USERSWITCH_MS)) == std::cv_status::timeout) {
8314             TLOGI(WmsLogTag::DMS, "wait switchUserCV_ timeout");
8315             userSwitching_ = false;
8316         }
8317     }
8318     SwitchScbNodeHandle(userId, newScbPid, false);
8319     MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, GetDefaultScreenId(), false);
8320 #endif
8321 }
8322 
SetDefaultMultiScreenModeWhenSwitchUser()8323 void ScreenSessionManager::SetDefaultMultiScreenModeWhenSwitchUser()
8324 {
8325     if (!SessionPermission::IsSystemCalling()) {
8326         TLOGE(WmsLogTag::DMS, "permission denied!");
8327         return;
8328     }
8329     TLOGI(WmsLogTag::DMS, "switching user, change screen mode.");
8330     if (!g_isPcDevice) {
8331         TLOGW(WmsLogTag::DMS, "not pc device");
8332         return;
8333     }
8334 #ifdef WM_MULTI_USR_ABILITY_ENABLE
8335     sptr<ScreenSession> innerSession = nullptr;
8336     sptr<ScreenSession> externalSession = nullptr;
8337     GetInternalAndExternalSession(innerSession, externalSession);
8338     if (!innerSession || !externalSession) {
8339         TLOGE(WmsLogTag::DMS, "screen session is null.");
8340         return;
8341     }
8342     userSwitching_ = true;
8343     std::ostringstream oss;
8344     oss << "innerScreen screenId: " << innerSession->GetScreenId()
8345         << ", rsId: " << innerSession->GetRSScreenId()
8346         << ", externalScreen screenId: " << externalSession->GetScreenId()
8347         << ", rsId: " << externalSession->GetRSScreenId();
8348     oss << std::endl;
8349     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
8350     if (externalSession->GetScreenCombination() != ScreenCombination::SCREEN_MIRROR) {
8351         if (GetIsOuterOnlyMode()) {
8352             TLOGI(WmsLogTag::DMS, "exit outer only mode.");
8353             SetIsOuterOnlyMode(false);
8354             ExitOuterOnlyMode(innerSession->GetRSScreenId(), externalSession->GetRSScreenId(),
8355                 MultiScreenMode::SCREEN_MIRROR);
8356             switchUserCV_.notify_all();
8357             userSwitching_ = false;
8358         } else {
8359             TLOGI(WmsLogTag::DMS, "change to mirror.");
8360             SetIsOuterOnlyMode(false);
8361             MultiScreenModeChange(innerSession->GetRSScreenId(), externalSession->GetRSScreenId(), SCREEN_MIRROR);
8362         }
8363     } else {
8364         TLOGI(WmsLogTag::DMS, "already mirror.");
8365         switchUserCV_.notify_all();
8366         userSwitching_ = false;
8367     }
8368 #endif
8369 }
8370 
ScbStatusRecoveryWhenSwitchUser(std::vector<int32_t> oldScbPids,int32_t newScbPid)8371 void ScreenSessionManager::ScbStatusRecoveryWhenSwitchUser(std::vector<int32_t> oldScbPids, int32_t newScbPid)
8372 {
8373 #ifdef WM_MULTI_USR_ABILITY_ENABLE
8374     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
8375     if (screenSession == nullptr) {
8376         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
8377         return;
8378     }
8379     if (g_foldScreenFlag) {
8380         NotifyFoldStatusChanged(GetFoldStatus());
8381         NotifyDisplayModeChanged(GetFoldDisplayMode());
8382     }
8383     int64_t delayTime = 0;
8384     if (g_foldScreenFlag && oldScbDisplayMode_ != GetFoldDisplayMode() &&
8385         !FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
8386         delayTime = SWITCH_USER_DISPLAYMODE_CHANGE_DELAY;
8387         auto foldStatus = GetFoldStatus();
8388         TLOGE(WmsLogTag::DMS, "old mode: %{public}u, cur mode: %{public}u", oldScbDisplayMode_, GetFoldDisplayMode());
8389         if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
8390             screenSession->UpdatePropertyByFoldControl(screenSession->GetScreenProperty());
8391             OnVerticalChangeBoundsWhenSwitchUser(screenSession);
8392             screenSession->PropertyChange(screenSession->GetScreenProperty(),
8393                 FoldDisplayMode::MAIN == GetFoldDisplayMode() ? ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING :
8394                 ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
8395         } else if (foldStatus == FoldStatus::EXPAND || foldStatus == FoldStatus::HALF_FOLD) {
8396             screenSession->UpdatePropertyByFoldControl(GetPhyScreenProperty(SCREEN_ID_FULL));
8397             OnBeforeScreenPropertyChange(foldStatus);
8398             screenSession->PropertyChange(screenSession->GetScreenProperty(),
8399                 ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
8400         } else if (foldStatus == FoldStatus::FOLDED) {
8401             screenSession->UpdatePropertyByFoldControl(GetPhyScreenProperty(SCREEN_ID_MAIN));
8402             OnBeforeScreenPropertyChange(foldStatus);
8403             screenSession->PropertyChange(screenSession->GetScreenProperty(),
8404                 ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING);
8405         } else {
8406             TLOGE(WmsLogTag::DMS, "unsupport foldStatus: %{public}u", foldStatus);
8407         }
8408     } else {
8409         screenSession->UpdateValidRotationToScb();
8410     }
8411     auto task = [=] {
8412         auto clientProxy = GetClientProxy();
8413         if (!clientProxy) {
8414             TLOGNE(WmsLogTag::DMS, "ScbStatusRecoveryWhenSwitchUser clientProxy_ is null");
8415             return;
8416         }
8417         clientProxy->SwitchUserCallback(oldScbPids, newScbPid);
8418         RecoverMultiScreenModeWhenSwitchUser(oldScbPids, newScbPid);
8419     };
8420     taskScheduler_->PostAsyncTask(task, "clientProxy_ SwitchUserCallback task", delayTime);
8421 #endif
8422 }
8423 
OnVerticalChangeBoundsWhenSwitchUser(sptr<ScreenSession> screenSession)8424 void ScreenSessionManager::OnVerticalChangeBoundsWhenSwitchUser(sptr<ScreenSession> screenSession)
8425 {
8426     if (screenSession == nullptr) {
8427         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
8428         return;
8429     }
8430     auto rotation = screenSession->GetScreenProperty().GetRotation();
8431     if (std::fabs(rotation - SECONDARY_ROTATION_90) < FLT_EPSILON ||
8432         std::fabs(rotation - SECONDARY_ROTATION_270) < FLT_EPSILON ) {
8433         const RRect& bounds = screenSession->GetScreenProperty().GetBounds();
8434         RRect afterBounds =
8435             RRect({ 0, bounds.rect_.GetTop(), bounds.rect_.GetHeight(), bounds.rect_.GetWidth()}, 0.0f, 0.0f);
8436         screenSession->SetBounds(afterBounds);
8437         TLOGI(WmsLogTag::DMS, "before width:%{public}f, height:%{public}f,after width:%{public}f, height:%{public}f",
8438             bounds.rect_.GetWidth(), bounds.rect_.GetHeight(),
8439             afterBounds.rect_.GetWidth(), afterBounds.rect_.GetHeight());
8440     }
8441 }
8442 
RecoverMultiScreenModeWhenSwitchUser(std::vector<int32_t> oldScbPids,int32_t newScbPid)8443 void ScreenSessionManager::RecoverMultiScreenModeWhenSwitchUser(std::vector<int32_t> oldScbPids, int32_t newScbPid)
8444 {
8445     if (!g_isPcDevice) {
8446         TLOGI(WmsLogTag::DMS, "not PC device, return before recover.");
8447         return;
8448     }
8449     bool extendScreenConnected = false;
8450     ScreenId extendScreenId = SCREEN_ID_INVALID;
8451     std::map<ScreenId, sptr<ScreenSession>> screenSessionMap;
8452     {
8453         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8454         screenSessionMap = screenSessionMap_;
8455     }
8456     for (const auto& [screenId, screenSession] : screenSessionMap) {
8457         if (screenSession == nullptr) {
8458             TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
8459             continue;
8460         }
8461         if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
8462             screenSession->GetIsExtend()) {
8463             TLOGI(WmsLogTag::DMS, "recover extend screen, screenId = %{public}" PRIu64, screenId);
8464             extendScreenConnected = true;
8465             extendScreenId = screenId;
8466             RecoverMultiScreenMode(screenSession);
8467             FlushDisplayNodeWhenSwtichUser(oldScbPids, newScbPid, screenSession);
8468         } else if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
8469             !screenSession->GetIsExtend()) {
8470             SetExtendedScreenFallbackPlan(screenId);
8471         }
8472     }
8473     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
8474         if (extendScreenConnected) {
8475             OnExtendScreenConnectStatusChange(extendScreenId, ExtendScreenConnectStatus::CONNECT);
8476         } else {
8477             OnExtendScreenConnectStatusChange(extendScreenId, ExtendScreenConnectStatus::DISCONNECT);
8478         }
8479     }
8480 }
8481 
FlushDisplayNodeWhenSwtichUser(std::vector<int32_t> oldScbPids,int32_t newScbPid,sptr<ScreenSession> screenSession)8482 void ScreenSessionManager::FlushDisplayNodeWhenSwtichUser(std::vector<int32_t> oldScbPids, int32_t newScbPid,
8483     sptr<ScreenSession> screenSession)
8484 {
8485     {
8486         auto displayNode = screenSession->GetDisplayNode();
8487         if (displayNode == nullptr) {
8488             TLOGE(WmsLogTag::DMS, "display node is null");
8489             return;
8490         }
8491         displayNode->SetScbNodePid(oldScbPids, newScbPid);
8492     }
8493     RSTransactionAdapter::FlushImplicitTransaction(screenSession->GetRSUIContext());
8494 }
8495 
HandleSwitchPcMode()8496 bool ScreenSessionManager::HandleSwitchPcMode()
8497 {
8498     if (!IS_SUPPORT_PC_MODE) {
8499         return g_isPcDevice;
8500     }
8501     std::lock_guard<std::mutex> lock(pcModeSwitchMutex_);
8502     if (system::GetBoolParameter(IS_PC_MODE_KEY, false)) {
8503         TLOGI(WmsLogTag::DMS, "PcMode change isPcDevice true");
8504         g_isPcDevice = true;
8505         SwitchModeHandleExternalScreen(true);
8506 #ifdef WM_MULTI_SCREEN_CTL_ABILITY_ENABLE
8507         SetMultiScreenFrameControl();
8508 #endif
8509     } else {
8510         TLOGI(WmsLogTag::DMS, "PadMode change isPcDevice false");
8511         g_isPcDevice = false;
8512         SwitchModeHandleExternalScreen(false);
8513 #ifdef WM_MULTI_SCREEN_CTL_ABILITY_ENABLE
8514         TLOGI(WmsLogTag::DMS, "Disable frame rate control");
8515         EventInfo event = { "VOTER_MUTIPHYSICALSCREEN", REMOVE_VOTE };
8516         rsInterface_.NotifyRefreshRateEvent(event);
8517 #endif
8518     }
8519     return g_isPcDevice;
8520 }
8521 
SwitchModeHandleExternalScreen(bool isSwitchToPcMode)8522 void ScreenSessionManager::SwitchModeHandleExternalScreen(bool isSwitchToPcMode)
8523 {
8524     std::ostringstream oss;
8525     std::vector<ScreenId> externalScreenIds;
8526     bool hasExternalScreen = false;
8527     {
8528         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8529         for (const auto& iter : screenSessionMap_) {
8530             auto screenSession = iter.second;
8531             if (screenSession == nullptr) {
8532                 continue;
8533             }
8534             if (IsDefaultMirrorMode(screenSession->GetScreenId()) && screenSession->GetIsRealScreen()) {
8535                 externalScreenIds.emplace_back(screenSession->GetScreenId());
8536                 hasExternalScreen = true;
8537                 screenSession->SetName(isSwitchToPcMode ? SCREEN_NAME_EXTEND : SCREEN_NAME_CAST);
8538                 screenSession->SetVirtualScreenFlag(isSwitchToPcMode ?
8539                     VirtualScreenFlag::DEFAULT : VirtualScreenFlag::CAST);
8540                 oss << screenSession->GetScreenId() << ",";
8541             }
8542         }
8543     }
8544     TLOGI(WmsLogTag::DMS, "screenIds:%{public}s", oss.str().c_str());
8545     if (hasExternalScreen && !isSwitchToPcMode) {
8546         ScreenId screenGroupId = SCREEN_GROUP_ID_DEFAULT;
8547         MakeMirror(SCREEN_ID_DEFAULT, externalScreenIds, screenGroupId);
8548         TLOGI(WmsLogTag::DMS, "notify cast screen connect");
8549         NotifyCastWhenScreenConnectChange(true);
8550     }
8551 }
8552 
SetClient(const sptr<IScreenSessionManagerClient> & client)8553 void ScreenSessionManager::SetClient(const sptr<IScreenSessionManagerClient>& client)
8554 {
8555     if (!SessionPermission::IsSystemCalling()) {
8556         TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
8557             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8558         return;
8559     }
8560     if (!client) {
8561         TLOGE(WmsLogTag::DMS, "SetClient client is null");
8562         return;
8563     }
8564     HandleSwitchPcMode();
8565     if (g_isPcDevice && userSwitching_) {
8566         std::unique_lock<std::mutex> lock(switchUserMutex_);
8567         if (switchUserCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_USERSWITCH_MS)) == std::cv_status::timeout) {
8568             TLOGW(WmsLogTag::DMS, "wait switchUserCV_ timeout");
8569             userSwitching_ = false;
8570         }
8571     }
8572     SetClientProxy(client);
8573     auto userId = GetUserIdByCallingUid();
8574     auto newScbPid = IPCSkeleton::GetCallingPid();
8575 
8576     std::ostringstream oss;
8577     oss << "set client userId: " << userId
8578         << " clientName: " << SysCapUtil::GetClientName();
8579     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
8580     screenEventTracker_.RecordEvent(oss.str());
8581     currentUserIdForSettings_ = userId;
8582     MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, GetDefaultScreenId(), true);
8583     NotifyClientProxyUpdateFoldDisplayMode(GetFoldDisplayMode());
8584     SetClientInner();
8585     SwitchScbNodeHandle(userId, newScbPid, true);
8586     AddScbClientDeathRecipient(client, newScbPid);
8587 
8588     static bool isNeedSwitchScreen = FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() ||
8589         FoldScreenStateInternel::IsSingleDisplayFoldDevice();
8590     if (isNeedSwitchScreen) {
8591         FoldDisplayMode displayMode = GetFoldDisplayMode();
8592         if (displayMode == FoldDisplayMode::FULL) {
8593             TLOGI(WmsLogTag::DMS, "switch screen to full");
8594             SetDisplayNodeScreenId(SCREEN_ID_FULL, SCREEN_ID_FULL);
8595         } else if (displayMode == FoldDisplayMode::MAIN) {
8596             TLOGI(WmsLogTag::DMS, "switch screen to main");
8597             SetDisplayNodeScreenId(SCREEN_ID_FULL, SCREEN_ID_MAIN);
8598         }
8599     }
8600 }
8601 
SwitchScbNodeHandle(int32_t newUserId,int32_t newScbPid,bool coldBoot)8602 void ScreenSessionManager::SwitchScbNodeHandle(int32_t newUserId, int32_t newScbPid, bool coldBoot)
8603 {
8604 #ifdef WM_MULTI_USR_ABILITY_ENABLE
8605     std::ostringstream oss;
8606     oss << "currentUserId: " << currentUserId_
8607         << "  currentScbPId: " << currentScbPId_
8608         << "  newUserId: " << newUserId
8609         << "  newScbPid: " << newScbPid
8610         << "  coldBoot: " << static_cast<int32_t>(coldBoot);
8611     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
8612     screenEventTracker_.RecordEvent(oss.str());
8613 
8614     std::unique_lock<std::mutex> lock(oldScbPidsMutex_);
8615     if (currentScbPId_ != INVALID_SCB_PID) {
8616         auto pidIter = std::find(oldScbPids_.begin(), oldScbPids_.end(), currentScbPId_);
8617         if (pidIter == oldScbPids_.end() && currentScbPId_ > 0) {
8618             oldScbPids_.emplace_back(currentScbPId_);
8619         }
8620         oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), newScbPid), oldScbPids_.end());
8621         if (oldScbPids_.size() == 0) {
8622             TLOGE(WmsLogTag::DMS, "swicth user failed, oldScbPids is null");
8623             screenEventTracker_.RecordEvent("swicth user failed, oldScbPids is null");
8624         }
8625     }
8626     auto clientProxy = GetClientProxy();
8627     if (!clientProxy) {
8628         TLOGE(WmsLogTag::DMS, "clientProxy is null");
8629         return;
8630     }
8631     if (coldBoot) {
8632         clientProxy->SwitchUserCallback(oldScbPids_, newScbPid);
8633         clientProxyMap_[newUserId] = clientProxy;
8634     } else {
8635         HotSwitch(newUserId, newScbPid);
8636     }
8637     UpdateDisplayScaleState(GetDefaultScreenId());
8638     currentUserId_ = newUserId;
8639     currentScbPId_ = newScbPid;
8640     scbSwitchCV_.notify_all();
8641     oldScbDisplayMode_ = GetFoldDisplayMode();
8642 #endif
8643 }
8644 
NotifyCastWhenSwitchScbNode()8645 void ScreenSessionManager::NotifyCastWhenSwitchScbNode()
8646 {
8647     std::map<ScreenId, sptr<ScreenSession>> screenSessionMapCopy;
8648     {
8649         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8650         screenSessionMapCopy = screenSessionMap_;
8651     }
8652     for (const auto& sessionIt : screenSessionMapCopy) {
8653         auto screenSession = sessionIt.second;
8654         if (screenSession == nullptr) {
8655             TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first);
8656             continue;
8657         }
8658         if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL ||
8659             !IsDefaultMirrorMode(screenSession->GetScreenId())) {
8660             TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"", sessionIt.first);
8661             continue;
8662         }
8663         bool isScreenMirror = screenSession ->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR;
8664         NotifyCastWhenScreenConnectChange(isScreenMirror);
8665         return;
8666     }
8667 }
8668 
HotSwitch(int32_t newUserId,int32_t newScbPid)8669 void ScreenSessionManager::HotSwitch(int32_t newUserId, int32_t newScbPid)
8670 {
8671     // hot switch
8672     if (clientProxyMap_.count(newUserId) == 0) {
8673         TLOGE(WmsLogTag::DMS, "not found client proxy. userId:%{public}d.", newUserId);
8674         return;
8675     }
8676     if (newUserId == currentUserId_) {
8677         TLOGI(WmsLogTag::DMS, "switch user not change");
8678         return;
8679     }
8680     if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
8681         // Delete the screen whose ID is 5 generated by Coordination before switching the private space.
8682         SessionOption option = {
8683             .screenId_ = SCREEN_ID_MAIN,
8684         };
8685         auto clientProxy = GetClientProxy();
8686         if (clientProxy) {
8687             clientProxy->OnScreenConnectionChanged(option, ScreenEvent::DISCONNECTED);
8688         }
8689     }
8690     SetClientProxy(clientProxyMap_[newUserId]);
8691     ScbStatusRecoveryWhenSwitchUser(oldScbPids_, newScbPid);
8692 }
8693 
GetCurrentUserId()8694 int32_t ScreenSessionManager::GetCurrentUserId()
8695 {
8696     return currentUserIdForSettings_;
8697 }
8698 
SetClientInner()8699 void ScreenSessionManager::SetClientInner()
8700 {
8701     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8702     for (const auto& iter : screenSessionMap_) {
8703         if (!iter.second) {
8704             continue;
8705         }
8706         // In the rotating state, after scb restarts, the screen information needs to be reset.
8707         float phyWidth = 0.0f;
8708         float phyHeight = 0.0f;
8709         bool isReset = true;
8710         int boundaryOffset = 0;
8711         GetCurrentScreenPhyBounds(phyWidth, phyHeight, isReset, iter.first);
8712         auto localRotation = iter.second->GetRotation();
8713         if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
8714             FoldDisplayMode displayMode = GetFoldDisplayMode();
8715             if (displayMode == FoldDisplayMode::FULL) {
8716                 boundaryOffset = SECONDARY_FULL_OFFSET;
8717                 phyWidth = SECONDARY_FULL_STATUS_WIDTH;
8718             } else if (displayMode == FoldDisplayMode::MAIN) {
8719                 phyWidth = MAIN_STATUS_DEFAULT_WIDTH;
8720                 phyHeight = SCREEN_DEFAULT_HEIGHT;
8721             }
8722         }
8723         TLOGI(WmsLogTag::DMS, "phyWidth = :%{public}f, phyHeight = :%{public}f, localRotation = :%{public}u",
8724             phyWidth, phyHeight, localRotation);
8725         if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
8726             bool isModeChanged = localRotation != Rotation::ROTATION_0;
8727             if (isModeChanged && isReset) {
8728                 TLOGI(WmsLogTag::DMS, "screen(id:%{public}" PRIu64 ") current is not default mode, reset it",
8729                     iter.first);
8730                 SetRotation(iter.first, Rotation::ROTATION_0, false);
8731                 SetPhysicalRotationClientInner(iter.first, 0);
8732                 iter.second->SetDisplayBoundary(RectF(0, boundaryOffset, phyWidth, phyHeight), 0);
8733             }
8734         }
8735         auto clientProxy = GetClientProxy();
8736         if (!clientProxy) {
8737             TLOGE(WmsLogTag::DMS, "clientProxy is null");
8738             return;
8739         }
8740         if (iter.second->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
8741             TLOGI(WmsLogTag::DMS, "current screen is extend and mirror, return before OnScreenConnectionChanged");
8742             RecoverMultiScreenMode(iter.second);
8743             continue;
8744         }
8745         clientProxy->OnScreenConnectionChanged(GetSessionOption(iter.second, iter.first),
8746             ScreenEvent::CONNECTED);
8747         RecoverMultiScreenMode(iter.second);
8748     }
8749 }
8750 
SetPhysicalRotationClientInner(ScreenId screenId,int rotation)8751 void ScreenSessionManager::SetPhysicalRotationClientInner(ScreenId screenId, int rotation)
8752 {
8753     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
8754     if (screenSession == nullptr) {
8755         TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"",
8756             screenId);
8757         return;
8758     }
8759     screenSession->SetPhysicalRotation(rotation);
8760     screenSession->SetScreenComponentRotation(rotation);
8761     TLOGI(WmsLogTag::DMS, "SetPhysicalRotationClientInner end");
8762 }
8763 
RecoverDefaultScreenModeInner(ScreenId innerRsId,ScreenId externalRsId)8764 void ScreenSessionManager::RecoverDefaultScreenModeInner(ScreenId innerRsId, ScreenId externalRsId)
8765 {
8766 #ifdef FOLD_ABILITY_ENABLE
8767     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
8768         SuperFoldStateManager::GetInstance().GetCurrentStatus() != SuperFoldStatus::EXPANDED) {
8769         SetMultiScreenMode(innerRsId, externalRsId, MultiScreenMode::SCREEN_MIRROR);
8770         ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_MIRROR);
8771     } else {
8772 #endif
8773     SetMultiScreenMode(innerRsId, externalRsId, MultiScreenMode::SCREEN_EXTEND);
8774     ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_EXTEND);
8775 #ifdef FOLD_ABILITY_ENABLE
8776     }
8777 #endif
8778 }
8779 
RecoverMultiScreenMode(sptr<ScreenSession> screenSession)8780 void ScreenSessionManager::RecoverMultiScreenMode(sptr<ScreenSession> screenSession)
8781 {
8782     if (screenSession == nullptr) {
8783         TLOGE(WmsLogTag::DMS, "screenSession is null!");
8784         return;
8785     }
8786     if (!g_isPcDevice || screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL) {
8787         TLOGI(WmsLogTag::DMS, "not PC or not real screen, no need recover!");
8788         return;
8789     }
8790     if (isDeviceShutDown_) {
8791         TLOGI(WmsLogTag::DMS, "device shut down, no need recover!");
8792         return;
8793     }
8794     sptr<ScreenSession> internalSession = GetInternalScreenSession();
8795     if (!RecoverRestoredMultiScreenMode(screenSession)) {
8796         if (internalSession == nullptr) {
8797             TLOGE(WmsLogTag::DMS, "internalSession is nullptr");
8798             return;
8799         }
8800         ScreenId innerRsId = internalSession->GetRSScreenId();
8801         ScreenId externalRsId = screenSession->GetRSScreenId();
8802         if (innerRsId == externalRsId) {
8803             TLOGW(WmsLogTag::DMS, "same rsId: %{public}" PRIu64, innerRsId);
8804             return;
8805         }
8806         RecoverDefaultScreenModeInner(innerRsId, externalRsId);
8807         SetMultiScreenDefaultRelativePosition();
8808     }
8809     sptr<ScreenSession> newInternalSession = GetInternalScreenSession();
8810     if (newInternalSession != nullptr && internalSession != nullptr &&
8811         internalSession->GetScreenId() != newInternalSession->GetScreenId()) {
8812         TLOGW(WmsLogTag::DMS, "main screen changed, reset screenSession.");
8813         screenSession = internalSession;
8814     }
8815     SetExtendedScreenFallbackPlan(screenSession->GetScreenId());
8816     if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
8817         screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::UNDEFINED);
8818     }
8819 }
8820 
GetCurrentScreenPhyBounds(float & phyWidth,float & phyHeight,bool & isReset,const ScreenId & screenid)8821 void ScreenSessionManager::GetCurrentScreenPhyBounds(float& phyWidth, float& phyHeight,
8822                                                      bool& isReset, const ScreenId& screenid)
8823 {
8824 #ifdef FOLD_ABILITY_ENABLE
8825     if (foldScreenController_ != nullptr) {
8826         FoldDisplayMode displayMode = GetFoldDisplayMode();
8827         TLOGI(WmsLogTag::DMS, "fold screen with displayMode = %{public}u", displayMode);
8828         if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
8829             auto phyBounds = GetPhyScreenProperty(screenid).GetPhyBounds();
8830             phyWidth = phyBounds.rect_.width_;
8831             phyHeight = phyBounds.rect_.height_;
8832             if (displayMode == FoldDisplayMode::UNKNOWN) {
8833                 isReset = false;
8834             }
8835             return;
8836         }
8837         if (displayMode == FoldDisplayMode::MAIN) {
8838             auto phyBounds = GetPhyScreenProperty(SCREEN_ID_MAIN).GetPhyBounds();
8839             phyWidth = phyBounds.rect_.width_;
8840             phyHeight = phyBounds.rect_.height_;
8841         } else if (displayMode == FoldDisplayMode::FULL || displayMode == FoldDisplayMode::GLOBAL_FULL) {
8842             auto phyBounds = GetPhyScreenProperty(SCREEN_ID_FULL).GetPhyBounds();
8843             phyWidth = phyBounds.rect_.width_;
8844             phyHeight = phyBounds.rect_.height_;
8845             if (g_screenRotationOffSet == ROTATION_90 || g_screenRotationOffSet == ROTATION_270) {
8846                 std::swap(phyWidth, phyHeight);
8847             }
8848         } else {
8849             isReset = false;
8850         }
8851         return;
8852     }
8853 #endif
8854     int id = HiviewDFX::XCollie::GetInstance().SetTimer("GetCurrentScreenPhyBounds", XCOLLIE_TIMEOUT_10S, nullptr,
8855         nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
8856     auto remoteScreenMode = rsInterface_.GetScreenActiveMode(screenid);
8857     HiviewDFX::XCollie::GetInstance().CancelTimer(id);
8858     phyWidth = remoteScreenMode.GetScreenWidth();
8859     phyHeight = remoteScreenMode.GetScreenHeight();
8860 }
8861 
GetScreenProperty(ScreenId screenId)8862 ScreenProperty ScreenSessionManager::GetScreenProperty(ScreenId screenId)
8863 {
8864     if (!SessionPermission::IsSystemCalling()) {
8865         TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
8866             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8867         return {};
8868     }
8869     DmsXcollie dmsXcollie("DMS:GetScreenProperty", XCOLLIE_TIMEOUT_10S);
8870     auto screenSession = GetScreenSession(screenId);
8871     if (!screenSession) {
8872         TLOGI(WmsLogTag::DMS, "screenSession is null");
8873         return {};
8874     }
8875     return screenSession->GetScreenProperty();
8876 }
8877 
GetDisplayNode(ScreenId screenId)8878 std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetDisplayNode(ScreenId screenId)
8879 {
8880     if (!SessionPermission::IsSystemCalling()) {
8881         TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
8882             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8883         return nullptr;
8884     }
8885     DmsXcollie dmsXcollie("DMS:GetDisplayNode", XCOLLIE_TIMEOUT_10S);
8886     auto screenSession = GetScreenSession(screenId);
8887     if (!screenSession) {
8888         TLOGE(WmsLogTag::DMS, "screenSession is null");
8889         return nullptr;
8890     }
8891     return screenSession->GetDisplayNode();
8892 }
8893 
GetScreenCombination(ScreenId screenId)8894 ScreenCombination ScreenSessionManager::GetScreenCombination(ScreenId screenId)
8895 {
8896     DmsXcollie dmsXcollie("DMS:GetScreenCombination", XCOLLIE_TIMEOUT_10S);
8897     auto screenSession = GetScreenSession(screenId);
8898     if (!screenSession) {
8899         TLOGI(WmsLogTag::DMS, "screenSession is null");
8900         return ScreenCombination::SCREEN_ALONE;
8901     }
8902     return screenSession->GetScreenCombination();
8903 }
8904 
Dump(int fd,const std::vector<std::u16string> & args)8905 int ScreenSessionManager::Dump(int fd, const std::vector<std::u16string>& args)
8906 {
8907     TLOGI(WmsLogTag::DMS, "Dump begin");
8908     sptr<ScreenSessionDumper> dumper = new ScreenSessionDumper(fd, args);
8909     if (dumper == nullptr) {
8910         TLOGE(WmsLogTag::DMS, "dumper is nullptr");
8911         return -1;
8912     }
8913     {
8914         std::lock_guard<std::mutex> lock(freezedPidListMutex_);
8915         dumper->DumpFreezedPidList(freezedPidList_);
8916     }
8917     dumper->DumpEventTracker(screenEventTracker_);
8918     {
8919         std::lock_guard<std::mutex> lock(oldScbPidsMutex_);
8920         dumper->DumpMultiUserInfo(oldScbPids_, currentUserId_, currentScbPId_);
8921     }
8922     dumper->ExecuteDumpCmd();
8923     TLOGI(WmsLogTag::DMS, "dump end");
8924     return 0;
8925 }
8926 
TriggerFoldStatusChange(FoldStatus foldStatus)8927 void ScreenSessionManager::TriggerFoldStatusChange(FoldStatus foldStatus)
8928 {
8929 #ifdef FOLD_ABILITY_ENABLE
8930     TLOGI(WmsLogTag::DMS, "enter foldStatus = %{public}d.", foldStatus);
8931     if (foldScreenController_ == nullptr) {
8932         return;
8933     }
8934     foldScreenController_->SetFoldStatus(foldStatus);
8935     FoldDisplayMode displayMode = foldScreenController_->GetModeMatchStatus();
8936     SetFoldDisplayMode(displayMode);
8937     NotifyFoldStatusChanged(foldStatus);
8938 #endif
8939 }
8940 
NotifyFoldStatusChanged(const std::string & statusParam)8941 int ScreenSessionManager::NotifyFoldStatusChanged(const std::string& statusParam)
8942 {
8943 #ifdef FOLD_ABILITY_ENABLE
8944     TLOGI(WmsLogTag::DMS, "is dump log");
8945     if (statusParam.empty()) {
8946         return -1;
8947     }
8948     FoldStatus foldStatus = FoldStatus::UNKNOWN;
8949     FoldDisplayMode displayMode = FoldDisplayMode::UNKNOWN;
8950     if (statusParam == STATUS_FOLD_HALF) {
8951         foldStatus = FoldStatus::HALF_FOLD;
8952         displayMode = FoldDisplayMode::FULL;
8953     } else if (statusParam == STATUS_EXPAND) {
8954         foldStatus = FoldStatus::EXPAND;
8955         displayMode = FoldDisplayMode::FULL;
8956     } else if (statusParam == STATUS_FOLD) {
8957         foldStatus = FoldStatus::FOLDED;
8958         displayMode = FoldDisplayMode::MAIN;
8959     } else {
8960         TLOGW(WmsLogTag::DMS, "status not support");
8961         return -1;
8962     }
8963     SetFoldDisplayMode(displayMode);
8964     if (foldScreenController_ != nullptr) {
8965         foldScreenController_->SetFoldStatus(foldStatus);
8966     }
8967     NotifyFoldStatusChanged(foldStatus);
8968 #endif
8969     return 0;
8970 }
8971 
NotifyAvailableAreaChanged(DMRect area,DisplayId displayId)8972 void ScreenSessionManager::NotifyAvailableAreaChanged(DMRect area, DisplayId displayId)
8973 {
8974     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER);
8975     TLOGI(WmsLogTag::DMS, "entry, agent size: %{public}u", static_cast<uint32_t>(agents.size()));
8976     if (agents.empty()) {
8977         return;
8978     }
8979     TLOGI(WmsLogTag::DMS, "displayId: %{public}" PRIu64
8980         ", AvailableArea: [%{public}d, %{public}d, %{public}u, %{public}u]",
8981         static_cast<DisplayId>(displayId), area.posX_, area.posY_, area.width_, area.height_);
8982     for (auto& agent : agents) {
8983         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8984         if (!IsFreezed(agentPid,
8985             DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER)) {
8986             agent->NotifyAvailableAreaChanged(area, displayId);
8987         }
8988     }
8989 }
8990 
GetAvailableArea(DisplayId displayId,DMRect & area)8991 DMError ScreenSessionManager::GetAvailableArea(DisplayId displayId, DMRect& area)
8992 {
8993     auto displayInfo = GetDisplayInfoById(displayId);
8994     if (displayInfo == nullptr) {
8995         TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
8996         return DMError::DM_ERROR_NULLPTR;
8997     }
8998     sptr<ScreenSession> screenSession;
8999     if (displayId == DISPLAY_ID_FAKE) {
9000         if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
9001             return DMError::DM_ERROR_NULLPTR;
9002         }
9003         ScreenId internalScreenId = GetInternalScreenId();
9004         sptr<ScreenSession> internalScreenSession = GetScreenSession(internalScreenId);
9005         if (internalScreenSession == nullptr) {
9006             TLOGE(WmsLogTag::DMS, "internal session is nullptr.");
9007             return DMError::DM_ERROR_NULLPTR;
9008         }
9009         if (!internalScreenSession->GetScreenProperty().GetIsFakeInUse()) {
9010             return DMError::DM_ERROR_NULLPTR;
9011         }
9012         screenSession = internalScreenSession->GetFakeScreenSession();
9013     } else {
9014         screenSession = GetScreenSession(displayInfo->GetScreenId());
9015     }
9016     if (screenSession == nullptr) {
9017         TLOGE(WmsLogTag::DMS, "can not get screen now");
9018         return DMError::DM_ERROR_NULLPTR;
9019     }
9020     area = screenSession->GetAvailableArea();
9021     return DMError::DM_OK;
9022 }
9023 
GetExpandAvailableArea(DisplayId displayId,DMRect & area)9024 DMError ScreenSessionManager::GetExpandAvailableArea(DisplayId displayId, DMRect& area)
9025 {
9026     auto displayInfo = GetDisplayInfoById(displayId);
9027     if (displayInfo == nullptr) {
9028         TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
9029         return DMError::DM_ERROR_NULLPTR;
9030     }
9031     sptr<ScreenSession> screenSession;
9032     screenSession = GetScreenSession(displayInfo->GetScreenId());
9033     if (screenSession == nullptr) {
9034         TLOGE(WmsLogTag::DMS, "can not get screen now");
9035         return DMError::DM_ERROR_NULLPTR;
9036     }
9037     area = screenSession->GetExpandAvailableArea();
9038     return DMError::DM_OK;
9039 }
9040 
UpdateAvailableArea(ScreenId screenId,DMRect area)9041 void ScreenSessionManager::UpdateAvailableArea(ScreenId screenId, DMRect area)
9042 {
9043     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9044         TLOGE(WmsLogTag::DMS, "update available area permission denied!");
9045         return;
9046     }
9047     if (GetUserIdByCallingUid() != currentUserId_) {
9048         TLOGE(WmsLogTag::DMS, "not currentuser, calling uid:%{public}d, current uid:%{public}d",
9049             GetUserIdByCallingUid(), currentUserId_);
9050         return;
9051     }
9052     auto screenSession = GetScreenSession(screenId);
9053     if (screenSession == nullptr) {
9054         TLOGE(WmsLogTag::DMS, "can not get default screen now");
9055         return;
9056     }
9057     if (!screenSession->UpdateAvailableArea(area)) {
9058         return;
9059     }
9060     if (g_isPcDevice) {
9061         {
9062             std::unique_lock<std::mutex> lock(displayAddMutex_);
9063             if (needWaitAvailableArea_) {
9064                 TLOGI(WmsLogTag::DMS, "need notify add display.");
9065                 displayAddCV_.notify_all();
9066                 needWaitAvailableArea_ = false;
9067             }
9068         }
9069         sptr<ScreenSession> physicalScreen = GetPhysicalScreenSession(screenSession->GetRSScreenId());
9070         if (physicalScreen) {
9071             physicalScreen->UpdateAvailableArea(area);
9072         }
9073     }
9074     NotifyAvailableAreaChanged(area, screenId);
9075 }
9076 
UpdateSuperFoldAvailableArea(ScreenId screenId,DMRect bArea,DMRect cArea)9077 void ScreenSessionManager::UpdateSuperFoldAvailableArea(ScreenId screenId, DMRect bArea, DMRect cArea)
9078 {
9079     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9080         TLOGE(WmsLogTag::DMS, "update super fold available area permission denied!");
9081         return;
9082     }
9083 
9084     auto screenSession = GetScreenSession(screenId);
9085     if (screenSession == nullptr) {
9086         TLOGE(WmsLogTag::DMS, "can not get default screen now");
9087         return;
9088     }
9089     if (screenSession->UpdateAvailableArea(bArea)) {
9090         if (g_isPcDevice) {
9091             sptr<ScreenSession> physicalScreen = GetPhysicalScreenSession(screenSession->GetRSScreenId());
9092             if (physicalScreen) {
9093                 physicalScreen->UpdateAvailableArea(bArea);
9094             }
9095         }
9096         NotifyAvailableAreaChanged(bArea, screenId);
9097         NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
9098             DisplayChangeEvent::SUPER_FOLD_AVAILABLE_AREA_UPDATE);
9099     }
9100     if (!screenSession->GetIsFakeInUse()) {
9101         TLOGE(WmsLogTag::DMS, "fake screen session is not in use");
9102         return;
9103     }
9104     auto fakeScreenSession = screenSession->GetFakeScreenSession();
9105     if (fakeScreenSession == nullptr) {
9106         TLOGE(WmsLogTag::DMS, "can not get fake screen now");
9107         return;
9108     }
9109     if (fakeScreenSession->UpdateAvailableArea(cArea) && cArea.width_ > 0) {
9110         NotifyAvailableAreaChanged(cArea, fakeScreenSession->GetScreenId());
9111         NotifyDisplayChanged(fakeScreenSession->ConvertToDisplayInfo(),
9112             DisplayChangeEvent::SUPER_FOLD_AVAILABLE_AREA_UPDATE);
9113     }
9114 }
9115 
UpdateSuperFoldExpandAvailableArea(ScreenId screenId,DMRect area)9116 void ScreenSessionManager::UpdateSuperFoldExpandAvailableArea(ScreenId screenId, DMRect area)
9117 {
9118     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9119         TLOGE(WmsLogTag::DMS, "update super fold available area permission denied!");
9120         return;
9121     }
9122 
9123     auto screenSession = GetScreenSession(screenId);
9124     if (screenSession == nullptr) {
9125         TLOGE(WmsLogTag::DMS, "can not get default screen now");
9126         return;
9127     }
9128     if (screenSession->UpdateExpandAvailableArea(area)) {
9129         TLOGI(WmsLogTag::DMS,
9130             "ExpandAvailableArea x: %{public}d, y: %{public}d, width: %{public}d, height: %{public}d",
9131             area.posX_, area.posY_, area.width_, area.height_);
9132     }
9133     if (g_isPcDevice) {
9134         sptr<ScreenSession> physicalScreen = GetPhysicalScreenSession(screenSession->GetRSScreenId());
9135         if (physicalScreen) {
9136             physicalScreen->UpdateExpandAvailableArea(area);
9137         }
9138     }
9139 }
9140 
NotifyFoldToExpandCompletion(bool foldToExpand)9141 void ScreenSessionManager::NotifyFoldToExpandCompletion(bool foldToExpand)
9142 {
9143 #ifdef FOLD_ABILITY_ENABLE
9144     TLOGI(WmsLogTag::DMS, "ENTER");
9145     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9146         TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
9147             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
9148         return;
9149     }
9150     if (!FoldScreenStateInternel::IsDualDisplayFoldDevice() &&
9151         !FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
9152         !FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
9153         SetDisplayNodeScreenId(SCREEN_ID_FULL, foldToExpand ? SCREEN_ID_FULL : SCREEN_ID_MAIN);
9154     }
9155     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
9156         SetDisplayNodeScreenId(SCREEN_ID_FULL, SCREEN_ID_FULL);
9157     }
9158     /* Avoid fold to expand process queues */
9159     if (foldScreenController_ != nullptr) {
9160         foldScreenController_->SetdisplayModeChangeStatus(false);
9161     }
9162     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
9163     if (screenSession == nullptr) {
9164         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
9165         return;
9166     }
9167     screenSession->UpdateRotationAfterBoot(foldToExpand);
9168 #endif
9169 }
9170 
RecordEventFromScb(std::string description,bool needRecordEvent)9171 void ScreenSessionManager::RecordEventFromScb(std::string description, bool needRecordEvent)
9172 {
9173     TLOGD(WmsLogTag::DMS, "%{public}s", description.c_str());
9174     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9175         TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
9176             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
9177         return;
9178     }
9179     if (needRecordEvent) {
9180         screenEventTracker_.RecordEvent(description);
9181     }
9182 }
9183 
CheckAndSendHiSysEvent(const std::string & eventName,const std::string & bundleName) const9184 void ScreenSessionManager::CheckAndSendHiSysEvent(const std::string& eventName, const std::string& bundleName) const
9185 {
9186     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CheckAndSendHiSysEvent");
9187     if (eventName != "CREATE_VIRTUAL_SCREEN") {
9188         if (!Permission::CheckIsCallingBundleName(bundleName)) {
9189             TLOGD(WmsLogTag::DMS, "BundleName not in whitelist!");
9190             return;
9191         }
9192     }
9193     int32_t eventRet = HiSysEventWrite(
9194         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
9195         eventName, // CREATE_VIRTUAL_SCREEN, GET_DISPLAY_SNAPSHOT
9196         OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,
9197         "PID", getpid(),
9198         "UID", getuid());
9199     TLOGI(WmsLogTag::DMS, "%{public}s: Write HiSysEvent ret:%{public}d", eventName.c_str(), eventRet);
9200 }
9201 
ProxyForFreeze(const std::set<int32_t> & pidList,bool isProxy)9202 DMError ScreenSessionManager::ProxyForFreeze(const std::set<int32_t>& pidList, bool isProxy)
9203 {
9204     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9205         TLOGE(WmsLogTag::DMS, "permission denied!");
9206         return DMError::DM_ERROR_NOT_SYSTEM_APP;
9207     }
9208     {
9209         std::lock_guard<std::mutex> lock(freezedPidListMutex_);
9210         for (auto pid : pidList) {
9211             if (isProxy) {
9212                 freezedPidList_.insert(pid);
9213             } else {
9214                 freezedPidList_.erase(pid); // set删除不存在的元素不会引发异常
9215             }
9216         }
9217     }
9218     if (isProxy) {
9219         return DMError::DM_OK;
9220     }
9221 
9222     // 进程解冻时刷新一次displaychange
9223     sptr<ScreenSession> screenSession = GetScreenSession(GetDefaultScreenId());
9224     if (!screenSession) {
9225         return DMError::DM_ERROR_NULLPTR;
9226     }
9227     auto task = [=] {
9228         NotifyUnfreezed(pidList, screenSession);
9229     };
9230     taskScheduler_->PostAsyncTask(task, "ProxyForUnFreeze NotifyDisplayChanged");
9231     return DMError::DM_OK;
9232 }
9233 
NotifyUnfreezedAgents(const int32_t & pid,const std::set<int32_t> & unfreezedPidList,const std::set<DisplayManagerAgentType> & pidAgentTypes,const sptr<ScreenSession> & screenSession)9234 void ScreenSessionManager::NotifyUnfreezedAgents(const int32_t& pid, const std::set<int32_t>& unfreezedPidList,
9235     const std::set<DisplayManagerAgentType>& pidAgentTypes, const sptr<ScreenSession>& screenSession)
9236 {
9237     bool isAgentTypeNotify = false;
9238     for (auto agentType : pidAgentTypes) {
9239         auto agents = dmAgentContainer_.GetAgentsByType(agentType);
9240         for (auto agent : agents) {
9241             int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
9242             if (agentPid != pid || unfreezedPidList.count(pid) == 0) {
9243                 continue;
9244             }
9245             isAgentTypeNotify = true;
9246             if (agentType == DisplayManagerAgentType::DISPLAY_EVENT_LISTENER) {
9247                 agent->OnDisplayChange(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_UNFREEZED);
9248             } else if (agentType == DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER) {
9249                 FoldDisplayMode displayMode = GetFoldDisplayMode();
9250                 agent->NotifyDisplayModeChanged(displayMode);
9251             } else if (agentType == DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER) {
9252                 FoldStatus foldStatus = GetFoldStatus();
9253                 agent->NotifyFoldStatusChanged(foldStatus);
9254             } else if (agentType == DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER) {
9255                 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
9256                 agent->NotifyFoldAngleChanged(lastFoldAngles_);
9257             } else if (agentType == DisplayManagerAgentType::SCREEN_EVENT_LISTENER) {
9258                 auto displayInfo = screenSession->ConvertToDisplayInfo();
9259                 auto screenInfo = GetScreenInfoById(displayInfo->GetScreenId());
9260                 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
9261                 agent->OnScreenChange(screenInfo, lastScreenChangeEvent_);
9262             } else if (agentType ==  DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER) {
9263                 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
9264                 agent->NotifyDisplayChangeInfoChanged(lastDisplayChangeInfo_);
9265             } else if (agentType ==  DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER) {
9266                 auto area = screenSession->GetAvailableArea();
9267                 auto displayId = screenSession->ConvertToDisplayInfo()->GetDisplayId();
9268                 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
9269                 agent->NotifyAvailableAreaChanged(area, displayId);
9270             } else {
9271                 isAgentTypeNotify = false;
9272                 TLOGI(WmsLogTag::DMS, "Unknown agentType.");
9273             }
9274         }
9275         if (isAgentTypeNotify) {
9276             pidAgentTypeMap_[pid].erase(agentType);
9277         }
9278     }
9279 }
9280 
NotifyUnfreezed(const std::set<int32_t> & unfreezedPidList,const sptr<ScreenSession> & screenSession)9281 void ScreenSessionManager::NotifyUnfreezed(const std::set<int32_t>& unfreezedPidList,
9282     const sptr<ScreenSession>& screenSession)
9283 {
9284     std::lock_guard<std::mutex> lock(freezedPidListMutex_);
9285     std::ostringstream oss;
9286     oss << "pid,type:";
9287     for (auto iter = pidAgentTypeMap_.begin(); iter != pidAgentTypeMap_.end();) {
9288         int32_t pid = iter->first;
9289         auto pidAgentTypes = iter->second;
9290         NotifyUnfreezedAgents(pid, unfreezedPidList, pidAgentTypes, screenSession);
9291         if (pidAgentTypeMap_[pid].empty()) {
9292             iter = pidAgentTypeMap_.erase(iter);
9293         } else {
9294             iter++;
9295         }
9296         oss << pid << ",";
9297         for (auto type : pidAgentTypes) {
9298             oss << static_cast<int32_t>(type) << " ";
9299         }
9300         oss << "|";
9301     }
9302     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
9303 }
9304 
ResetAllFreezeStatus()9305 DMError ScreenSessionManager::ResetAllFreezeStatus()
9306 {
9307     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9308         TLOGE(WmsLogTag::DMS, "permission denied!");
9309         return DMError::DM_ERROR_NOT_SYSTEM_APP;
9310     }
9311     std::lock_guard<std::mutex> lock(freezedPidListMutex_);
9312     freezedPidList_.clear();
9313     pidAgentTypeMap_.clear();
9314     TLOGI(WmsLogTag::DMS, "freezedPidList_ has been clear.");
9315     return DMError::DM_OK;
9316 }
9317 
GetDeviceScreenConfig()9318 DeviceScreenConfig ScreenSessionManager::GetDeviceScreenConfig()
9319 {
9320     DmsXcollie dmsXcollie("DMS:GetDeviceScreenConfig", XCOLLIE_TIMEOUT_10S);
9321     return deviceScreenConfig_;
9322 }
9323 
RegisterApplicationStateObserver()9324 void ScreenSessionManager::RegisterApplicationStateObserver()
9325 {
9326 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
9327     std::string identify = IPCSkeleton::ResetCallingIdentity();
9328     if (!FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
9329         FoldScreenSensorManager::GetInstance().RegisterApplicationStateObserver();
9330     }
9331     IPCSkeleton::SetCallingIdentity(identify);
9332 #endif
9333 }
9334 
SetVirtualScreenBlackList(ScreenId screenId,std::vector<uint64_t> & windowIdList,std::vector<uint64_t> surfaceIdList,std::vector<uint8_t> typeBlackList)9335 void ScreenSessionManager::SetVirtualScreenBlackList(ScreenId screenId, std::vector<uint64_t>& windowIdList,
9336     std::vector<uint64_t> surfaceIdList, std::vector<uint8_t> typeBlackList)
9337 {
9338     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9339         TLOGE(WmsLogTag::DMS, "permission denied!");
9340         return;
9341     }
9342     TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64, screenId);
9343     ScreenId rsScreenId = SCREEN_ID_INVALID;
9344     if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
9345         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
9346         return;
9347     }
9348     auto clientProxy = GetClientProxy();
9349     if (!clientProxy) {
9350         TLOGE(WmsLogTag::DMS, "clientProxy_ is nullptr");
9351         return;
9352     }
9353     if (windowIdList.empty()) {
9354         TLOGI(WmsLogTag::DMS, "WindowIdList is empty");
9355         clientProxy->OnSetSurfaceNodeIdsChanged(rsScreenId, surfaceIdList);
9356         rsInterface_.SetVirtualScreenTypeBlackList(rsScreenId, typeBlackList);
9357         return;
9358     }
9359     std::vector<uint64_t> surfaceNodeIdsToRS;
9360     clientProxy->OnGetSurfaceNodeIdsFromMissionIdsChanged(windowIdList, surfaceNodeIdsToRS, true);
9361     if (!surfaceIdList.empty()) {
9362         for (auto surfaceId : surfaceIdList) {
9363             auto it = std::find(surfaceNodeIdsToRS.begin(), surfaceNodeIdsToRS.end(), surfaceId);
9364             if (it != surfaceNodeIdsToRS.end()) {
9365                 continue;
9366             }
9367             surfaceNodeIdsToRS.push_back(surfaceId);
9368         }
9369     }
9370     std::ostringstream oss;
9371     oss << "surfaceNodeIdsToRS[" << rsScreenId << "]: ";
9372     for (auto val : surfaceNodeIdsToRS) {
9373         oss << val << " ";
9374     }
9375     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
9376     rsInterface_.SetVirtualScreenTypeBlackList(rsScreenId, typeBlackList);
9377     clientProxy->OnSetSurfaceNodeIdsChanged(rsScreenId, surfaceNodeIdsToRS);
9378 }
9379 
SetVirtualDisplayMuteFlag(ScreenId screenId,bool muteFlag)9380 void ScreenSessionManager::SetVirtualDisplayMuteFlag(ScreenId screenId, bool muteFlag)
9381 {
9382     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9383         TLOGE(WmsLogTag::DMS, "permission denied!");
9384         return;
9385     }
9386     sptr<ScreenSession> virtualScreenSession = GetScreenSession(screenId);
9387     if (!virtualScreenSession) {
9388         TLOGE(WmsLogTag::DMS, "ScreenSession is null");
9389         return;
9390     }
9391     std::shared_ptr<RSDisplayNode> virtualDisplayNode = virtualScreenSession->GetDisplayNode();
9392     if (virtualDisplayNode) {
9393         virtualDisplayNode->SetVirtualScreenMuteStatus(muteFlag);
9394     } else {
9395         TLOGE(WmsLogTag::DMS, "DisplayNode is null");
9396         return;
9397     }
9398     TLOGI(WmsLogTag::DMS, "flush displayNode mute");
9399     RSTransactionAdapter::FlushImplicitTransaction(virtualScreenSession->GetRSUIContext());
9400     TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " muteFlag: %{public}d", screenId, muteFlag);
9401 }
9402 
DisablePowerOffRenderControl(ScreenId screenId)9403 void ScreenSessionManager::DisablePowerOffRenderControl(ScreenId screenId)
9404 {
9405     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9406         TLOGE(WmsLogTag::DMS, "permission denied!");
9407         return;
9408     }
9409     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64, screenId);
9410     ScreenId rsScreenId = SCREEN_ID_INVALID;
9411     if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
9412         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
9413         return;
9414     }
9415     rsInterface_.DisablePowerOffRenderControl(rsScreenId);
9416 }
9417 
ReportFoldStatusToScb(std::vector<std::string> & screenFoldInfo)9418 void ScreenSessionManager::ReportFoldStatusToScb(std::vector<std::string>& screenFoldInfo)
9419 {
9420     auto clientProxy = GetClientProxy();
9421     if (clientProxy) {
9422         auto screenInfo = GetDefaultScreenSession();
9423         int32_t rotation = -1;
9424         if (screenInfo != nullptr) {
9425             rotation = static_cast<int32_t>(screenInfo->GetRotation());
9426         }
9427         screenFoldInfo.emplace_back(std::to_string(rotation));
9428 
9429         clientProxy->OnFoldStatusChangedReportUE(screenFoldInfo);
9430     }
9431 }
9432 
GetAllDisplayPhysicalResolution()9433 std::vector<DisplayPhysicalResolution> ScreenSessionManager::GetAllDisplayPhysicalResolution()
9434 {
9435     std::lock_guard<std::mutex> lock(allDisplayPhysicalResolutionMutex_);
9436     if (allDisplayPhysicalResolution_.empty()) {
9437         sptr<ScreenSession> defaultScreen = GetDefaultScreenSession();
9438         if (defaultScreen == nullptr) {
9439             TLOGE(WmsLogTag::DMS, "default screen null");
9440             return allDisplayPhysicalResolution_;
9441         }
9442         ScreenProperty defaultScreenProperty = defaultScreen->GetScreenProperty();
9443         DisplayPhysicalResolution defaultSize;
9444         defaultSize.foldDisplayMode_ = FoldDisplayMode::UNKNOWN;
9445         defaultSize.physicalWidth_ = defaultScreenProperty.GetPhyBounds().rect_.width_;
9446         defaultSize.physicalHeight_ = defaultScreenProperty.GetPhyBounds().rect_.height_;
9447         allDisplayPhysicalResolution_.emplace_back(defaultSize);
9448     }
9449     for (auto& info : allDisplayPhysicalResolution_) {
9450         if (info.foldDisplayMode_ == FoldDisplayMode::GLOBAL_FULL) {
9451             info.foldDisplayMode_ = FoldDisplayMode::FULL;
9452             break;
9453         }
9454     }
9455     return allDisplayPhysicalResolution_;
9456 }
9457 
InitSecondaryDisplayPhysicalParams()9458 void ScreenSessionManager::InitSecondaryDisplayPhysicalParams()
9459 {
9460     std::vector<DisplayPhysicalResolution> resolutions = ScreenSceneConfig::GetAllDisplayPhysicalConfig();
9461     for (auto &resolution : resolutions) {
9462         if (FoldDisplayMode::MAIN == resolution.foldDisplayMode_) {
9463             screenParams_.push_back(resolution.physicalWidth_);
9464         } else if (FoldDisplayMode::FULL == resolution.foldDisplayMode_) {
9465             screenParams_.push_back(resolution.physicalWidth_);
9466         } else if (FoldDisplayMode::GLOBAL_FULL == resolution.foldDisplayMode_) {
9467             screenParams_.push_back(resolution.physicalWidth_);
9468             screenParams_.push_back(resolution.physicalHeight_);
9469         } else {
9470             TLOGW(WmsLogTag::DMS, "unKnown displayMode");
9471         }
9472     }
9473     if (screenParams_.size() < STATUS_PARAM_VALID_INDEX) {
9474         TLOGE(WmsLogTag::DMS, "invalid param num");
9475         return;
9476     }
9477     screenParams_.push_back(screenParams_[GLOBAL_FULL_STATUS_WIDTH_INDEX] - screenParams_[FULL_STATUS_WIDTH_INDEX]);
9478     TLOGI(WmsLogTag::DMS,
9479         "PhysicalResolution : mainStatusWidth_= %{public}d, fullStatusWidth_= %{public}d, gloablFullStatusWidth_="
9480         "%{public}d, screenHeight_= %{public}d",
9481           screenParams_[MAIN_STATUS_WIDTH_INDEX], screenParams_[FULL_STATUS_WIDTH_INDEX],
9482           screenParams_[GLOBAL_FULL_STATUS_WIDTH_INDEX], screenParams_[SCREEN_HEIGHT_INDEX]);
9483 }
9484 
GetCapabilityJson(FoldStatus foldStatus,FoldDisplayMode displayMode,std::vector<std::string> rotation,std::vector<std::string> orientation)9485 nlohmann::ordered_json ScreenSessionManager::GetCapabilityJson(FoldStatus foldStatus, FoldDisplayMode displayMode,
9486     std::vector<std::string> rotation, std::vector<std::string> orientation)
9487 {
9488     nlohmann::ordered_json capabilityInfo;
9489     capabilityInfo["foldStatus"] = std::to_string(static_cast<int32_t>(foldStatus));
9490     capabilityInfo["foldDisplayMode"] = std::to_string(static_cast<int32_t>(displayMode));
9491     capabilityInfo["rotation"] = rotation;
9492     capabilityInfo["orientation"] = orientation;
9493     return capabilityInfo;
9494 }
9495 
GetDisplayCapability(std::string & capabilitInfo)9496 DMError ScreenSessionManager::GetDisplayCapability(std::string& capabilitInfo)
9497 {
9498     if (g_foldScreenFlag) {
9499         if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
9500             return GetSecondaryDisplayCapability(capabilitInfo);
9501         }
9502         return GetFoldableDeviceCapability(capabilitInfo);
9503     }
9504     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
9505         return GetSuperFoldCapability(capabilitInfo);
9506     }
9507 
9508     std::vector<std::string> orientation = ORIENTATION_DEFAULT;
9509     if (g_isPcDevice && !FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
9510         orientation = {"1", "0", "3", "2"};
9511     }
9512     nlohmann::ordered_json jsonDisplayCapabilityList;
9513     jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
9514     nlohmann::ordered_json capabilityInfo = GetCapabilityJson(FoldStatus::UNKNOWN, FoldDisplayMode::UNKNOWN,
9515         ROTATION_DEFAULT, orientation);
9516     jsonDisplayCapabilityList["capability"].push_back(std::move(capabilityInfo));
9517 
9518     capabilitInfo = jsonDisplayCapabilityList.dump();
9519     return DMError::DM_OK;
9520 }
9521 
GetSecondaryDisplayCapability(std::string & capabilitInfo)9522 DMError ScreenSessionManager::GetSecondaryDisplayCapability(std::string& capabilitInfo)
9523 {
9524     nlohmann::ordered_json jsonDisplayCapabilityList;
9525     jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
9526 
9527     nlohmann::ordered_json fCapabilityInfo = GetCapabilityJson(FoldStatus::FOLDED, FoldDisplayMode::MAIN,
9528         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9529     jsonDisplayCapabilityList["capability"].push_back(std::move(fCapabilityInfo));
9530     nlohmann::ordered_json nCapability = GetCapabilityJson(FoldStatus::FOLD_STATE_FOLDED_WITH_SECOND_EXPAND,
9531         FoldDisplayMode::MAIN, ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9532     jsonDisplayCapabilityList["capability"].push_back(std::move(nCapability));
9533     nlohmann::ordered_json mCapabilityInfo = GetCapabilityJson(FoldStatus::EXPAND, FoldDisplayMode::FULL,
9534         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9535     jsonDisplayCapabilityList["capability"].push_back(std::move(mCapabilityInfo));
9536     std::vector<std::string> orientation = {"3", "0", "1", "2"};
9537     nlohmann::ordered_json gCapability = GetCapabilityJson(FoldStatus::FOLD_STATE_EXPAND_WITH_SECOND_EXPAND,
9538         FoldDisplayMode::FULL, ROTATION_DEFAULT, orientation);
9539     jsonDisplayCapabilityList["capability"].push_back(std::move(gCapability));
9540 #ifdef FOLD_ABILITY_ENABLE
9541     if (foldScreenController_) {
9542         nlohmann::ordered_json foldCreaseRegion = foldScreenController_->GetFoldCreaseRegionJson();
9543         jsonDisplayCapabilityList["allCreaseRegion"] = foldCreaseRegion;
9544     }
9545 #endif
9546 
9547     capabilitInfo = jsonDisplayCapabilityList.dump();
9548     return DMError::DM_OK;
9549 }
9550 
GetFoldableDeviceCapability(std::string & capabilitInfo)9551 DMError ScreenSessionManager::GetFoldableDeviceCapability(std::string& capabilitInfo)
9552 {
9553     nlohmann::ordered_json jsonDisplayCapabilityList;
9554     jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
9555     FoldStatus expandStatus = FoldStatus::EXPAND;
9556     FoldStatus foldStatus = FoldStatus::FOLDED;
9557     FoldDisplayMode expandDisplayMode = FoldDisplayMode::FULL;
9558     FoldDisplayMode foldDisplayMode = FoldDisplayMode::MAIN;
9559     if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
9560         expandDisplayMode = FoldDisplayMode::MAIN;
9561         foldDisplayMode = FoldDisplayMode::SUB;
9562     }
9563     nlohmann::ordered_json expandCapabilityInfo = GetCapabilityJson(expandStatus, expandDisplayMode,
9564         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9565     jsonDisplayCapabilityList["capability"].push_back(std::move(expandCapabilityInfo));
9566     nlohmann::ordered_json foldCapabilityInfo = GetCapabilityJson(foldStatus, foldDisplayMode,
9567         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9568     jsonDisplayCapabilityList["capability"].push_back(std::move(foldCapabilityInfo));
9569 #ifdef FOLD_ABILITY_ENABLE
9570     if (foldScreenController_) {
9571         nlohmann::ordered_json foldCreaseRegion = foldScreenController_->GetFoldCreaseRegionJson();
9572         jsonDisplayCapabilityList["allCreaseRegion"] = foldCreaseRegion;
9573     }
9574 #endif
9575 
9576     capabilitInfo = jsonDisplayCapabilityList.dump();
9577     return DMError::DM_OK;
9578 }
9579 
GetSuperFoldCapability(std::string & capabilitInfo)9580 DMError ScreenSessionManager::GetSuperFoldCapability(std::string& capabilitInfo)
9581 {
9582     nlohmann::ordered_json jsonDisplayCapabilityList;
9583     jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
9584 
9585     nlohmann::ordered_json expandCapabilityInfo = GetCapabilityJson(FoldStatus::EXPAND, FoldDisplayMode::UNKNOWN,
9586         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9587     jsonDisplayCapabilityList["capability"].push_back(std::move(expandCapabilityInfo));
9588     nlohmann::ordered_json foldCapabilityInfo = GetCapabilityJson(FoldStatus::FOLDED, FoldDisplayMode::UNKNOWN,
9589         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9590     jsonDisplayCapabilityList["capability"].push_back(std::move(foldCapabilityInfo));
9591     nlohmann::ordered_json halfFoldCapabilityInfo = GetCapabilityJson(FoldStatus::HALF_FOLD, FoldDisplayMode::UNKNOWN,
9592         ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9593     jsonDisplayCapabilityList["capability"].push_back(std::move(halfFoldCapabilityInfo));
9594 #ifdef FOLD_ABILITY_ENABLE
9595     nlohmann::ordered_json foldCreaseRegion = SuperFoldStateManager::GetInstance().GetFoldCreaseRegionJson();
9596     jsonDisplayCapabilityList["allCreaseRegion"] = foldCreaseRegion;
9597 #endif
9598 
9599     capabilitInfo = jsonDisplayCapabilityList.dump();
9600     return DMError::DM_OK;
9601 }
9602 
SetVirtualScreenStatus(ScreenId screenId,VirtualScreenStatus screenStatus)9603 bool ScreenSessionManager::SetVirtualScreenStatus(ScreenId screenId, VirtualScreenStatus screenStatus)
9604 {
9605     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9606         TLOGE(WmsLogTag::DMS, "permission denied!");
9607         return false;
9608     }
9609     TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 " screenStatus: %{public}d",
9610         screenId, static_cast<int32_t>(screenStatus));
9611     ScreenId rsScreenId = SCREEN_ID_INVALID;
9612     if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
9613         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
9614         return false;
9615     }
9616 
9617     return rsInterface_.SetVirtualScreenStatus(rsScreenId, screenStatus);
9618 }
9619 
GetOrCreateFakeScreenSession(sptr<ScreenSession> screenSession)9620 sptr<ScreenSession> ScreenSessionManager::GetOrCreateFakeScreenSession(sptr<ScreenSession> screenSession)
9621 {
9622     sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
9623     if (fakeScreenSession != nullptr) {
9624         TLOGI(WmsLogTag::DMS, "fake screen session has exist");
9625         return fakeScreenSession;
9626     }
9627     ScreenProperty screenProperty = screenSession->GetScreenProperty();
9628     ScreenSessionConfig config = {
9629         .screenId = SCREEN_ID_FAKE,
9630         .defaultScreenId = SCREEN_ID_INVALID,
9631         .property = screenProperty,
9632     };
9633     fakeScreenSession =
9634         new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
9635     if (fakeScreenSession == nullptr) {
9636         return nullptr;
9637     }
9638     return fakeScreenSession;
9639 }
9640 
InitFakeScreenSession(sptr<ScreenSession> screenSession)9641 void ScreenSessionManager::InitFakeScreenSession(sptr<ScreenSession> screenSession)
9642 {
9643     if (screenSession == nullptr) {
9644         TLOGE(WmsLogTag::DMS, "screen session is null");
9645         return;
9646     }
9647     sptr<ScreenSession> fakeScreenSession = GetOrCreateFakeScreenSession(screenSession);
9648     if (fakeScreenSession == nullptr) {
9649         TLOGE(WmsLogTag::DMS, "get or create fake screen session failed");
9650         return;
9651     }
9652     ScreenProperty screenProperty = screenSession->GetScreenProperty();
9653     uint32_t screenWidth = screenProperty.GetBounds().rect_.GetWidth();
9654     uint32_t screenHeight = screenProperty.GetBounds().rect_.GetHeight();
9655     uint32_t fakeScreenHeight = screenHeight / HALF_SCREEN_PARAM;
9656     DMRect creaseRect = screenProperty.GetCreaseRect();
9657     if (creaseRect.height_ > 0) {
9658         fakeScreenHeight = screenHeight - (static_cast<uint32_t>(creaseRect.posY_) + creaseRect.height_);
9659     }
9660     fakeScreenSession->SetIsFakeSession(true);
9661     fakeScreenSession->UpdatePropertyByResolution(screenWidth, fakeScreenHeight);
9662     fakeScreenSession->SetXYPosition(0, DISPLAY_B_HEIGHT);
9663     fakeScreenSession->SetScreenCombination(ScreenCombination::SCREEN_EXTEND);
9664     screenSession->UpdatePropertyByFakeBounds(screenWidth, fakeScreenHeight);
9665     screenSession->SetFakeScreenSession(fakeScreenSession);
9666     screenSession->SetIsFakeInUse(true);
9667 }
9668 
SetVirtualScreenSecurityExemption(ScreenId screenId,uint32_t pid,std::vector<uint64_t> & windowIdList)9669 DMError ScreenSessionManager::SetVirtualScreenSecurityExemption(ScreenId screenId, uint32_t pid,
9670     std::vector<uint64_t>& windowIdList)
9671 {
9672     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9673         TLOGE(WmsLogTag::DMS, "permission denied!");
9674         return DMError::DM_ERROR_INVALID_CALLING;
9675     }
9676     std::vector<uint64_t> surfaceNodeIds;
9677     if (!windowIdList.empty()) {
9678         MockSessionManagerService::GetInstance().GetProcessSurfaceNodeIdByPersistentId(
9679             pid, windowIdList, surfaceNodeIds);
9680     }
9681     auto rsId = screenIdManager_.ConvertToRsScreenId(screenId);
9682     auto ret = rsInterface_.SetVirtualScreenSecurityExemptionList(rsId, surfaceNodeIds);
9683 
9684     std::ostringstream oss;
9685     oss << "screenId:" << screenId << ", rsID: " << rsId << ", pid: " << pid
9686         << ", winListSize:[ ";
9687     for (auto val : windowIdList) {
9688         oss << val << " ";
9689     }
9690     oss << "]" << ", surfaceListSize:[ ";
9691     for (auto val : surfaceNodeIds) {
9692         oss << val << " ";
9693     }
9694     oss << "]" << ", ret: " << ret;
9695     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
9696     return ret == 0 ? DMError::DM_OK : DMError::DM_ERROR_UNKNOWN;
9697 }
9698 
SetDefaultScreenId(ScreenId defaultScreenId)9699 void ScreenSessionManager::SetDefaultScreenId(ScreenId defaultScreenId)
9700 {
9701     defaultScreenId_ = defaultScreenId;
9702 }
9703 
GetClientProxy()9704 sptr<IScreenSessionManagerClient> ScreenSessionManager::GetClientProxy()
9705 {
9706     std::lock_guard<std::mutex> lock(clientProxyMutex_);
9707     return clientProxy_;
9708 }
9709 
SetClientProxy(const sptr<IScreenSessionManagerClient> & client)9710 void ScreenSessionManager::SetClientProxy(const sptr<IScreenSessionManagerClient>& client)
9711 {
9712     std::lock_guard<std::mutex> lock(clientProxyMutex_);
9713     clientProxy_ = client;
9714 }
9715 
SetMultiScreenMode(ScreenId mainScreenId,ScreenId secondaryScreenId,MultiScreenMode screenMode)9716 DMError ScreenSessionManager::SetMultiScreenMode(ScreenId mainScreenId, ScreenId secondaryScreenId,
9717     MultiScreenMode screenMode)
9718 {
9719 #ifdef WM_MULTI_SCREEN_ENABLE
9720     TLOGW(WmsLogTag::DMS, "mainScreenId:%{public}" PRIu64",secondaryScreenId:%{public}" PRIu64",Mode:%{public}u",
9721         mainScreenId, secondaryScreenId, screenMode);
9722     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9723         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
9724             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
9725         return DMError::DM_ERROR_NOT_SYSTEM_APP;
9726     }
9727     if (IsPhysicalExtendScreenInUse(mainScreenId, secondaryScreenId) == DMError::DM_OK) {
9728         return DMError::DM_ERROR_INVALID_MODE_ID;
9729     }
9730     CreateExtendVirtualScreen(secondaryScreenId);
9731     if (mainScreenId == secondaryScreenId && mainScreenId == SCREEN_ID_OUTER_ONLY) {
9732         TLOGW(WmsLogTag::DMS, "set to outer only mode.");
9733         SetIsOuterOnlyMode(true);
9734         MultiScreenModeChange(mainScreenId, mainScreenId, "off");
9735         return DMError::DM_OK;
9736     }
9737     if (GetIsOuterOnlyMode()) {
9738         SetIsOuterOnlyMode(false);
9739         TLOGI(WmsLogTag::DMS, "exit outer only mode.");
9740         ExitOuterOnlyMode(mainScreenId, secondaryScreenId, screenMode);
9741         return DMError::DM_OK;
9742     }
9743     SetMultiScreenModeInner(mainScreenId, secondaryScreenId, screenMode);
9744     auto combination = screenMode == MultiScreenMode::SCREEN_MIRROR ?
9745         ScreenCombination::SCREEN_MIRROR : ScreenCombination::SCREEN_EXPAND;
9746     SetScreenCastInfo(secondaryScreenId, mainScreenId, combination);
9747     NotifyScreenModeChange();
9748 #endif
9749     return DMError::DM_OK;
9750 }
9751 
SetMultiScreenModeInner(ScreenId mainScreenId,ScreenId secondaryScreenId,MultiScreenMode screenMode)9752 void ScreenSessionManager::SetMultiScreenModeInner(ScreenId mainScreenId, ScreenId secondaryScreenId,
9753     MultiScreenMode screenMode)
9754 {
9755     TLOGI(WmsLogTag::DMS, "enter");
9756     if (screenMode == MultiScreenMode::SCREEN_MIRROR) {
9757         MultiScreenModeChange(mainScreenId, secondaryScreenId, "mirror");
9758         SetExtendedScreenFallbackPlan(secondaryScreenId);
9759         sptr<ScreenSession> screenSession = GetScreenSession(secondaryScreenId);
9760         if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
9761             MultiScreenPositionOptions defaultOptions = { GetDefaultScreenId(), 0, 0 };
9762             SetRelativePositionForDisconnect(defaultOptions);
9763             NotifyCaptureStatusChanged(true);
9764         }
9765     } else if (screenMode == MultiScreenMode::SCREEN_EXTEND) {
9766         bool lastScreenMirror = false;
9767         sptr<ScreenSession> screenSession = GetScreenSession(secondaryScreenId);
9768         if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
9769             lastScreenMirror = true;
9770         }
9771         MultiScreenModeChange(mainScreenId, secondaryScreenId, "extend");
9772         SetExtendedScreenFallbackPlan(secondaryScreenId);
9773         if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND &&
9774             lastScreenMirror) {
9775             NotifyCaptureStatusChanged(false);
9776         }
9777     } else {
9778         TLOGE(WmsLogTag::DMS, "operate mode error");
9779     }
9780 }
9781 
ExitOuterOnlyMode(ScreenId mainScreenId,ScreenId secondaryScreenId,MultiScreenMode screenMode)9782 void ScreenSessionManager::ExitOuterOnlyMode(ScreenId mainScreenId, ScreenId secondaryScreenId,
9783     MultiScreenMode screenMode)
9784 {
9785 #ifdef WM_MULTI_SCREEN_ENABLE
9786     ScreenCombination innerCombination = ScreenCombination::SCREEN_MAIN;
9787     ScreenCombination externalCombination = ScreenCombination::SCREEN_EXTEND;
9788     sptr<ScreenSession> internalSession = GetInternalScreenSession();
9789     if (internalSession == nullptr) {
9790         TLOGE(WmsLogTag::DMS, "internalSession is nullptr");
9791         return;
9792     }
9793     ScreenCombination combination = ScreenCombination::SCREEN_EXTEND;
9794     if (screenMode == MultiScreenMode::SCREEN_MIRROR) {
9795         combination = ScreenCombination::SCREEN_MIRROR;
9796     }
9797     if (internalSession->GetRSScreenId() == mainScreenId) {
9798         innerCombination = ScreenCombination::SCREEN_MAIN;
9799         externalCombination = combination;
9800     } else if (internalSession->GetRSScreenId() == secondaryScreenId) {
9801         innerCombination = combination;
9802         externalCombination = ScreenCombination::SCREEN_MAIN;
9803     } else {
9804         TLOGE(WmsLogTag::DMS, "invalid param, use default mode.");
9805     }
9806     MultiScreenPowerChangeManager::GetInstance().SetInnerAndExternalCombination(innerCombination,
9807         externalCombination);
9808     MultiScreenModeChange(mainScreenId, mainScreenId, "on");
9809 #endif
9810 }
9811 
IsPhysicalExtendScreenInUse(ScreenId mainScreenId,ScreenId secondaryScreenId)9812 DMError ScreenSessionManager::IsPhysicalExtendScreenInUse(ScreenId mainScreenId, ScreenId secondaryScreenId)
9813 {
9814     TLOGI(WmsLogTag::DMS, "Enter");
9815     sptr<ScreenSession> mainScreenSession = GetScreenSessionByRsId(mainScreenId);
9816     sptr<ScreenSession> secondaryScreenSession = GetScreenSessionByRsId(secondaryScreenId);
9817     if (mainScreenSession == nullptr || secondaryScreenSession == nullptr) {
9818         TLOGE(WmsLogTag::DMS, "ScreenSession is null");
9819         return DMError::DM_ERROR_NULLPTR;
9820     }
9821     if (mainScreenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL ||
9822         secondaryScreenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
9823         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
9824         for (auto sessionIt : screenSessionMap_) {
9825             auto screenSession = sessionIt.second;
9826             if (screenSession == nullptr) {
9827                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
9828                 continue;
9829             }
9830             if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
9831                 (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR ||
9832                  screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND)) {
9833                 TLOGI(WmsLogTag::DMS, "physical extend screen in use screenid: %{public}" PRIu64,
9834                     screenSession->GetScreenId());
9835                 return DMError::DM_OK;
9836             }
9837         }
9838     }
9839     return DMError::DM_ERROR_UNKNOWN;
9840 }
9841 
CreateExtendVirtualScreen(ScreenId screenId)9842 void ScreenSessionManager::CreateExtendVirtualScreen(ScreenId screenId)
9843 {
9844     TLOGI(WmsLogTag::DMS, "Enter");
9845     sptr<ScreenSession> screenSession = GetScreenSessionByRsId(screenId);
9846     if (screenSession == nullptr) {
9847         TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
9848         return;
9849     }
9850     if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::VIRTUAL) {
9851         return;
9852     }
9853     if (screenSession->GetDisplayNode() == nullptr) {
9854         Rosen::RSDisplayNodeConfig rsConfig;
9855         ScreenId rsScreenId = screenSession->GetRSScreenId();
9856         rsConfig.screenId = rsScreenId;
9857         screenSession->CreateDisplayNode(rsConfig);
9858         screenSession->SetDisplayNodeScreenId(rsScreenId);
9859         screenSession->SetIsCurrentInUse(true);
9860         screenSession->SetIsExtend(true);
9861         screenSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
9862         screenSession->SetIsExtendVirtual(true);
9863         TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64", rsScreenId:%{public}" PRIu64"",
9864             screenId, rsScreenId);
9865     }
9866 }
9867 
SetMultiScreenRelativePosition(MultiScreenPositionOptions mainScreenOptions,MultiScreenPositionOptions secondScreenOption)9868 DMError ScreenSessionManager::SetMultiScreenRelativePosition(MultiScreenPositionOptions mainScreenOptions,
9869     MultiScreenPositionOptions secondScreenOption)
9870 {
9871 #ifdef WM_MULTI_SCREEN_ENABLE
9872     TLOGI(WmsLogTag::DMS,
9873         "mID:%{public}" PRIu64", X:%{public}u, Y:%{public}u,sID:%{public}" PRIu64", X:%{public}u, Y:%{public}u",
9874         mainScreenOptions.screenId_, mainScreenOptions.startX_, mainScreenOptions.startY_,
9875         secondScreenOption.screenId_, secondScreenOption.startX_, secondScreenOption.startY_);
9876     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9877         TLOGE(WmsLogTag::DMS, "permission denied! clientName: %{public}s, pid: %{public}d",
9878             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
9879         return DMError::DM_ERROR_NOT_SYSTEM_APP;
9880     }
9881     sptr<ScreenSession> firstScreenSession = nullptr;
9882     sptr<ScreenSession> secondScreenSession = nullptr;
9883     if (g_isPcDevice) {
9884         firstScreenSession = GetScreenSessionByRsId(mainScreenOptions.screenId_);
9885         secondScreenSession = GetScreenSessionByRsId(secondScreenOption.screenId_);
9886     } else {
9887         firstScreenSession = GetScreenSession(mainScreenOptions.screenId_);
9888         secondScreenSession = GetScreenSession(secondScreenOption.screenId_);
9889     }
9890     if (!firstScreenSession || !secondScreenSession) {
9891         TLOGE(WmsLogTag::DMS, "ScreenSession is null");
9892         return DMError::DM_ERROR_NULLPTR;
9893     }
9894     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
9895         !MultiScreenManager::GetInstance().AreScreensTouching(firstScreenSession, secondScreenSession,
9896         mainScreenOptions, secondScreenOption)) {
9897         TLOGE(WmsLogTag::DMS, "Options incorrect!");
9898         return DMError::DM_ERROR_INVALID_PARAM;
9899     }
9900     SetMultiScreenRelativePositionInner(firstScreenSession, secondScreenSession, mainScreenOptions,
9901         secondScreenOption);
9902 #endif
9903     return DMError::DM_OK;
9904 }
9905 
SetMultiScreenRelativePositionInner(sptr<ScreenSession> & firstScreenSession,sptr<ScreenSession> & secondScreenSession,MultiScreenPositionOptions mainScreenOptions,MultiScreenPositionOptions secondScreenOption)9906 void ScreenSessionManager::SetMultiScreenRelativePositionInner(sptr<ScreenSession>& firstScreenSession,
9907     sptr<ScreenSession>& secondScreenSession, MultiScreenPositionOptions mainScreenOptions,
9908     MultiScreenPositionOptions secondScreenOption)
9909 {
9910 #ifdef WM_MULTI_SCREEN_ENABLE
9911     firstScreenSession->SetStartPosition(mainScreenOptions.startX_, mainScreenOptions.startY_);
9912     secondScreenSession->SetStartPosition(secondScreenOption.startX_, secondScreenOption.startY_);
9913     CalculateXYPosition(firstScreenSession, secondScreenSession);
9914     firstScreenSession->PropertyChange(firstScreenSession->GetScreenProperty(),
9915         ScreenPropertyChangeReason::RELATIVE_POSITION_CHANGE);
9916     secondScreenSession->PropertyChange(secondScreenSession->GetScreenProperty(),
9917         ScreenPropertyChangeReason::RELATIVE_POSITION_CHANGE);
9918     if (g_isPcDevice) {
9919         sptr<ScreenSession> firstPhysicalScreen = GetPhysicalScreenSession(firstScreenSession->GetRSScreenId());
9920         sptr<ScreenSession> secondPhysicalScreen = GetPhysicalScreenSession(secondScreenSession->GetRSScreenId());
9921         if (firstPhysicalScreen && secondPhysicalScreen) {
9922             firstPhysicalScreen->SetStartPosition(mainScreenOptions.startX_, mainScreenOptions.startY_);
9923             secondPhysicalScreen->SetStartPosition(secondScreenOption.startX_, secondScreenOption.startY_);
9924             CalculateXYPosition(firstPhysicalScreen, secondPhysicalScreen);
9925         }
9926     }
9927     std::shared_ptr<RSDisplayNode> firstDisplayNode = firstScreenSession->GetDisplayNode();
9928     std::shared_ptr<RSDisplayNode> secondDisplayNode = secondScreenSession->GetDisplayNode();
9929     if (firstDisplayNode && secondDisplayNode) {
9930         SetScreenOffset(firstScreenSession->GetScreenId(), mainScreenOptions.startX_, mainScreenOptions.startY_);
9931         SetScreenOffset(secondScreenSession->GetScreenId(), secondScreenOption.startX_, secondScreenOption.startY_);
9932     } else {
9933         TLOGW(WmsLogTag::DMS, "DisplayNode is null");
9934     }
9935     TLOGI(WmsLogTag::DMS, "free displayNode");
9936     RSTransactionAdapter::FlushImplicitTransaction(
9937         {firstScreenSession->GetRSUIContext(), secondScreenSession->GetRSUIContext()});
9938 #endif
9939 }
9940 
SetRelativePositionForDisconnect(MultiScreenPositionOptions defaultScreenOptions)9941 void ScreenSessionManager::SetRelativePositionForDisconnect(MultiScreenPositionOptions defaultScreenOptions)
9942 {
9943 #ifdef WM_MULTI_SCREEN_ENABLE
9944     TLOGI(WmsLogTag::DMS, "mID:%{public}" PRIu64", X:%{public}u, Y:%{public}u",
9945         defaultScreenOptions.screenId_, defaultScreenOptions.startX_, defaultScreenOptions.startY_);
9946     sptr<ScreenSession> defaultScreenSession = GetScreenSession(defaultScreenOptions.screenId_);
9947     if (!defaultScreenSession) {
9948         TLOGE(WmsLogTag::DMS, "ScreenSession is null");
9949         return;
9950     }
9951     defaultScreenSession->SetStartPosition(defaultScreenOptions.startX_, defaultScreenOptions.startY_);
9952     CalculateXYPosition(defaultScreenSession);
9953     defaultScreenSession->PropertyChange(defaultScreenSession->GetScreenProperty(),
9954         ScreenPropertyChangeReason::RELATIVE_POSITION_CHANGE);
9955     std::shared_ptr<RSDisplayNode> defaultDisplayNode = defaultScreenSession->GetDisplayNode();
9956     if (defaultDisplayNode) {
9957         SetScreenOffset(defaultScreenSession->GetScreenId(),
9958             defaultScreenOptions.startX_, defaultScreenOptions.startY_);
9959     } else {
9960         TLOGW(WmsLogTag::DMS, "DisplayNode is null");
9961     }
9962     TLOGI(WmsLogTag::DMS, "free displayNode");
9963     RSTransactionAdapter::FlushImplicitTransaction(defaultScreenSession->GetRSUIContext());
9964 #endif
9965 }
9966 
MultiScreenModeChange(ScreenId mainScreenId,ScreenId secondaryScreenId,const std::string & operateMode)9967 void ScreenSessionManager::MultiScreenModeChange(ScreenId mainScreenId, ScreenId secondaryScreenId,
9968     const std::string& operateMode)
9969 {
9970 #ifdef WM_MULTI_SCREEN_ENABLE
9971     std::lock_guard<std::mutex> lock(screenModeChangeMutex_);
9972     TLOGW(WmsLogTag::DMS, "mainId=%{public}" PRIu64" secondId=%{public}" PRIu64" operateType: %{public}s",
9973         mainScreenId, secondaryScreenId, operateMode.c_str());
9974     OnScreenModeChange(ScreenModeChangeEvent::BEGIN);
9975     if (g_isPcDevice) {
9976         std::unique_lock<std::mutex> lock(screenMaskMutex_);
9977         if (screenMaskCV_.wait_for(lock,
9978             std::chrono::milliseconds(CV_WAIT_SCREEN_MASK_MS)) == std::cv_status::timeout) {
9979             TLOGI(WmsLogTag::DMS, "wait screenMaskMutex_ timeout");
9980         }
9981     }
9982     sptr<ScreenSession> firstSession = nullptr;
9983     sptr<ScreenSession> secondarySession = nullptr;
9984     OperateModeChange(mainScreenId, secondaryScreenId, firstSession, secondarySession, operateMode);
9985     if (firstSession != nullptr && secondarySession != nullptr) {
9986         ScreenCombination firstCombination = firstSession->GetScreenCombination();
9987         ScreenCombination secondaryCombination = secondarySession->GetScreenCombination();
9988         MultiScreenManager::GetInstance().MultiScreenModeChange(firstSession, secondarySession, operateMode);
9989         if ((firstCombination == ScreenCombination::SCREEN_MIRROR ||
9990             secondaryCombination == ScreenCombination::SCREEN_MIRROR) &&
9991             operateMode == SCREEN_EXTEND) {
9992             MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_MIRROR, MULTI_SCREEN_EXIT_STR);
9993             MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_ENTER_STR);
9994             NotifyDisplayChanged(secondarySession->ConvertToDisplayInfo(),
9995                 DisplayChangeEvent::SOURCE_MODE_CHANGED);
9996         } else if ((firstCombination == ScreenCombination::SCREEN_EXTEND ||
9997             secondaryCombination == ScreenCombination::SCREEN_EXTEND) &&
9998             operateMode == SCREEN_MIRROR) {
9999             MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_EXIT_STR);
10000             MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_MIRROR, MULTI_SCREEN_ENTER_STR);
10001             NotifyDisplayChanged(secondarySession->ConvertToDisplayInfo(),
10002                 DisplayChangeEvent::SOURCE_MODE_CHANGED);
10003         }
10004     } else {
10005         TLOGE(WmsLogTag::DMS, "params error");
10006     }
10007     NotifyScreenModeChange();
10008     OnScreenModeChange(ScreenModeChangeEvent::END);
10009 #endif
10010 }
10011 
OperateModeChange(ScreenId mainScreenId,ScreenId secondaryScreenId,sptr<ScreenSession> & firstSession,sptr<ScreenSession> & secondarySession,const std::string & operateMode)10012 void ScreenSessionManager::OperateModeChange(ScreenId mainScreenId, ScreenId secondaryScreenId,
10013     sptr<ScreenSession>& firstSession, sptr<ScreenSession>& secondarySession, const std::string& operateMode)
10014 {
10015     {
10016         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
10017         for (auto sessionIt : screenSessionMap_) {
10018             auto screenSession = sessionIt.second;
10019             if (screenSession == nullptr) {
10020                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
10021                 continue;
10022             }
10023             if (!screenSession->GetIsCurrentInUse()) {
10024                 TLOGE(WmsLogTag::DMS, "current screen: %{public}" PRIu64" is not in user!", sessionIt.first);
10025                 continue;
10026             }
10027             if (screenSession->GetRSScreenId() == mainScreenId) {
10028                 firstSession = screenSession;
10029             }
10030             if (screenSession->GetRSScreenId() == secondaryScreenId) {
10031                 secondarySession = screenSession;
10032             }
10033         }
10034     }
10035     if (operateMode == "off" || operateMode == "on") {
10036         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
10037         for (auto sessionIt : screenSessionMap_) {
10038             auto screenSession = sessionIt.second;
10039             if (screenSession == nullptr) {
10040                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
10041                 continue;
10042             }
10043             if (!screenSession->GetIsCurrentInUse()) {
10044                 TLOGW(WmsLogTag::DMS, "current screen: %{public}" PRIu64" is not in user!", sessionIt.first);
10045                 continue;
10046             }
10047             if (screenSession->GetRSScreenId() == mainScreenId) {
10048                 firstSession = screenSession;
10049             }
10050             if (screenSession->GetRSScreenId() == secondaryScreenId) {
10051                 secondarySession = screenSession;
10052             }
10053         }
10054     }
10055 }
10056 
SwitchScrollParam(FoldDisplayMode displayMode)10057 void ScreenSessionManager::SwitchScrollParam(FoldDisplayMode displayMode)
10058 {
10059     auto task = [=]() {
10060         std::map<FoldDisplayMode, ScrollableParam> scrollableParams = ScreenSceneConfig::GetAllScrollableParam();
10061         std::string scrollVelocityScale = scrollableParams.count(displayMode) != 0 ?
10062             scrollableParams[displayMode].velocityScale_ : "0";
10063         std::string scrollFriction = scrollableParams.count(displayMode) != 0 ?
10064             scrollableParams[displayMode].friction_ : "0";
10065         system::SetParameter("persist.scrollable.velocityScale", scrollVelocityScale);
10066         system::SetParameter("persist.scrollable.friction", scrollFriction);
10067     };
10068     taskScheduler_->PostAsyncTask(task, "SwitchScrollParam");
10069 }
10070 
MultiScreenModeChange(const std::string & firstScreenIdStr,const std::string & secondaryScreenIdStr,const std::string & secondaryChandeMode)10071 void ScreenSessionManager::MultiScreenModeChange(const std::string& firstScreenIdStr,
10072     const std::string& secondaryScreenIdStr, const std::string& secondaryChandeMode)
10073 {
10074 #ifdef WM_MULTI_SCREEN_ENABLE
10075     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
10076         TLOGE(WmsLogTag::DMS, "permission denied! clientName: %{public}s, pid: %{public}d",
10077             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
10078         return;
10079     }
10080     if (!ScreenSettingHelper::IsNumber(firstScreenIdStr) || !ScreenSettingHelper::IsNumber(secondaryScreenIdStr)) {
10081         TLOGE(WmsLogTag::DMS, "param denied!");
10082         return;
10083     }
10084     ScreenId firstScreenId = DISPLAY_ID_INVALID;
10085     ScreenId secondaryScreenId = DISPLAY_ID_INVALID;
10086     if (!ScreenSettingHelper::ConvertStrToUint64(firstScreenIdStr, firstScreenId) ||
10087         !ScreenSettingHelper::ConvertStrToUint64(secondaryScreenIdStr, secondaryScreenId)) {
10088         TLOGE(WmsLogTag::DMS, "dumper screenId params error!");
10089         return;
10090     }
10091     if (secondaryChandeMode == "mirror" || secondaryChandeMode == "extend") {
10092         MultiScreenModeChange(firstScreenId, secondaryScreenId, secondaryChandeMode);
10093     } else {
10094         TLOGE(WmsLogTag::DMS, "dumper params error");
10095     }
10096 #endif
10097 }
10098 
OnScreenExtendChange(ScreenId mainScreenId,ScreenId extendScreenId)10099 void ScreenSessionManager::OnScreenExtendChange(ScreenId mainScreenId, ScreenId extendScreenId)
10100 {
10101     auto clientProxy = GetClientProxy();
10102     if (!clientProxy) {
10103         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
10104         return;
10105     }
10106     clientProxy->OnScreenExtendChanged(mainScreenId, extendScreenId);
10107 }
10108 
OnTentModeChanged(int tentType,int32_t hall)10109 void ScreenSessionManager::OnTentModeChanged(int tentType, int32_t hall)
10110 {
10111 #ifdef FOLD_ABILITY_ENABLE
10112     if (!foldScreenController_) {
10113         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
10114         return;
10115     }
10116     foldScreenController_->OnTentModeChanged(tentType, hall);
10117 #endif
10118 }
10119 
SetCoordinationFlag(bool isCoordinationFlag)10120 void ScreenSessionManager::SetCoordinationFlag(bool isCoordinationFlag)
10121 {
10122     TLOGI(WmsLogTag::DMS, "set coordination flag %{public}d", isCoordinationFlag);
10123     isCoordinationFlag_ = isCoordinationFlag;
10124 }
10125 
GetCoordinationFlag(void)10126 bool ScreenSessionManager::GetCoordinationFlag(void)
10127 {
10128     return isCoordinationFlag_;
10129 }
10130 
SetVirtualScreenMaxRefreshRate(ScreenId id,uint32_t refreshRate,uint32_t & actualRefreshRate)10131 DMError ScreenSessionManager::SetVirtualScreenMaxRefreshRate(ScreenId id, uint32_t refreshRate,
10132     uint32_t& actualRefreshRate)
10133 {
10134     if (!SessionPermission::IsSystemCalling()) {
10135         TLOGE(WmsLogTag::DMS, "permission denied! clientName: %{public}s, pid: %{public}d",
10136             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
10137         return DMError::DM_ERROR_NOT_SYSTEM_APP;
10138     }
10139     TLOGI(WmsLogTag::DMS, "ID:%{public}" PRIu64", refreshRate:%{public}u, actualRefreshRate:%{public}u",
10140         id, refreshRate, actualRefreshRate);
10141     if (id == GetDefaultScreenId()) {
10142         TLOGE(WmsLogTag::DMS, "cannot set refresh main screen id: %{public}" PRIu64".", GetDefaultScreenId());
10143         return DMError::DM_ERROR_INVALID_PARAM;
10144     }
10145     auto screenSession = GetScreenSession(id);
10146     if (screenSession == nullptr) {
10147         TLOGE(WmsLogTag::DMS, "screenSession is null.");
10148         return DMError::DM_ERROR_INVALID_PARAM;
10149     }
10150     ScreenId rsScreenId;
10151     if (!screenIdManager_.ConvertToRsScreenId(id, rsScreenId)) {
10152         TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
10153         return DMError::DM_ERROR_INVALID_PARAM;
10154     }
10155     int32_t res = rsInterface_.SetVirtualScreenRefreshRate(rsScreenId, refreshRate, actualRefreshRate);
10156     TLOGI(WmsLogTag::DMS, "refreshRate:%{public}u, actualRefreshRate:%{public}u", refreshRate, actualRefreshRate);
10157     if (res != StatusCode::SUCCESS) {
10158         TLOGE(WmsLogTag::DMS, "rsInterface error: %{public}d", res);
10159         return DMError::DM_ERROR_INVALID_PARAM;
10160     }
10161     screenSession->UpdateRefreshRate(actualRefreshRate);
10162     screenSession->SetSupportedRefreshRate({actualRefreshRate});
10163     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::UPDATE_REFRESHRATE);
10164     return DMError::DM_OK;
10165 }
10166 
OnScreenCaptureNotify(ScreenId mainScreenId,int32_t uid,const std::string & clientName)10167 void ScreenSessionManager::OnScreenCaptureNotify(ScreenId mainScreenId, int32_t uid, const std::string& clientName)
10168 {
10169     auto clientProxy = GetClientProxy();
10170     if (!clientProxy) {
10171         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
10172         return;
10173     }
10174     clientProxy->ScreenCaptureNotify(mainScreenId, uid, clientName);
10175 }
10176 
AddPermissionUsedRecord(const std::string & permission,int32_t successCount,int32_t failCount)10177 void ScreenSessionManager::AddPermissionUsedRecord(const std::string& permission, int32_t successCount,
10178     int32_t failCount)
10179 {
10180     int32_t ret = Security::AccessToken::PrivacyKit::AddPermissionUsedRecord(IPCSkeleton::GetCallingTokenID(),
10181         permission, successCount, failCount);
10182     if (ret != 0) {
10183         TLOGW(WmsLogTag::DMS, "permission:%{public}s, successCount %{public}d, failedCount %{public}d",
10184             permission.c_str(), successCount, failCount);
10185     }
10186 }
10187 
GetScreenCapture(const CaptureOption & captureOption,DmErrorCode * errorCode)10188 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetScreenCapture(const CaptureOption& captureOption,
10189     DmErrorCode* errorCode)
10190 {
10191     TLOGI(WmsLogTag::DMS, "enter!");
10192     if (errorCode == nullptr) {
10193         TLOGE(WmsLogTag::DMS, "param is null.");
10194         return nullptr;
10195     }
10196     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
10197         TLOGW(WmsLogTag::DMS, "capture disabled by edm!");
10198         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
10199         return nullptr;
10200     }
10201     if (!ScreenSceneConfig::IsSupportCapture()) {
10202         TLOGW(WmsLogTag::DMS, "device not support capture.");
10203         *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
10204         return nullptr;
10205     }
10206     if (!Permission::CheckCallingPermission(CUSTOM_SCREEN_CAPTURE_PERMISSION) && !SessionPermission::IsShellCall()) {
10207         TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d.",
10208             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingRealPid());
10209         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
10210         return nullptr;
10211     }
10212     if (captureOption.displayId_ == DISPLAY_ID_INVALID ||
10213         (captureOption.displayId_ == DISPLAY_ID_FAKE && !IsFakeDisplayExist())) {
10214         TLOGE(WmsLogTag::DMS, "display id invalid.");
10215         *errorCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
10216         return nullptr;
10217     }
10218     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetScreenCapture(%" PRIu64")", captureOption.displayId_);
10219     auto res = GetScreenSnapshot(captureOption.displayId_, false);
10220     AddPermissionUsedRecord(CUSTOM_SCREEN_CAPTURE_PERMISSION,
10221         static_cast<int32_t>(res != nullptr), static_cast<int32_t>(res == nullptr));
10222     if (res == nullptr) {
10223         TLOGE(WmsLogTag::DMS, "get capture null.");
10224         *errorCode = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
10225         return nullptr;
10226     }
10227     NotifyScreenshot(captureOption.displayId_);
10228     if (SessionPermission::IsBetaVersion()) {
10229         CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
10230     }
10231     *errorCode = DmErrorCode::DM_OK;
10232     isScreenShot_ = true;
10233     /* notify scb to do toast */
10234     OnScreenCaptureNotify(GetDefaultScreenId(), IPCSkeleton::GetCallingUid(), SysCapUtil::GetClientName());
10235     /* notify application capture happend */
10236     NotifyCaptureStatusChanged();
10237     return res;
10238 }
10239 
GetPrimaryDisplayInfo()10240 sptr<DisplayInfo> ScreenSessionManager::GetPrimaryDisplayInfo()
10241 {
10242     sptr<ScreenSession> screenSession = nullptr;
10243     {
10244         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
10245         for (auto sessionIt : screenSessionMap_) {
10246             sptr<ScreenSession> session = sessionIt.second;
10247             if (session == nullptr) {
10248                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
10249                 continue;
10250             }
10251             if (!session->GetIsExtend()) {
10252                 TLOGD(WmsLogTag::DMS, "find primary %{public}" PRIu64, session->screenId_);
10253                 screenSession = session;
10254                 break;
10255             }
10256         }
10257     }
10258     if (screenSession == nullptr) {
10259         TLOGW(WmsLogTag::DMS, "get extend screen faild use default!");
10260         screenSession = GetScreenSession(GetDefaultScreenId());
10261     }
10262     if (screenSession) {
10263         std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
10264         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
10265         if (displayInfo == nullptr) {
10266             TLOGI(WmsLogTag::DMS, "convert display error.");
10267             return nullptr;
10268         }
10269         displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
10270         return displayInfo;
10271     } else {
10272         TLOGE(WmsLogTag::DMS, "failed");
10273         return nullptr;
10274     }
10275 }
10276 
OnSuperFoldStatusChange(ScreenId screenId,SuperFoldStatus superFoldStatus)10277 void ScreenSessionManager::OnSuperFoldStatusChange(ScreenId screenId, SuperFoldStatus superFoldStatus)
10278 {
10279     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", superFoldStatus: %{public}d", screenId,
10280         static_cast<uint32_t>(superFoldStatus));
10281     auto clientProxy = GetClientProxy();
10282     if (!clientProxy) {
10283         TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
10284         return;
10285     }
10286     clientProxy->OnSuperFoldStatusChanged(screenId, superFoldStatus);
10287 }
10288 
OnExtendScreenConnectStatusChange(ScreenId screenId,ExtendScreenConnectStatus extendScreenConnectStatus)10289 void ScreenSessionManager::OnExtendScreenConnectStatusChange(ScreenId screenId,
10290     ExtendScreenConnectStatus extendScreenConnectStatus)
10291 {
10292     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", extendScreenConnectStatus: %{public}d", screenId,
10293         static_cast<uint32_t>(extendScreenConnectStatus));
10294     auto clientProxy = GetClientProxy();
10295     if (!clientProxy) {
10296         TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
10297         return;
10298     }
10299     clientProxy->OnExtendScreenConnectStatusChanged(screenId, extendScreenConnectStatus);
10300 }
10301 
OnSecondaryReflexionChange(ScreenId screenId,bool isSecondaryReflexion)10302 void ScreenSessionManager::OnSecondaryReflexionChange(ScreenId screenId, bool isSecondaryReflexion)
10303 {
10304     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", isSecondaryReflexion: %{public}d", screenId,
10305         isSecondaryReflexion);
10306     auto clientProxy = GetClientProxy();
10307     if (!clientProxy) {
10308         TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
10309         return;
10310     }
10311     clientProxy->OnSecondaryReflexionChanged(screenId, isSecondaryReflexion);
10312 }
10313 
OnBeforeScreenPropertyChange(FoldStatus foldStatus)10314 void ScreenSessionManager::OnBeforeScreenPropertyChange(FoldStatus foldStatus)
10315 {
10316     TLOGI(WmsLogTag::DMS, "foldstatus: %{public}d", foldStatus);
10317     if (!FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
10318         return;
10319     }
10320     if (!clientProxy_) {
10321         TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
10322         return;
10323     }
10324     clientProxy_->OnBeforeScreenPropertyChanged(foldStatus);
10325 }
10326 
GetCameraStatus()10327 int32_t ScreenSessionManager::GetCameraStatus()
10328 {
10329     return cameraStatus_;
10330 }
10331 
GetCameraPosition()10332 int32_t ScreenSessionManager::GetCameraPosition()
10333 {
10334     return cameraPosition_;
10335 }
10336 
IsScreenCasting()10337 bool ScreenSessionManager::IsScreenCasting()
10338 {
10339     if (virtualScreenCount_ > 0 || hdmiScreenCount_ > 0) {
10340         TLOGI(WmsLogTag::DMS, "virtualScreenCount_: %{public}" PRIu32 ", hdmiScreenCount_: %{public}d",
10341             virtualScreenCount_, hdmiScreenCount_);
10342         return true;
10343     }
10344     TLOGI(WmsLogTag::DMS, "not casting");
10345     return false;
10346 }
10347 
GetSessionOption(sptr<ScreenSession> screenSession)10348 SessionOption ScreenSessionManager::GetSessionOption(sptr<ScreenSession> screenSession)
10349 {
10350     SessionOption option = {
10351         .rsId_ = screenSession->GetRSScreenId(),
10352         .name_ = screenSession->GetName(),
10353         .isExtend_ = screenSession->GetIsExtend(),
10354         .innerName_ = screenSession->GetInnerName(),
10355         .screenId_ = screenSession->GetScreenId(),
10356     };
10357     return option;
10358 }
10359 
GetSessionOption(sptr<ScreenSession> screenSession,ScreenId screenId)10360 SessionOption ScreenSessionManager::GetSessionOption(sptr<ScreenSession> screenSession, ScreenId screenId)
10361 {
10362     SessionOption option = {
10363         .rsId_ = screenSession->GetRSScreenId(),
10364         .name_ = screenSession->GetName(),
10365         .isExtend_ = screenSession->GetIsExtend(),
10366         .innerName_ = screenSession->GetInnerName(),
10367         .screenId_ = screenId,
10368     };
10369     return option;
10370 }
10371 
SetScreenSkipProtectedWindow(const std::vector<ScreenId> & screenIds,bool isEnable)10372 DMError ScreenSessionManager::SetScreenSkipProtectedWindow(const std::vector<ScreenId>& screenIds, bool isEnable)
10373 {
10374     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
10375         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
10376             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
10377         return DMError::DM_ERROR_NOT_SYSTEM_APP;
10378     }
10379     std::ostringstream oss;
10380     for (ScreenId screenId : screenIds) {
10381         oss << screenId << " ";
10382     }
10383     TLOGI(WmsLogTag::DMS, "screenIds:%{public}s, isEnable:%{public}d", oss.str().c_str(), isEnable);
10384     {
10385         std::lock_guard<std::mutex> lock(shareProtectMutex_);
10386         for (ScreenId screenId : screenIds) {
10387             sptr<ScreenSession> screenSession = GetScreenSession(screenId);
10388             if (screenSession == nullptr) {
10389                 continue;
10390             }
10391             if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
10392                 ScreenId rsScreenId = INVALID_SCREEN_ID;
10393                 if (!screenIdManager_.ConvertToRsScreenId(screenSession->GetScreenId(), rsScreenId) ||
10394                     rsScreenId == INVALID_SCREEN_ID) {
10395                     TLOGE(WmsLogTag::DMS, "No corresponding rsId:%{public}" PRIu64 "", rsScreenId);
10396                     continue;
10397                 }
10398                 TLOGI(WmsLogTag::DMS, "virtualScreenId:%{public}" PRIu64 "", screenId);
10399                 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
10400                     "SetCastScreenEnableSkipWindow(%" PRIu64")", screenId);
10401                 rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, isEnable);
10402             }
10403         }
10404     }
10405     return DMError::DM_OK;
10406 }
10407 
IsSpecialApp()10408 bool ScreenSessionManager::IsSpecialApp()
10409 {
10410     if (!FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() &&
10411         !FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
10412         return false;
10413     }
10414     static std::chrono::steady_clock::time_point lastRequestTime = std::chrono::steady_clock::now();
10415     auto currentTime = std::chrono::steady_clock::now();
10416     auto interval = std::chrono::duration_cast<std::chrono::microseconds>(currentTime - lastRequestTime).count();
10417     std::string bundleName = NO_EXIST_BUNDLE_MANE;
10418     int32_t currentPid = IPCSkeleton::GetCallingPid();
10419     if (interval < MAX_INTERVAL_US) {
10420         bundleName = g_uidVersionMap.Get(currentPid);
10421     }
10422     if (bundleName == NO_EXIST_BUNDLE_MANE) {
10423         bundleName = SysCapUtil::GetBundleName();
10424         TLOGI(WmsLogTag::DMS, "Get BundleName from IPC pid: %{public}d name: %{public}s",
10425             currentPid, bundleName.c_str());
10426         g_uidVersionMap.Set(currentPid, bundleName);
10427     }
10428     lastRequestTime = currentTime;
10429     TLOGD(WmsLogTag::DMS, "bundleName: %{public}s", bundleName.c_str());
10430     auto it = g_packageNames_.find(bundleName);
10431     if (it != g_packageNames_.end()) {
10432         TLOGI(WmsLogTag::DMS, "Is Special App");
10433         return true;
10434     }
10435     return false;
10436 }
10437 
UpdateValidArea(ScreenId screenId,uint32_t validWidth,uint32_t validHeight)10438 void ScreenSessionManager::UpdateValidArea(ScreenId screenId, uint32_t validWidth, uint32_t validHeight)
10439 {
10440     auto screenSession = GetScreenSession(screenId);
10441     if (!screenSession) {
10442         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
10443         return;
10444     }
10445     screenSession->SetValidWidth(validWidth);
10446     screenSession->SetValidHeight(validHeight);
10447 }
10448 
GetIsRealScreen(ScreenId screenId)10449 bool ScreenSessionManager::GetIsRealScreen(ScreenId screenId)
10450 {
10451     if (!SessionPermission::IsSystemCalling()) {
10452         TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
10453             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
10454         return false;
10455     }
10456     auto screenSession = GetScreenSession(screenId);
10457     if (!screenSession) {
10458         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
10459         return false;
10460     }
10461     return screenSession->GetIsRealScreen();
10462 }
10463 
SetSystemKeyboardStatus(bool isTpKeyboardOn)10464 DMError ScreenSessionManager::SetSystemKeyboardStatus(bool isTpKeyboardOn)
10465 {
10466     if (!SessionPermission::IsSACalling()) {
10467         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
10468             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
10469         return DMError::DM_ERROR_NOT_SYSTEM_APP;
10470     }
10471 #ifdef FOLD_ABILITY_ENABLE
10472     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
10473         SuperFoldStateManager::GetInstance().SetSystemKeyboardStatus(isTpKeyboardOn);
10474         return DMError::DM_OK;
10475     }
10476 #endif // FOLD_ABILITY_ENABLE
10477     return DMError::DM_ERROR_DEVICE_NOT_SUPPORT;
10478 }
10479 
WakeUpPictureFrameBlock(DisplayEvent event)10480 void ScreenSessionManager::WakeUpPictureFrameBlock(DisplayEvent event)
10481 {
10482     std::unique_lock <std::mutex> lock(screenWaitPictureFrameMutex_);
10483     if (event == DisplayEvent::SCREEN_LOCK_START_DREAM) {
10484         TLOGI(WmsLogTag::DMS, "[UL_POWER]get pictureFrameReady");
10485         pictureFrameReady_ = true;
10486     } else if (event == DisplayEvent::SCREEN_LOCK_END_DREAM) {
10487         TLOGI(WmsLogTag::DMS, "[UL_POWER]get pictureFrameBreak");
10488         pictureFrameBreak_ = true;
10489     } else {
10490         return;
10491     }
10492     TLOGI(WmsLogTag::DMS, "[UL_POWER]notify block");
10493     screenWaitPictureFrameCV_.notify_all();
10494 }
10495 
BlockScreenWaitPictureFrameByCV(bool isStartDream)10496 bool ScreenSessionManager::BlockScreenWaitPictureFrameByCV(bool isStartDream)
10497 {
10498     TLOGI(WmsLogTag::DMS, "[UL_POWER]enter");
10499     std::unique_lock <std::mutex> lock(screenWaitPictureFrameMutex_);
10500     pictureFrameReady_ = false;
10501     pictureFrameBreak_ = false;
10502     if (screenWaitPictureFrameCV_.wait_for(lock, std::chrono::milliseconds(SCREEN_WAIT_PICTURE_FRAME_TIME))
10503         == std::cv_status::timeout) {
10504         TLOGI(WmsLogTag::DMS, "[UL_POWER]wait picture frame timeout");
10505         return true;
10506     }
10507     bool pictureFrameIsOk = isStartDream ? pictureFrameReady_ : pictureFrameBreak_;
10508     TLOGI(WmsLogTag::DMS, "[UL_POWER]pictureFrameIsOk:%{public}d", pictureFrameIsOk);
10509     return pictureFrameIsOk;
10510 }
10511 
SetForceCloseHdr(ScreenId screenId,bool isForceCloseHdr)10512 void ScreenSessionManager::SetForceCloseHdr(ScreenId screenId, bool isForceCloseHdr)
10513 {
10514     if (!SessionPermission::IsSystemCalling()) {
10515         TLOGE(WmsLogTag::DMS, "permission denied!");
10516         return;
10517     }
10518     auto screenSession = GetScreenSession(screenId);
10519     if (!screenSession) {
10520         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
10521         return;
10522     }
10523     TLOGI(WmsLogTag::DMS, "[UL_POWER]screenId:%{public}" PRIu64 "isForceCloseHdr:%{public}d",
10524         screenId, isForceCloseHdr);
10525     screenSession->SetForceCloseHdr(isForceCloseHdr);
10526 }
10527 
RegisterSettingExtendScreenDpiObserver()10528 void ScreenSessionManager::RegisterSettingExtendScreenDpiObserver()
10529 {
10530     TLOGI(WmsLogTag::DMS, "Register Setting Extend Dpi Observer");
10531     SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetExtendScreenDpi(); };
10532     ScreenSettingHelper::RegisterSettingExtendScreenDpiObserver(updateFunc);
10533 }
10534 
SetExtendScreenDpi()10535 void ScreenSessionManager::SetExtendScreenDpi()
10536 {
10537     float extendScreenDpiCoef = EXTEND_SCREEN_DPI_DEFAULT_PARAMETER;
10538     bool ret = ScreenSettingHelper::GetSettingExtendScreenDpi(extendScreenDpiCoef);
10539     if (!ret) {
10540         TLOGE(WmsLogTag::DMS, "get setting extend screen dpi failed");
10541         g_extendScreenDpiCoef = EXTEND_SCREEN_DPI_DEFAULT_PARAMETER;
10542     } else {
10543         g_extendScreenDpiCoef = extendScreenDpiCoef;
10544     }
10545     float dpi = static_cast<float>(cachedSettingDpi_) / BASELINE_DENSITY;
10546     SetExtendPixelRatio(dpi * g_extendScreenDpiCoef);
10547     TLOGI(WmsLogTag::DMS, "get setting extend screen dpi is : %{public}f", g_extendScreenDpiCoef);
10548 }
10549 
GetFakePhysicalScreenSession(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)10550 sptr<ScreenSession> ScreenSessionManager::GetFakePhysicalScreenSession(ScreenId screenId, ScreenId defScreenId,
10551     ScreenProperty property)
10552 {
10553     sptr<ScreenSession> screenSession = nullptr;
10554     ScreenSessionConfig config;
10555     if (g_isPcDevice) {
10556         config = {
10557             .screenId = screenId,
10558             .rsId = screenId,
10559             .defaultScreenId = defScreenId,
10560             .property = property,
10561         };
10562         screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
10563     }
10564     return screenSession;
10565 }
10566 
CreateFakePhysicalMirrorSessionInner(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)10567 sptr<ScreenSession> ScreenSessionManager::CreateFakePhysicalMirrorSessionInner(ScreenId screenId, ScreenId defScreenId,
10568     ScreenProperty property)
10569 {
10570 #ifdef WM_MULTI_SCREEN_ENABLE
10571     sptr<ScreenSession> screenSession = nullptr;
10572     if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
10573         TLOGW(WmsLogTag::DMS, "mirror disabled by edm!");
10574         return screenSession;
10575     }
10576     screenSession = GetFakePhysicalScreenSession(screenId, defScreenId, property);
10577     if (!screenSession) {
10578         TLOGE(WmsLogTag::DMS, "screenSession is null");
10579         return nullptr;
10580     }
10581     if (g_isPcDevice) {
10582         InitExtendScreenProperty(screenId, screenSession, property);
10583         screenSession->SetName(SCREEN_NAME_EXTEND);
10584         screenSession->SetIsExtend(true);
10585         screenSession->SetScreenCombination(ScreenCombination::SCREEN_EXTEND);
10586     } else {
10587         screenSession->SetIsExtend(true);
10588         screenSession->SetName(SCREEN_NAME_CAST);
10589         screenSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
10590         screenSession->SetVirtualScreenFlag(VirtualScreenFlag::CAST);
10591     }
10592     GetAndMergeEdidInfo(screenSession);
10593     screenSession->SetMirrorScreenType(MirrorScreenType::PHYSICAL_MIRROR);
10594     screenSession->SetIsPcUse(g_isPcDevice ? true : false);
10595     screenSession->SetIsInternal(false);
10596     screenSession->SetIsRealScreen(true);
10597     screenSession->SetIsCurrentInUse(true);
10598     return screenSession;
10599 #else
10600     return nullptr;
10601 #endif
10602 }
10603 
GetPhysicalScreenSessionInner(ScreenId screenId,ScreenProperty property)10604 sptr<ScreenSession> ScreenSessionManager::GetPhysicalScreenSessionInner(ScreenId screenId, ScreenProperty property)
10605 {
10606     ScreenId defScreenId = GetDefaultScreenId();
10607     TLOGW(WmsLogTag::DMS, "screenId:%{public}" PRIu64, screenId);
10608     if (IsDefaultMirrorMode(screenId)) {
10609 #ifdef WM_MULTI_SCREEN_ENABLE
10610         return CreateFakePhysicalMirrorSessionInner(screenId, defScreenId, property);
10611 #else
10612         return nullptr;
10613 #endif
10614     }
10615     std::string screenName = "UNKNOWN";
10616     if (screenId == SCREEN_ID_MAIN) {
10617         screenName = "SubScreen";
10618     }
10619     ScreenSessionConfig config = {
10620         .screenId = screenId,
10621         .defaultScreenId = defScreenId,
10622         .name = screenName,
10623         .property = property,
10624     };
10625     sptr<ScreenSession> screenSession = nullptr;
10626     screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
10627     screenSession->SetIsExtend(false);
10628     screenSession->SetScreenCombination(ScreenCombination::SCREEN_MAIN);
10629     screenSession->SetIsInternal(true);
10630     screenSession->SetIsRealScreen(true);
10631     screenSession->SetIsCurrentInUse(true);
10632     screenSession->SetIsPcUse(g_isPcDevice ? true : false);
10633     return screenSession;
10634 }
10635 
GetOrCreatePhysicalScreenSession(ScreenId screenId)10636 sptr<ScreenSession> ScreenSessionManager::GetOrCreatePhysicalScreenSession(ScreenId screenId)
10637 {
10638     TLOGW(WmsLogTag::DMS, "ENTER. ScreenId: %{public}" PRIu64, screenId);
10639     sptr<ScreenSession> screenSession = GetPhysicalScreenSession(screenId);
10640     if (screenSession) {
10641         TLOGW(WmsLogTag::DMS, "physical screen Exist ScreenId: %{public}" PRIu64, screenId);
10642         return screenSession;
10643     }
10644 
10645     ScreenProperty property;
10646     CreateScreenProperty(screenId, property);
10647     TLOGW(WmsLogTag::DMS, "create screen property end");
10648 
10649     sptr<ScreenSession> session = GetPhysicalScreenSessionInner(screenId, property);
10650     if (session == nullptr) {
10651         TLOGE(WmsLogTag::DMS, "get physical screen fail ScreenId: %{public}" PRIu64, screenId);
10652         return session;
10653     }
10654     InitExtendScreenDensity(session, property);
10655     InitAbstractScreenModesInfo(session);
10656     session->groupSmsId_ = 1;
10657     {
10658         std::lock_guard<std::recursive_mutex> lock(physicalScreenSessionMapMutex_);
10659         physicalScreenSessionMap_[screenId] = session;
10660     }
10661     SetHdrFormats(screenId, session);
10662     SetColorSpaces(screenId, session);
10663     SetSupportedRefreshRate(session);
10664     TLOGW(WmsLogTag::DMS, "Create success. ScreenId: %{public}" PRIu64, screenId);
10665     return session;
10666 }
10667 
GetScreenSessionByRsId(ScreenId rsScreenId)10668 sptr<ScreenSession> ScreenSessionManager::GetScreenSessionByRsId(ScreenId rsScreenId)
10669 {
10670     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
10671     for (auto sessionIt : screenSessionMap_) {
10672         sptr<ScreenSession> screenSession = sessionIt.second;
10673         if (screenSession == nullptr) {
10674             TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
10675             continue;
10676         }
10677         if (screenSession->GetRSScreenId() == rsScreenId) {
10678             TLOGI(WmsLogTag::DMS, "found rsScreenId = %{public}" PRIu64, rsScreenId);
10679             return screenSession;
10680         }
10681     }
10682     return nullptr;
10683 }
10684 
GetPhysicalScreenSession(ScreenId screenId) const10685 sptr<ScreenSession> ScreenSessionManager::GetPhysicalScreenSession(ScreenId screenId) const
10686 {
10687     {
10688         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
10689         if (screenSessionMap_.empty()) {
10690             screenEventTracker_.LogWarningAllInfos();
10691         }
10692     }
10693 
10694     std::lock_guard<std::recursive_mutex> lock(physicalScreenSessionMapMutex_);
10695     auto iter = physicalScreenSessionMap_.find(screenId);
10696     if (iter == physicalScreenSessionMap_.end()) {
10697         TLOGW(WmsLogTag::DMS, "not found screen id: %{public}" PRIu64, screenId);
10698         return nullptr;
10699     }
10700     return iter->second;
10701 }
10702 
NotifyExtendScreenCreateFinish()10703 void ScreenSessionManager::NotifyExtendScreenCreateFinish()
10704 {
10705     if (!SessionPermission::IsSystemCalling()) {
10706         TLOGE(WmsLogTag::DMS, "permission denied!");
10707         return;
10708     }
10709     if (!g_isPcDevice) {
10710         TLOGW(WmsLogTag::DMS, "not pc device.");
10711         return;
10712     }
10713     sptr<ScreenSession> mainScreen = nullptr;
10714     sptr<ScreenSession> extendScreen = nullptr;
10715     {
10716         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
10717         for (auto sessionIt : screenSessionMap_) {
10718             auto screenSession = sessionIt.second;
10719             if (screenSession == nullptr) {
10720                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr.");
10721                 continue;
10722             }
10723             if (!screenSession->GetIsCurrentInUse()) {
10724                 continue;
10725             }
10726             if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
10727                 mainScreen = screenSession;
10728             } else {
10729                 extendScreen = screenSession;
10730             }
10731         }
10732     }
10733     if (mainScreen == nullptr) {
10734         TLOGE(WmsLogTag::DMS, "main screen is null");
10735         return;
10736     }
10737     NotifyCreatedScreen(mainScreen);
10738     if (extendScreen == nullptr) {
10739         TLOGE(WmsLogTag::DMS, "extend screen is null");
10740         return;
10741     }
10742     NotifyCreatedScreen(extendScreen);
10743 }
10744 
UpdateScreenIdManager(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)10745 void ScreenSessionManager::UpdateScreenIdManager(sptr<ScreenSession>& innerScreen,
10746     sptr<ScreenSession>& externalScreen)
10747 {
10748     ScreenId innerScreenId = innerScreen->GetRSScreenId();
10749     ScreenId externalScreenId = externalScreen->GetRSScreenId();
10750     screenIdManager_.UpdateScreenId(externalScreenId, innerScreen->GetScreenId());
10751     screenIdManager_.UpdateScreenId(innerScreenId, externalScreen->GetScreenId());
10752 }
10753 
DumperClientScreenSessions()10754 std::string ScreenSessionManager::DumperClientScreenSessions()
10755 {
10756     std::string clientSessions = "";
10757     auto clientProxy = GetClientProxy();
10758     if (clientProxy) {
10759         clientSessions = clientProxy->OnDumperClientScreenSessions();
10760     }
10761     return clientSessions;
10762 }
10763 
SetMultiScreenModeChangeTracker(std::string changeProc)10764 void ScreenSessionManager::SetMultiScreenModeChangeTracker(std::string changeProc)
10765 {
10766     screenEventTracker_.RecordEvent(changeProc);
10767 }
10768 
NotifyCreatedScreen(sptr<ScreenSession> screenSession)10769 void ScreenSessionManager::NotifyCreatedScreen(sptr<ScreenSession> screenSession)
10770 {
10771     if (!g_isPcDevice) {
10772         TLOGW(WmsLogTag::DMS, "not pc device.");
10773         return;
10774     }
10775     if (screenSession == nullptr) {
10776         TLOGE(WmsLogTag::DMS, "screenSession is null");
10777         return;
10778     }
10779     std::ostringstream oss;
10780     oss << "screenId: " << screenSession->GetScreenId()
10781         << ", rsId: " << screenSession->GetRSScreenId();
10782     oss << std::endl;
10783     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
10784     if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
10785         TLOGW(WmsLogTag::DMS, "mirror, no need to notify.");
10786         return;
10787     }
10788     ScreenProperty property = screenSession->GetScreenProperty();
10789     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
10790         TLOGW(WmsLogTag::DMS, "super fold device, change by rotation.");
10791         screenSession->PropertyChange(property, ScreenPropertyChangeReason::ROTATION);
10792     } else {
10793         screenSession->PropertyChange(property, ScreenPropertyChangeReason::UNDEFINED);
10794     }
10795     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
10796     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
10797 }
10798 
NotifyExtendScreenDestroyFinish()10799 void ScreenSessionManager::NotifyExtendScreenDestroyFinish()
10800 {
10801     if (!SessionPermission::IsSystemCalling()) {
10802         TLOGE(WmsLogTag::DMS, "permission denied!");
10803         return;
10804     }
10805     if (!g_isPcDevice) {
10806         TLOGW(WmsLogTag::DMS, "not pc device.");
10807         return;
10808     }
10809     TLOGI(WmsLogTag::DMS, "destroy finish, notify block");
10810     switchUserCV_.notify_all();
10811     userSwitching_ = false;
10812 }
10813 
SetRSScreenPowerStatus(ScreenId screenId,ScreenPowerStatus status)10814 void ScreenSessionManager::SetRSScreenPowerStatus(ScreenId screenId, ScreenPowerStatus status)
10815 {
10816     rsInterface_.SetScreenPowerStatus(screenId, status);
10817     if (status == ScreenPowerStatus::POWER_STATUS_ON) {
10818 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
10819         uint32_t ret = DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().NotifyBrightnessManagerScreenPowerStatus(
10820             static_cast<uint32_t>(screenId), static_cast<uint32_t>(status));
10821         TLOGI(WmsLogTag::DMS, "notify brightness, screenId:%{public}" PRIu64 ", status:%{public}u, ret = %{public}u",
10822             screenId, static_cast<uint32_t>(status), ret);
10823 #endif
10824     }
10825 }
10826 
OnScreenModeChange(ScreenModeChangeEvent screenModeChangeEvent)10827 void ScreenSessionManager::OnScreenModeChange(ScreenModeChangeEvent screenModeChangeEvent)
10828 {
10829     TLOGI(WmsLogTag::DMS, "screenModeChangeEvent: %{public}d", static_cast<uint32_t>(screenModeChangeEvent));
10830     auto clientProxy = GetClientProxy();
10831     if (!clientProxy) {
10832         TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
10833         return;
10834     }
10835     clientProxy->OnScreenModeChanged(screenModeChangeEvent);
10836 }
10837 
NotifyScreenMaskAppear()10838 void ScreenSessionManager::NotifyScreenMaskAppear()
10839 {
10840     if (!SessionPermission::IsSystemCalling()) {
10841         TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
10842             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
10843         return;
10844     }
10845     if (!g_isPcDevice) {
10846         TLOGW(WmsLogTag::DMS, "not pc device.");
10847         return;
10848     }
10849     TLOGI(WmsLogTag::DMS, "screen mask appeared, notify block");
10850     screenMaskCV_.notify_all();
10851 }
10852 
GetKeyboardState()10853 bool ScreenSessionManager::GetKeyboardState()
10854 {
10855 #ifdef FOLD_ABILITY_ENABLE
10856     return SuperFoldStateManager::GetInstance().GetKeyboardState();
10857 #endif
10858     return false;
10859 }
10860 
GetScreenAreaOfDisplayArea(DisplayId displayId,const DMRect & displayArea,ScreenId & screenId,DMRect & screenArea)10861 DMError ScreenSessionManager::GetScreenAreaOfDisplayArea(DisplayId displayId, const DMRect& displayArea,
10862     ScreenId& screenId, DMRect& screenArea)
10863 {
10864     TLOGI(WmsLogTag::DMS, "displayId:%{public}" PRIu64 ",displayArea:%{public}d,%{public}d,%{public}d,%{public}d",
10865         displayId, displayArea.posX_, displayArea.posY_, displayArea.width_, displayArea.height_);
10866     auto displayInfo = GetDisplayInfoById(displayId);
10867     if (displayInfo == nullptr) {
10868         TLOGE(WmsLogTag::DMS, "can not get displayInfo");
10869         return DMError::DM_ERROR_NULLPTR;
10870     }
10871     DMRect displayRegion =
10872         { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(), displayInfo->GetWidth(), displayInfo->GetHeight() };
10873     if (!displayArea.IsInsideOf(displayRegion)) {
10874         TLOGE(WmsLogTag::DMS, "displayArea is outSide of displayRegion");
10875         return DMError::DM_ERROR_INVALID_PARAM;
10876     }
10877     screenId = displayInfo->GetScreenId();
10878     auto screenSession = GetScreenSession(screenId);
10879     if (screenSession == nullptr) {
10880         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
10881         return DMError::DM_ERROR_INVALID_PARAM;
10882     }
10883     RRect bounds = screenSession->GetScreenProperty().GetPhyBounds();
10884     DMRect screenRegion =
10885         { bounds.rect_.GetLeft(), bounds.rect_.GetTop(), bounds.rect_.GetWidth(), bounds.rect_.GetHeight() };
10886     DMRect displayAreaFixed = displayArea;
10887     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && GetFoldStatus() == FoldStatus::HALF_FOLD) {
10888         if (displayId == DISPLAY_ID_FAKE) {
10889             displayAreaFixed.posY_ += screenRegion.height_ - displayRegion.height_;
10890         }
10891         displayRegion.height_ = screenRegion.height_;
10892     } else if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice() && GetFoldDisplayMode() == FoldDisplayMode::FULL) {
10893         switch (displayInfo->GetRotation()) {
10894         case Rotation::ROTATION_0:
10895             displayRegion.posX_ = FULL_STATUS_OFFSET_X;
10896             displayAreaFixed.posX_ += FULL_STATUS_OFFSET_X;
10897             break;
10898         case Rotation::ROTATION_90:
10899             displayRegion.posY_ = FULL_STATUS_OFFSET_X;
10900             displayAreaFixed.posY_ += FULL_STATUS_OFFSET_X;
10901             break;
10902         default:
10903             break;
10904         }
10905     }
10906     CalculateRotatedDisplay(displayInfo->GetRotation(), screenRegion, displayRegion, displayAreaFixed);
10907     CalculateScreenArea(displayRegion, displayAreaFixed, screenRegion, screenArea);
10908     TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 ",screenArea:%{public}d,%{public}d,%{public}d,%{public}d",
10909         screenId, screenArea.posX_, screenArea.posY_, screenArea.width_, screenArea.height_);
10910     return DMError::DM_OK;
10911 }
10912 
CalculateRotatedDisplay(Rotation rotation,const DMRect & screenRegion,DMRect & displayRegion,DMRect & displayArea)10913 void ScreenSessionManager::CalculateRotatedDisplay(Rotation rotation, const DMRect& screenRegion,
10914     DMRect& displayRegion, DMRect& displayArea)
10915 {
10916     std::vector<std::string> phyOffsets = FoldScreenStateInternel::GetPhyRotationOffset();
10917     int32_t phyOffset = 0;
10918     if (phyOffsets.size() > 1 &&
10919         (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice() || GetFoldStatus() != FoldStatus::FOLDED)) {
10920         if (!ScreenSettingHelper::ConvertStrToInt32(phyOffsets[1], phyOffset)) {
10921             TLOGE(WmsLogTag::DMS, "transfer phyOffset1 failed.");
10922             return;
10923         }
10924     } else if (phyOffsets.size() > 0) {
10925         if (!ScreenSettingHelper::ConvertStrToInt32(phyOffsets[0], phyOffset)) {
10926             TLOGE(WmsLogTag::DMS, "transfer phyOffset0 failed.");
10927             return;
10928         }
10929     }
10930     Rotation phyOffsetRotation = ConvertIntToRotation(phyOffset);
10931     uint32_t correctedRotation = (static_cast<uint32_t>(rotation) + static_cast<uint32_t>(phyOffsetRotation)) %
10932         ROTATION_MOD;
10933     DMRect displayRegionCopy = displayRegion;
10934     DMRect displayAreaCopy = displayArea;
10935     switch (static_cast<Rotation>(correctedRotation)) {
10936         case Rotation::ROTATION_90:
10937             displayRegion.width_ = displayRegionCopy.height_;
10938             displayRegion.height_ = displayRegionCopy.width_;
10939             displayArea.width_ = displayAreaCopy.height_;
10940             displayArea.height_ = displayAreaCopy.width_;
10941             displayRegion.posX_ = displayRegionCopy.posY_;
10942             displayRegion.posY_ = static_cast<int32_t>(screenRegion.width_) -
10943                 (displayRegionCopy.posX_ + static_cast<int32_t>(displayRegionCopy.width_));
10944             displayArea.posX_ = displayAreaCopy.posY_;
10945             displayArea.posY_ = static_cast<int32_t>(screenRegion.width_) -
10946                 (displayAreaCopy.posX_ + static_cast<int32_t>(displayAreaCopy.width_));
10947             break;
10948         case Rotation::ROTATION_180:
10949             displayRegion.posX_ = static_cast<int32_t>(screenRegion.width_) -
10950                 (displayRegionCopy.posX_ + static_cast<int32_t>(displayRegionCopy.width_));
10951             displayRegion.posY_ = static_cast<int32_t>(screenRegion.height_) -
10952                 (displayRegionCopy.posY_ + static_cast<int32_t>(displayRegionCopy.height_));
10953             displayArea.posX_ = static_cast<int32_t>(screenRegion.width_) -
10954                 (displayAreaCopy.posX_ + static_cast<int32_t>(displayAreaCopy.width_));
10955             displayArea.posY_ = static_cast<int32_t>(screenRegion.height_) -
10956                 (displayAreaCopy.posY_ + static_cast<int32_t>(displayAreaCopy.height_));
10957             break;
10958         case Rotation::ROTATION_270:
10959             displayRegion.width_ = displayRegionCopy.height_;
10960             displayRegion.height_ = displayRegionCopy.width_;
10961             displayArea.width_ = displayAreaCopy.height_;
10962             displayArea.height_ = displayAreaCopy.width_;
10963             displayRegion.posX_ = static_cast<int32_t>(screenRegion.height_) -
10964                 (displayRegionCopy.posY_ + static_cast<int32_t>(displayRegionCopy.height_));
10965             displayRegion.posY_ = displayRegionCopy.posX_;
10966             displayArea.posX_ = static_cast<int32_t>(screenRegion.height_) -
10967                 (displayAreaCopy.posY_ + static_cast<int32_t>(displayAreaCopy.height_));
10968             displayArea.posY_ = displayAreaCopy.posX_;
10969             break;
10970         default:
10971             break;
10972     }
10973 }
10974 
CalculateScreenArea(const DMRect & displayRegion,const DMRect & displayArea,const DMRect & screenRegion,DMRect & screenArea)10975 void ScreenSessionManager::CalculateScreenArea(const DMRect& displayRegion, const DMRect& displayArea,
10976     const DMRect& screenRegion, DMRect& screenArea)
10977 {
10978     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
10979        screenArea = displayArea;
10980        return;
10981     }
10982     if (displayRegion == screenRegion) {
10983         screenArea = displayArea;
10984         return;
10985     }
10986     float ratioX = static_cast<float>(displayArea.posX_ - displayRegion.posX_) /
10987         static_cast<float>(displayRegion.width_);
10988     float ratioY = static_cast<float>(displayArea.posY_ - displayRegion.posY_) /
10989         static_cast<float>(displayRegion.height_);
10990     float ratioWidth = static_cast<float>(displayArea.width_) / static_cast<float>(displayRegion.width_);
10991     float ratioHeight = static_cast<float>(displayArea.height_) / static_cast<float>(displayRegion.height_);
10992     screenArea.posX_ = screenRegion.posX_ + static_cast<int32_t>(ratioX * screenRegion.width_);
10993     screenArea.posY_ = screenRegion.posY_ + static_cast<int32_t>(ratioY * screenRegion.height_);
10994     screenArea.width_ = static_cast<uint32_t>(ratioWidth * screenRegion.width_);
10995     screenArea.height_ = static_cast<uint32_t>(ratioHeight * screenRegion.height_);
10996 }
10997 
SetPrimaryDisplaySystemDpi(float virtualPixelRatio)10998 DMError ScreenSessionManager::SetPrimaryDisplaySystemDpi(float virtualPixelRatio)
10999 {
11000     sptr<DisplayInfo> displayInfo = GetPrimaryDisplayInfo();
11001     if (displayInfo == nullptr) {
11002         TLOGE(WmsLogTag::DMS, "displayInfo is null.");
11003         return DMError::DM_ERROR_NULLPTR;
11004     }
11005     ScreenId screenId = displayInfo->GetScreenId();
11006     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
11007     if (screenSession == nullptr) {
11008         TLOGE(WmsLogTag::DMS, "screenSession is null.");
11009         return DMError::DM_ERROR_NULLPTR;
11010     }
11011     TLOGI(WmsLogTag::DMS, "displayId: %{public}" PRIu64 " densityInCurResolution: %{public}f",
11012         displayInfo->GetDisplayId(), screenSession->GetDensityInCurResolution());
11013     screenSession->SetDensityInCurResolution(virtualPixelRatio);
11014     return DMError::DM_OK;
11015 }
11016 
SetVirtualScreenAutoRotation(ScreenId screenId,bool enable)11017 DMError ScreenSessionManager::SetVirtualScreenAutoRotation(ScreenId screenId, bool enable)
11018 {
11019     TLOGI(WmsLogTag::DMS, "enter");
11020     if (!SessionPermission::IsSystemCalling()) {
11021         TLOGE(WmsLogTag::DMS, "permission denied!");
11022         return DMError::DM_ERROR_INVALID_PERMISSION;
11023     }
11024 
11025     ScreenId rsScreenId = SCREEN_ID_INVALID;
11026     bool res = ConvertScreenIdToRsScreenId(screenId, rsScreenId);
11027     if (!res) {
11028         TLOGE(WmsLogTag::DMS, "convert screenId to rsScreenId failed");
11029         return DMError::DM_ERROR_INVALID_PARAM;
11030     }
11031     TLOGI(WmsLogTag::DMS, "unique screenId: %{public}" PRIu64 " rsScreenId: %{public}" PRIu64, screenId, rsScreenId);
11032 
11033     auto ret = rsInterface_.SetVirtualScreenAutoRotation(rsScreenId, enable);
11034     if (ret != StatusCode::SUCCESS) {
11035         TLOGE(WmsLogTag::DMS, "rsInterface error: %{public}d", ret);
11036         return DMError::DM_ERROR_INVALID_PARAM;
11037     }
11038     return DMError::DM_OK;
11039 }
11040 
SetScreenOffset(ScreenId screenId,float offsetX,float offsetY)11041 bool ScreenSessionManager::SetScreenOffset(ScreenId screenId, float offsetX, float offsetY)
11042 {
11043     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
11044     if (screenSession == nullptr) {
11045         TLOGE(WmsLogTag::DMS, "screenSession is null.");
11046         return false;
11047     }
11048     TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 " rsId_:%{public}" PRIu64 \
11049         " GetRSScreenId:%{public}" PRIu64 " offsetX:%{public}f, offsetY:%{public}f",
11050         screenId, screenSession->rsId_, screenSession->GetRSScreenId(), offsetX, offsetY);
11051     RSInterfaces::GetInstance().SetScreenOffset(screenSession->rsId_, offsetX, offsetY);
11052     return true;
11053 }
11054 
SetScreenPrivacyWindowTagSwitch(ScreenId screenId,const std::vector<std::string> & privacyWindowTag,bool enable)11055 DMError ScreenSessionManager::SetScreenPrivacyWindowTagSwitch(ScreenId screenId,
11056     const std::vector<std::string>& privacyWindowTag, bool enable)
11057 {
11058     if (!SessionPermission::IsSystemCalling()) {
11059         TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
11060             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
11061         return DMError::DM_ERROR_NOT_SYSTEM_APP;
11062     }
11063     auto screenSession = GetScreenSession(screenId);
11064     if (screenSession == nullptr) {
11065         TLOGE(WmsLogTag::DMS, "cannot find screenInfo: %{public}" PRIu64, screenId);
11066         return DMError::DM_ERROR_NULLPTR;
11067     }
11068     MockSessionManagerService::GetInstance().SetScreenPrivacyWindowTagSwitch(
11069         screenIdManager_.ConvertToRsScreenId(screenId), privacyWindowTag, enable);
11070     std::ostringstream oss;
11071     for (auto tag : privacyWindowTag) {
11072         oss << tag << ",";
11073     }
11074     TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 " privacyWindowTag:%{public}s, enable:%{public}d", screenId,
11075         oss.str().c_str(), enable);
11076     return DMError::DM_OK;
11077 }
11078 // LCOV_EXCL_STOP
11079 
GetPhyScreenId(ScreenId screenId)11080 ScreenId ScreenSessionManager::GetPhyScreenId(ScreenId screenId)
11081 {
11082     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice() &&
11083         GetCoordinationFlag() && screenId == SCREEN_ID_MAIN) {
11084         TLOGW(WmsLogTag::DMS, "Coordination phyScreen SCREEN_ID_FULL");
11085         return SCREEN_ID_FULL;
11086     }
11087     return screenId;
11088 }
11089 
UpdateCoordinationRefreshRate(uint32_t refreshRate)11090 void ScreenSessionManager::UpdateCoordinationRefreshRate(uint32_t refreshRate)
11091 {
11092     if (!FoldScreenStateInternel::IsSecondaryDisplayFoldDevice() || !GetCoordinationFlag()) {
11093         return;
11094     }
11095     sptr<ScreenSession> screenSession = GetScreenSession(SCREEN_ID_MAIN);
11096     if (!screenSession) {
11097         TLOGE(WmsLogTag::DMS, "screenSession SCREEN_ID_MAIN is null");
11098         return;
11099     }
11100     screenSession->UpdateRefreshRate(refreshRate);
11101     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::UPDATE_REFRESHRATE);
11102 }
11103 
SynchronizePowerStatus(ScreenPowerState state)11104 bool ScreenSessionManager::SynchronizePowerStatus(ScreenPowerState state)
11105 {
11106     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
11107         TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
11108             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
11109         return false;
11110     }
11111     TLOGI(WmsLogTag::DMS, "[UL_POWER] Synchronize power state: %{public}u", static_cast<uint32_t>(state));
11112 #ifdef FOLD_ABILITY_ENABLE
11113     ScreenPowerStatus status = ScreenPowerStatus::INVALID_POWER_STATUS;
11114     if (!GetPowerStatus(state, PowerStateChangeReason::STATE_CHANGE_REASON_SYNCHRONIZE_POWER_STATE, status)) {
11115         TLOGE(WmsLogTag::DMS, "GetPowerStatus failed");
11116         return false;
11117     }
11118     if (foldScreenController_ == nullptr) {
11119         TLOGE(WmsLogTag::DMS, "foldScreenController_ is null");
11120         return false;
11121     }
11122     ScreenId screenId = foldScreenController_->GetCurrentScreenId();
11123     auto rsSetScreenPowerStatusTask = [this, screenId, status] {
11124         SetRSScreenPowerStatus(screenId, status);
11125     };
11126     screenPowerTaskScheduler_->PostVoidSyncTask(rsSetScreenPowerStatusTask, "rsInterface_.SetScreenPowerStatus task");
11127 #endif
11128     return true;
11129 }
11130 
GetPowerTaskScheduler() const11131 std::shared_ptr<TaskScheduler> ScreenSessionManager::GetPowerTaskScheduler() const
11132 {
11133     return screenPowerTaskScheduler_;
11134 }
11135 
GetCancelSuspendStatus() const11136 bool ScreenSessionManager::GetCancelSuspendStatus() const
11137 {
11138     if (!sessionDisplayPowerController_) {
11139         TLOGE(WmsLogTag::DMS, "sessionDisplayPowerController_ is null");
11140         return false;
11141     }
11142     std::lock_guard<std::mutex> notifyLock(sessionDisplayPowerController_->notifyMutex_);
11143     return sessionDisplayPowerController_->needCancelNotify_ ||
11144             sessionDisplayPowerController_->canceledSuspend_;
11145 }
11146 
RegisterSettingDuringCallStateObserver()11147 void ScreenSessionManager::RegisterSettingDuringCallStateObserver()
11148 {
11149     TLOGI(WmsLogTag::DMS, "Register Setting During Call State Observer");
11150     SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { UpdateDuringCallState(); };
11151     ScreenSettingHelper::RegisterSettingDuringCallStateObserver(updateFunc);
11152 }
11153 
UpdateDuringCallState()11154 void ScreenSessionManager::UpdateDuringCallState()
11155 {
11156     TLOGI(WmsLogTag::DMS, "update during call state, current state: %{public}d", duringCallState_);
11157     bool ret = ScreenSettingHelper::GetSettingDuringCallState(duringCallState_);
11158     if (!ret) {
11159         TLOGE(WmsLogTag::DMS, "get setting during call state failed");
11160         return;
11161     }
11162     TLOGI(WmsLogTag::DMS, "get setting during call state: %{public}d", duringCallState_);
11163 #ifdef FOLD_ABILITY_ENABLE
11164     if (ScreenSceneConfig::IsSupportDuringCall() && !duringCallState_ && foldScreenController_ != nullptr &&
11165         foldScreenController_->GetDisplayMode() == FoldDisplayMode::SUB) {
11166         TLOGI(WmsLogTag::DMS, "duringcallstate exit, recover displaymode");
11167         foldScreenController_->RecoverDisplayMode();
11168     }
11169 #endif
11170 }
11171 
SetDuringCallState(bool value)11172 void ScreenSessionManager::SetDuringCallState(bool value)
11173 {
11174     bool ret = ScreenSettingHelper::SetSettingDuringCallState("during_call_state", value);
11175     TLOGI(WmsLogTag::DMS, "set during call state to %{public}d, ret:%{public}d", value, ret);
11176 }
11177 } // namespace OHOS::Rosen
11178