1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "session_manager/include/screen_session_manager.h"
17 
18 #include <csignal>
19 #include <cstdint>
20 #include <ctime>
21 #include <iomanip>
22 #include <string_ex.h>
23 #include <unique_fd.h>
24 
25 #include <hitrace_meter.h>
26 #ifdef DEVICE_STATUS_ENABLE
27 #include <interaction_manager.h>
28 #endif // DEVICE_STATUS_ENABLE
29 #include <ipc_skeleton.h>
30 #include <parameter.h>
31 #include <parameters.h>
32 #include <privacy_kit.h>
33 #include <system_ability_definition.h>
34 #include <transaction/rs_interfaces.h>
35 #include <xcollie/watchdog.h>
36 #include <hisysevent.h>
37 #include <power_mgr_client.h>
38 
39 #include "dm_common.h"
40 #include "fold_screen_state_internel.h"
41 #include "multi_screen_manager.h"
42 #include "pipeline/rs_node_map.h"
43 #include "scene_board_judgement.h"
44 #include "session_permission.h"
45 #include "screen_scene_config.h"
46 #include "surface_capture_future.h"
47 #include "sys_cap_util.h"
48 #include "permission.h"
49 #include "window_manager_hilog.h"
50 #include "screen_rotation_property.h"
51 #include "screen_sensor_connector.h"
52 #include "screen_setting_helper.h"
53 #include "screen_session_dumper.h"
54 #include "mock_session_manager_service.h"
55 #include "connection/screen_snapshot_picker_connection.h"
56 #include "connection/screen_cast_connection.h"
57 #include "publish/screen_session_publish.h"
58 #include "dms_xcollie.h"
59 
60 namespace OHOS::Rosen {
61 namespace {
62 const std::string SCREEN_SESSION_MANAGER_THREAD = "OS_ScreenSessionManager";
63 const std::string SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD = "OS_ScreenSessionManager_ScreenPower";
64 const std::string SCREEN_CAPTURE_PERMISSION = "ohos.permission.CAPTURE_SCREEN";
65 const std::string CUSTOM_SCREEN_CAPTURE_PERMISSION = "ohos.permission.CUSTOM_SCREEN_CAPTURE";
66 const std::string BOOTEVENT_BOOT_COMPLETED = "bootevent.boot.completed";
67 const int32_t CV_WAIT_SCREENON_MS = 300;
68 const int32_t CV_WAIT_SCREENOFF_MS_MAX = 3000;
69 const int32_t CV_WAIT_SCREENOFF_MS = 1500;
70 const int32_t CV_WAIT_BUFFER_AVAILABLE_MS = 8 * 1000 * 1000;
71 const int32_t CV_WAIT_SCBSWITCH_MS = 3000;
72 const int64_t SWITCH_USER_DISPLAYMODE_CHANGE_DELAY = 500;
73 const std::string STATUS_FOLD_HALF = "-z";
74 const std::string STATUS_EXPAND = "-y";
75 const std::string STATUS_FOLD = "-p";
76 const std::string SETTING_LOCKED_KEY = "settings.general.accelerometer_rotation_status";
77 const ScreenId SCREEN_ID_DEFAULT = 0;
78 const ScreenId SCREEN_ID_FULL = 0;
79 const ScreenId SCREEN_ID_MAIN = 5;
80 const ScreenId SCREEN_ID_PC = 4;
81 const ScreenId SCREEN_ID_PC_MAIN = 9;
82 const ScreenId MINIMUM_VIRTUAL_SCREEN_ID = 1000;
83 constexpr int32_t INVALID_UID = -1;
84 constexpr int32_t INVALID_USER_ID = -1;
85 constexpr int32_t INVALID_SCB_PID = -1;
86 constexpr int32_t BASE_USER_RANGE = 200000;
87 static bool g_foldScreenFlag = system::GetParameter("const.window.foldscreen.type", "") != "";
88 static int32_t g_screenRotationOffSet = system::GetIntParameter<int32_t>("const.fold.screen_rotation.offset", 0);
89 static const int32_t ROTATION_90 = 1;
90 static const int32_t ROTATION_270 = 3;
91 static const int32_t AUTO_ROTATE_OFF = 0;
92 static const int NOTIFY_EVENT_FOR_DUAL_FAILED = 0;
93 static const int NOTIFY_EVENT_FOR_DUAL_SUCESS = 1;
94 static const int NO_NEED_NOTIFY_EVENT_FOR_DUAL = 2;
95 const unsigned int XCOLLIE_TIMEOUT_10S = 10;
96 const unsigned int XCOLLIE_TIMEOUT_5S = 5;
97 constexpr int32_t CAST_WIRED_PROJECTION_START = 1005;
98 constexpr int32_t CAST_WIRED_PROJECTION_STOP = 1007;
99 constexpr int32_t RES_FAILURE_FOR_PRIVACY_WINDOW = -2;
100 constexpr int32_t REMOVE_DISPLAY_MODE = 0;
101 constexpr int32_t IRREGULAR_REFRESH_RATE_SKIP_THRETHOLD = 10;
102 
103 const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
104 constexpr int32_t FOLDABLE_DEVICE { 2 };
105 constexpr float DEFAULT_PIVOT = 0.5f;
106 constexpr float DEFAULT_SCALE = 1.0f;
107 static const constexpr char* SET_SETTING_DPI_KEY {"default_display_dpi"};
108 
109 // based on the bundle_util
GetUserIdByCallingUid()110 inline int32_t GetUserIdByCallingUid()
111 {
112     int32_t uid = IPCSkeleton::GetCallingUid();
113     TLOGD(WmsLogTag::WMS_MULTI_USER, "get calling uid(%{public}d)", uid);
114     if (uid <= INVALID_UID) {
115         TLOGE(WmsLogTag::WMS_MULTI_USER, "uid is illegal: %{public}d", uid);
116         return INVALID_USER_ID;
117     }
118     return uid / BASE_USER_RANGE;
119 }
120 } // namespace
121 
122 WM_IMPLEMENT_SINGLE_INSTANCE(ScreenSessionManager)
123 
124 const bool REGISTER_RESULT = !SceneBoardJudgement::IsSceneBoardEnabled() ? false :
125     SystemAbility::MakeAndRegisterAbility(&ScreenSessionManager::GetInstance());
126 
ScreenSessionManager()127 ScreenSessionManager::ScreenSessionManager()
128     : SystemAbility(DISPLAY_MANAGER_SERVICE_SA_ID, true), rsInterface_(RSInterfaces::GetInstance())
129 {
130     screenEventTracker_.RecordEvent("Dms construct.");
131     LoadScreenSceneXml();
132     screenOffDelay_ = CV_WAIT_SCREENOFF_MS;
133     taskScheduler_ = std::make_shared<TaskScheduler>(SCREEN_SESSION_MANAGER_THREAD);
134     screenPowerTaskScheduler_ = std::make_shared<TaskScheduler>(SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD);
135     screenCutoutController_ = new (std::nothrow) ScreenCutoutController();
136     if (!screenCutoutController_) {
137         TLOGE(WmsLogTag::DMS, "screenCutoutController_ is nullptr");
138     }
139     sessionDisplayPowerController_ = new SessionDisplayPowerController(
140         std::bind(&ScreenSessionManager::NotifyDisplayStateChange, this,
141             std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
142     if (g_foldScreenFlag) {
143         HandleFoldScreenPowerInit();
144     }
145     WatchParameter(BOOTEVENT_BOOT_COMPLETED.c_str(), BootFinishedCallback, this);
146 }
147 
ConvertOffsetToCorrectRotation(int32_t phyOffset)148 ScreenRotation ScreenSessionManager::ConvertOffsetToCorrectRotation(int32_t phyOffset)
149 {
150     ScreenRotation offsetRotation = ScreenRotation::ROTATION_0;
151     switch (phyOffset) {
152         case 90: // Rotation 90 degree
153             offsetRotation = ScreenRotation::ROTATION_270;
154             break;
155         case 180: // Rotation 180 degree
156             offsetRotation = ScreenRotation::ROTATION_180;
157             break;
158         case 270: // Rotation 270 degree
159             offsetRotation = ScreenRotation::ROTATION_90;
160             break;
161         default:
162             offsetRotation = ScreenRotation::ROTATION_0;
163             break;
164     }
165     return offsetRotation;
166 }
167 
HandleFoldScreenPowerInit()168 void ScreenSessionManager::HandleFoldScreenPowerInit()
169 {
170     TLOGI(WmsLogTag::DMS, "Enter");
171     foldScreenController_ = new (std::nothrow) FoldScreenController(displayInfoMutex_, screenPowerTaskScheduler_);
172     if (!foldScreenController_) {
173         TLOGE(WmsLogTag::DMS, "foldScreenController_ is nullptr");
174         return;
175     }
176     foldScreenController_->SetOnBootAnimation(true);
177     if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
178         SetFoldScreenPowerInit([&]() {
179             foldScreenController_->BootAnimationFinishPowerInit();
180             FixPowerStatus();
181             foldScreenController_->SetOnBootAnimation(false);
182             RegisterApplicationStateObserver();
183         });
184     } else {
185         // 后续其他设备rs上电规格将陆续迁移到BootAnimationFinishPowerInit中
186         FoldScreenPowerInit();
187     }
188 }
189 
FoldScreenPowerInit()190 void ScreenSessionManager::FoldScreenPowerInit()
191 {
192     SetFoldScreenPowerInit([&]() {
193         int64_t timeStamp = 50;
194         #ifdef TP_FEATURE_ENABLE
195         int32_t tpType = 12;
196         std::string fullTpChange = "0";
197         std::string mainTpChange = "1";
198         #endif
199         if (!foldScreenController_) {
200             TLOGE(WmsLogTag::DMS, "foldScreenController_ is nullptr");
201             return;
202         }
203         ScreenId currentScreenId = foldScreenController_->GetCurrentScreenId();
204         if (currentScreenId == SCREEN_ID_FULL) {
205             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Full animation Init 1.");
206             rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF_FAKE);
207             rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
208             std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
209             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Full animation Init 2.");
210             #ifdef TP_FEATURE_ENABLE
211             rsInterface_.SetTpFeatureConfig(tpType, fullTpChange.c_str());
212             #endif
213             rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
214             if (foldScreenController_ != nullptr) {
215                 foldScreenController_->AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, REMOVE_DISPLAY_MODE);
216             }
217             rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
218         } else if (currentScreenId == SCREEN_ID_MAIN) {
219             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Main animation Init 3.");
220             rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF_FAKE);
221             rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
222             std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
223             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Main animation Init 4.");
224             #ifdef TP_FEATURE_ENABLE
225             rsInterface_.SetTpFeatureConfig(tpType, mainTpChange.c_str());
226             #endif
227             rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
228             if (foldScreenController_ != nullptr) {
229                 foldScreenController_->AddOrRemoveDisplayNodeToTree(SCREEN_ID_FULL, REMOVE_DISPLAY_MODE);
230             }
231             rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
232         } else {
233             TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Init, invalid active screen id");
234         }
235         FixPowerStatus();
236         foldScreenController_->SetOnBootAnimation(false);
237         RegisterApplicationStateObserver();
238     });
239 }
240 
FixPowerStatus()241 void ScreenSessionManager::FixPowerStatus()
242 {
243     if (!PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
244         PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
245         TLOGI(WmsLogTag::DMS, "Fix Screen Power State");
246     }
247 }
248 
Init()249 void ScreenSessionManager::Init()
250 {
251     if (system::GetParameter("soc.boot.mode", "") != "rescue") {
252         constexpr uint64_t interval = 5 * 1000; // 5 second
253         if (HiviewDFX::Watchdog::GetInstance().AddThread(
254             SCREEN_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
255             TLOGW(WmsLogTag::DMS, "Add thread %{public}s to watchdog failed.", SCREEN_SESSION_MANAGER_THREAD.c_str());
256         }
257 
258         if (HiviewDFX::Watchdog::GetInstance().AddThread(
259             SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD, screenPowerTaskScheduler_->GetEventHandler(), interval)) {
260             TLOGW(WmsLogTag::DMS, "Add thread %{public}s to watchdog failed.",
261                 SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD.c_str());
262         }
263     } else {
264         TLOGI(WmsLogTag::DMS, "Dms in rescue mode, not need watchdog.");
265         screenEventTracker_.RecordEvent("Dms in rescue mode, not need watchdog.");
266     }
267 
268     auto stringConfig = ScreenSceneConfig::GetStringConfig();
269     if (stringConfig.count("defaultDisplayCutoutPath") != 0) {
270         std::string defaultDisplayCutoutPath = static_cast<std::string>(stringConfig["defaultDisplayCutoutPath"]);
271         TLOGD(WmsLogTag::DMS, "defaultDisplayCutoutPath = %{public}s.", defaultDisplayCutoutPath.c_str());
272         ScreenSceneConfig::SetCutoutSvgPath(GetDefaultScreenId(), defaultDisplayCutoutPath);
273     }
274 
275     RegisterScreenChangeListener();
276     if (!ScreenSceneConfig::IsSupportRotateWithSensor()) {
277         TLOGI(WmsLogTag::DMS, "Current device type not support SetSensorSubscriptionEnabled.");
278     } else if (GetScreenPower(SCREEN_ID_FULL) == ScreenPowerState::POWER_ON) {
279         // 多屏设备只要有屏幕亮,GetScreenPower获取的任意一块屏幕状态均是ON
280         SetSensorSubscriptionEnabled();
281         screenEventTracker_.RecordEvent("Dms subscribed to sensor successfully.");
282     }
283 
284     // publish init
285     ScreenSessionPublish::GetInstance().InitPublishEvents();
286     screenEventTracker_.RecordEvent("Dms init end.");
287 }
288 
OnStart()289 void ScreenSessionManager::OnStart()
290 {
291     TLOGI(WmsLogTag::DMS, "DMS SA OnStart");
292     DmsXcollie dmsXcollie("DMS:OnStart", XCOLLIE_TIMEOUT_10S,
293         [this](void *) { screenEventTracker_.LogWarningAllInfos(); });
294     Init();
295     sptr<ScreenSessionManager> dms(this);
296     dms->IncStrongRef(nullptr);
297     if (!Publish(dms)) {
298         TLOGE(WmsLogTag::DMS, "Publish DMS failed");
299         return;
300     }
301     TLOGI(WmsLogTag::DMS, "DMS SA AddSystemAbilityListener");
302     (void)AddSystemAbilityListener(SENSOR_SERVICE_ABILITY_ID);
303     screenEventTracker_.RecordEvent("Dms AddSystemAbilityListener finished.");
304     TLOGI(WmsLogTag::DMS, "DMS SA OnStart end");
305     screenEventTracker_.RecordEvent("Dms onstart end.");
306 }
307 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)308 void ScreenSessionManager::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
309 {
310     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "OnAddSystemAbility: %d", systemAbilityId);
311     TLOGI(WmsLogTag::DMS, "receive sa add:%{public}d", systemAbilityId);
312     if (systemAbilityId == SENSOR_SERVICE_ABILITY_ID) {
313 #ifdef SENSOR_ENABLE
314         if (!g_foldScreenFlag) {
315             TLOGI(WmsLogTag::DMS, "current device is not fold phone.");
316             return;
317         }
318         if (!foldScreenController_ || isFoldScreenOuterScreenReady_) {
319             TLOGI(WmsLogTag::DMS, "foldScreenController_ is null or outer screen is not ready.");
320             return;
321         }
322         if (GetDisplayState(foldScreenController_->GetCurrentScreenId()) == DisplayState::ON) {
323             FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
324             TLOGI(WmsLogTag::DMS, "Recover Posture sensor finished");
325         }
326 
327         FoldScreenSensorManager::GetInstance().RegisterHallCallback();
328         TLOGI(WmsLogTag::DMS, "Recover Hall sensor finished");
329         screenEventTracker_.RecordEvent("Dms recover Posture and Hall sensor finished.");
330 #endif
331     }
332 }
333 
RegisterDisplayManagerAgent(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)334 DMError ScreenSessionManager::RegisterDisplayManagerAgent(
335     const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
336 {
337     TLOGI(WmsLogTag::DMS, " called type: %{public}u", type);
338     DmsXcollie dmsXcollie("DMS:RegisterDisplayManagerAgent", XCOLLIE_TIMEOUT_10S);
339     if ((type == DisplayManagerAgentType::SCREEN_EVENT_LISTENER ||
340         type == DisplayManagerAgentType::PRIVATE_WINDOW_LISTENER) &&
341         !SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
342         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
343             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
344         return DMError::DM_ERROR_NOT_SYSTEM_APP;
345     }
346     if (type < DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER
347         || type >= DisplayManagerAgentType::DISPLAY_MANAGER_MAX_AGENT_TYPE) {
348         TLOGE(WmsLogTag::DMS, "DisplayManagerAgentType: %{public}u", static_cast<uint32_t>(type));
349         return DMError::DM_ERROR_INVALID_PARAM;
350     }
351     if ((displayManagerAgent == nullptr) || (displayManagerAgent->AsObject() == nullptr)) {
352         TLOGE(WmsLogTag::DMS, "displayManagerAgent invalid");
353         return DMError::DM_ERROR_NULLPTR;
354     }
355     return dmAgentContainer_.RegisterAgent(displayManagerAgent, type) ? DMError::DM_OK :DMError::DM_ERROR_NULLPTR;
356 }
357 
UnregisterDisplayManagerAgent(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)358 DMError ScreenSessionManager::UnregisterDisplayManagerAgent(
359     const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
360 {
361     TLOGI(WmsLogTag::DMS, " called type: %{public}u", type);
362     if ((type == DisplayManagerAgentType::SCREEN_EVENT_LISTENER ||
363         type == DisplayManagerAgentType::PRIVATE_WINDOW_LISTENER) &&
364         !SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
365         TLOGE(WmsLogTag::DMS, "unregister display manager agent permission denied!");
366         TLOGE(WmsLogTag::DMS, "calling clientName: %{public}s, calling pid: %{public}d",
367             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
368         return DMError::DM_ERROR_NOT_SYSTEM_APP;
369     }
370     if ((displayManagerAgent == nullptr) || (displayManagerAgent->AsObject() == nullptr)) {
371         TLOGE(WmsLogTag::DMS, "displayManagerAgent invalid");
372         return DMError::DM_ERROR_NULLPTR;
373     }
374     return dmAgentContainer_.UnregisterAgent(displayManagerAgent, type) ? DMError::DM_OK :DMError::DM_ERROR_NULLPTR;
375 }
376 
LoadScreenSceneXml()377 void ScreenSessionManager::LoadScreenSceneXml()
378 {
379     if (ScreenSceneConfig::LoadConfigXml()) {
380         ScreenSceneConfig::DumpConfig();
381         ConfigureScreenScene();
382     }
383 }
384 
ConfigureScreenScene()385 void ScreenSessionManager::ConfigureScreenScene()
386 {
387     auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
388     auto enableConfig = ScreenSceneConfig::GetEnableConfig();
389     auto stringConfig = ScreenSceneConfig::GetStringConfig();
390     ConfigureDpi();
391     if (numbersConfig.count("defaultDeviceRotationOffset") != 0) {
392         defaultDeviceRotationOffset_ = static_cast<uint32_t>(numbersConfig["defaultDeviceRotationOffset"][0]);
393         TLOGD(WmsLogTag::DMS, "defaultDeviceRotationOffset = %{public}u", defaultDeviceRotationOffset_);
394     }
395     if (enableConfig.count("isWaterfallDisplay") != 0) {
396         bool isWaterfallDisplay = static_cast<bool>(enableConfig["isWaterfallDisplay"]);
397         TLOGD(WmsLogTag::DMS, "isWaterfallDisplay = %d", isWaterfallDisplay);
398     }
399     if (numbersConfig.count("curvedScreenBoundary") != 0) {
400         std::vector<int> vtBoundary = static_cast<std::vector<int>>(numbersConfig["curvedScreenBoundary"]);
401         TLOGD(WmsLogTag::DMS, "vtBoundary.size=%{public}u", static_cast<uint32_t>(vtBoundary.size()));
402     }
403     if (stringConfig.count("subDisplayCutoutPath") != 0) {
404         std::string subDisplayCutoutPath = static_cast<std::string>(stringConfig["subDisplayCutoutPath"]);
405         TLOGD(WmsLogTag::DMS, "subDisplayCutoutPath = %{public}s.", subDisplayCutoutPath.c_str());
406         ScreenSceneConfig::SetSubCutoutSvgPath(subDisplayCutoutPath);
407     }
408     if (stringConfig.count("rotationPolicy") != 0) {
409         std::string rotationPolicy = static_cast<std::string>(stringConfig["rotationPolicy"]);
410         TLOGD(WmsLogTag::DMS, "rotationPolicy = %{public}s.", rotationPolicy.c_str());
411         deviceScreenConfig_.rotationPolicy_ = rotationPolicy;
412     }
413     if (stringConfig.count("defaultRotationPolicy") != 0) {
414         std::string defaultRotationPolicy = stringConfig["defaultRotationPolicy"];
415         TLOGD(WmsLogTag::DMS, "defaultRotationPolicy = %{public}s.", defaultRotationPolicy.c_str());
416         deviceScreenConfig_.defaultRotationPolicy_ = defaultRotationPolicy;
417     }
418     if (enableConfig.count("isRightPowerButton") != 0) {
419         bool isRightPowerButton = static_cast<bool>(enableConfig["isRightPowerButton"]);
420         TLOGD(WmsLogTag::DMS, "isRightPowerButton = %d", isRightPowerButton);
421         deviceScreenConfig_.isRightPowerButton_ = isRightPowerButton;
422     }
423     ConfigureWaterfallDisplayCompressionParams();
424     ConfigureCastParams();
425 
426     if (numbersConfig.count("buildInDefaultOrientation") != 0) {
427         Orientation orientation = static_cast<Orientation>(numbersConfig["buildInDefaultOrientation"][0]);
428         TLOGD(WmsLogTag::DMS, "orientation = %d", orientation);
429     }
430     allDisplayPhysicalResolution_ = ScreenSceneConfig::GetAllDisplayPhysicalConfig();
431 }
432 
ConfigureDpi()433 void ScreenSessionManager::ConfigureDpi()
434 {
435     auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
436     if (numbersConfig.count("dpi") != 0) {
437         uint32_t densityDpi = static_cast<uint32_t>(numbersConfig["dpi"][0]);
438         TLOGI(WmsLogTag::DMS, "densityDpi = %u", densityDpi);
439         if (densityDpi >= DOT_PER_INCH_MINIMUM_VALUE && densityDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
440             isDensityDpiLoad_ = true;
441             defaultDpi = densityDpi;
442             cachedSettingDpi_ = defaultDpi;
443             densityDpi_ = static_cast<float>(densityDpi) / BASELINE_DENSITY;
444         }
445     }
446     if (numbersConfig.count("subDpi") != 0) {
447         uint32_t subDensityDpi = static_cast<uint32_t>(numbersConfig["subDpi"][0]);
448         TLOGI(WmsLogTag::DMS, "subDensityDpi = %u", subDensityDpi);
449         if (subDensityDpi >= DOT_PER_INCH_MINIMUM_VALUE && subDensityDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
450             isDensityDpiLoad_ = true;
451             subDensityDpi_ = static_cast<float>(subDensityDpi) / BASELINE_DENSITY;
452         }
453     }
454 }
455 
ConfigureCastParams()456 void ScreenSessionManager::ConfigureCastParams()
457 {
458     auto stringConfig = ScreenSceneConfig::GetStringConfig();
459     if (stringConfig.count("castBundleName") == 0) {
460         TLOGE(WmsLogTag::DMS, "not find cast bundleName in config xml");
461         return;
462     }
463     std::string castBundleName = static_cast<std::string>(stringConfig["castBundleName"]);
464     TLOGD(WmsLogTag::DMS, "castBundleName = %{public}s", castBundleName.c_str());
465     ScreenCastConnection::GetInstance().SetBundleName(castBundleName);
466     if (stringConfig.count("castAbilityName") == 0) {
467         TLOGE(WmsLogTag::DMS, "not find cast ability in config xml");
468         return;
469     }
470     std::string castAbilityName = static_cast<std::string>(stringConfig["castAbilityName"]);
471     TLOGD(WmsLogTag::DMS, "castAbilityName = %{public}s", castAbilityName.c_str());
472     ScreenCastConnection::GetInstance().SetAbilityName(castAbilityName);
473 }
474 
ConfigureWaterfallDisplayCompressionParams()475 void ScreenSessionManager::ConfigureWaterfallDisplayCompressionParams()
476 {
477     auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
478     auto enableConfig = ScreenSceneConfig::GetEnableConfig();
479     if (enableConfig.count("isWaterfallAreaCompressionEnableWhenHorizontal") != 0) {
480         bool enable = static_cast<bool>(enableConfig["isWaterfallAreaCompressionEnableWhenHorizontal"]);
481         TLOGD(WmsLogTag::DMS, "isWaterfallAreaCompressionEnableWhenHorizontal=%d.", enable);
482     }
483     ScreenSceneConfig::SetCurvedCompressionAreaInLandscape();
484 }
485 
ConfigureScreenSnapshotParams()486 void ScreenSessionManager::ConfigureScreenSnapshotParams()
487 {
488     auto stringConfig = ScreenSceneConfig::GetStringConfig();
489     if (stringConfig.count("screenSnapshotBundleName") == 0) {
490         TLOGE(WmsLogTag::DMS, "not find screen snapshot bundleName in config xml");
491         return;
492     }
493     std::string screenSnapshotBundleName = static_cast<std::string>(stringConfig["screenSnapshotBundleName"]);
494     TLOGD(WmsLogTag::DMS, "screenSnapshotBundleName = %{public}s.", screenSnapshotBundleName.c_str());
495     ScreenSnapshotPickerConnection::GetInstance().SetBundleName(screenSnapshotBundleName);
496     if (stringConfig.count("screenSnapshotAbilityName") == 0) {
497         TLOGE(WmsLogTag::DMS, "not find screen snapshot ability in config xml");
498         return;
499     }
500     std::string screenSnapshotAbilityName = static_cast<std::string>(stringConfig["screenSnapshotAbilityName"]);
501     TLOGD(WmsLogTag::DMS, "screenSnapshotAbilityName = %{public}s.", screenSnapshotAbilityName.c_str());
502     ScreenSnapshotPickerConnection::GetInstance().SetAbilityName(screenSnapshotAbilityName);
503 }
504 
RegisterScreenChangeListener()505 void ScreenSessionManager::RegisterScreenChangeListener()
506 {
507     TLOGI(WmsLogTag::DMS, "Register screen change listener.");
508     auto res = rsInterface_.SetScreenChangeCallback(
509         [this](ScreenId screenId, ScreenEvent screenEvent) { OnScreenChange(screenId, screenEvent); });
510     if (res != StatusCode::SUCCESS) {
511         auto task = [this]() { RegisterScreenChangeListener(); };
512         taskScheduler_->PostAsyncTask(task, "RegisterScreenChangeListener", 50); // Retry after 50 ms.
513         screenEventTracker_.RecordEvent("Dms OnScreenChange register failed.");
514     } else {
515         screenEventTracker_.RecordEvent("Dms OnScreenChange register success.");
516     }
517 }
518 
RegisterRefreshRateChangeListener()519 void ScreenSessionManager::RegisterRefreshRateChangeListener()
520 {
521     static bool isRegisterRefreshRateListener = false;
522     if (!isRegisterRefreshRateListener) {
523         auto res = rsInterface_.RegisterHgmRefreshRateUpdateCallback(
524             [this](uint32_t refreshRate) { OnHgmRefreshRateChange(refreshRate); });
525         if (res != StatusCode::SUCCESS) {
526             TLOGE(WmsLogTag::DMS, "Register refresh rate mode change listener failed.");
527             screenEventTracker_.RecordEvent("Dms RefreshRateChange register failed.");
528         } else {
529             isRegisterRefreshRateListener = true;
530             screenEventTracker_.RecordEvent("Dms RefreshRateChange register success.");
531         }
532     }
533 }
534 
OnVirtualScreenChange(ScreenId screenId,ScreenEvent screenEvent)535 void ScreenSessionManager::OnVirtualScreenChange(ScreenId screenId, ScreenEvent screenEvent)
536 {
537     TLOGI(WmsLogTag::DMS, "Notify scb virtual screen change, ScreenId: %{public}" PRIu64 ", ScreenEvent: %{public}d",
538         screenId, static_cast<int>(screenEvent));
539     auto screenSession = GetScreenSession(screenId);
540     if (!screenSession) {
541         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
542         return;
543     }
544     if (screenEvent == ScreenEvent::CONNECTED) {
545         if (clientProxy_) {
546             clientProxy_->OnScreenConnectionChanged(screenId, ScreenEvent::CONNECTED,
547                 screenSession->GetRSScreenId(), screenSession->GetName());
548         }
549         return;
550     }
551     if (screenEvent == ScreenEvent::DISCONNECTED) {
552         if (clientProxy_) {
553             clientProxy_->OnScreenConnectionChanged(screenId, ScreenEvent::DISCONNECTED,
554                 screenSession->GetRSScreenId(), screenSession->GetName());
555         }
556     }
557 }
558 
IsDefaultMirrorMode(ScreenId screenId)559 bool ScreenSessionManager::IsDefaultMirrorMode(ScreenId screenId)
560 {
561     if (screenId != SCREEN_ID_MAIN && screenId != SCREEN_ID_FULL &&
562         screenId != SCREEN_ID_PC_MAIN && screenId != SCREEN_ID_PC) {
563         return true;
564     }
565     return false;
566 }
567 
FreeDisplayMirrorNodeInner(const sptr<ScreenSession> mirrorSession)568 void ScreenSessionManager::FreeDisplayMirrorNodeInner(const sptr<ScreenSession> mirrorSession)
569 {
570     if (mirrorSession == nullptr) {
571         return;
572     }
573     std::shared_ptr<RSDisplayNode> displayNode = mirrorSession->GetDisplayNode();
574     if (displayNode == nullptr) {
575         return;
576     }
577     hdmiScreenCount_ = hdmiScreenCount_ > 0 ? hdmiScreenCount_ - 1 : 0;
578     NotifyCaptureStatusChanged();
579     displayNode->RemoveFromTree();
580     mirrorSession->ReleaseDisplayNode();
581     displayNode = nullptr;
582     auto transactionProxy = RSTransactionProxy::GetInstance();
583     if (transactionProxy != nullptr) {
584         TLOGI(WmsLogTag::DMS, "FreeDisplayMirrorNodeInner free displayNode");
585         transactionProxy->FlushImplicitTransaction();
586     }
587 }
588 
SetScreenCorrection()589 void ScreenSessionManager::SetScreenCorrection()
590 {
591     std::ostringstream oss;
592     if (g_foldScreenFlag) {
593         if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
594             auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_MAIN,
595                 static_cast<ScreenRotation>(ROTATION_90));
596             oss << "main screenRotationOffSet: " << g_screenRotationOffSet << " ret value: " << ret;
597         } else {
598             auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_FULL,
599                 static_cast<ScreenRotation>(g_screenRotationOffSet));
600             oss << "full screenRotationOffSet: " << g_screenRotationOffSet << " ret value: " << ret;
601         }
602     } else {
603         std::vector<std::string> phyOffsets = FoldScreenStateInternel::GetPhyRotationOffset();
604         int32_t phyOffset = static_cast<int32_t>(std::stoi(phyOffsets[0]));
605         ScreenRotation correctRotation = ConvertOffsetToCorrectRotation(phyOffset);
606         auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_DEFAULT, correctRotation);
607         oss << "phyOffset: " << phyOffset << " correctRotation value: " <<
608             static_cast<int32_t>(correctRotation) << " ret value: " << ret;
609     }
610     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
611     screenEventTracker_.RecordEvent(oss.str());
612 }
613 
OnScreenChange(ScreenId screenId,ScreenEvent screenEvent)614 void ScreenSessionManager::OnScreenChange(ScreenId screenId, ScreenEvent screenEvent)
615 {
616     std::ostringstream oss;
617     oss << "OnScreenChange triggered. screenId: " << static_cast<int32_t>(screenId)
618         << "  screenEvent: " << static_cast<int32_t>(screenEvent);
619     screenEventTracker_.RecordEvent(oss.str());
620     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " screenEvent: %{public}d",
621         screenId, static_cast<int>(screenEvent));
622     SetScreenCorrection();
623     auto screenSession = GetOrCreateScreenSession(screenId);
624     if (!screenSession) {
625         TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
626         return;
627     }
628 
629     if (foldScreenController_ != nullptr) {
630         screenSession->SetFoldScreen(true);
631     }
632     HandleScreenEvent(screenSession, screenId, screenEvent);
633 }
634 
NotifyScreenModeChange()635 void ScreenSessionManager::NotifyScreenModeChange()
636 {
637     auto task = [=] {
638         auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER);
639         if (agents.empty()) {
640             return;
641         }
642         std::vector<sptr<ScreenInfo>> screenInfos;
643         std::vector<ScreenId> screenIds = GetAllScreenIds();
644         for (auto screenId : screenIds) {
645             auto screenSession = GetScreenSession(screenId);
646             screenInfos.emplace_back(screenSession->ConvertToScreenInfo());
647         }
648         for (auto& agent : agents) {
649             int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
650             if (!IsFreezed(agentPid, DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER)) {
651                 agent->NotifyScreenModeChange(screenInfos);
652             }
653         }
654     };
655     taskScheduler_->PostAsyncTask(task, "NotifyScreenModeChange");
656 }
657 
SendCastEvent(const bool & isPlugIn)658 void ScreenSessionManager::SendCastEvent(const bool &isPlugIn)
659 {
660     TLOGI(WmsLogTag::DMS, "SendCastEvent entry isPlugIn:%{public}d", isPlugIn);
661     if (!ScreenCastConnection::GetInstance().CastConnectExtension(static_cast<int32_t>(isPlugIn))) {
662         TLOGE(WmsLogTag::DMS, "CastConnectionExtension failed");
663         return;
664     }
665     if (!ScreenCastConnection::GetInstance().IsConnectedSync()) {
666         TLOGE(WmsLogTag::DMS, "CastConnectionExtension connected failed");
667         ScreenCastConnection::GetInstance().CastDisconnectExtension();
668         return;
669     }
670     MessageParcel data;
671     MessageParcel reply;
672     if (isPlugIn) {
673         ScreenCastConnection::GetInstance().SendMessageToCastService(CAST_WIRED_PROJECTION_START, data, reply);
674     } else {
675         ScreenCastConnection::GetInstance().SendMessageToCastService(CAST_WIRED_PROJECTION_STOP, data, reply);
676     }
677     ScreenCastConnection::GetInstance().CastDisconnectExtension();
678 }
679 
NotifyCastWhenScreenConnectChange(bool isConnected)680 void ScreenSessionManager::NotifyCastWhenScreenConnectChange(bool isConnected)
681 {
682     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
683         TLOGE(WmsLogTag::DMS, "permission denied! calling clientName: %{public}s, calling pid: %{public}d",
684             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
685         return;
686     }
687     if (isConnected) {
688         auto task = [this]() {
689             SendCastEvent(true);
690             ScreenSessionPublish::GetInstance().PublishCastPlugInEvent();
691         };
692         taskScheduler_->PostAsyncTask(task, "SendCastEventTrue");
693         TLOGI(WmsLogTag::DMS, "PostAsyncTask SendCastEventTrue");
694     } else {
695         auto task = [this]() {
696             SendCastEvent(false);
697             ScreenSessionPublish::GetInstance().PublishCastPlugOutEvent();
698         };
699         taskScheduler_->PostAsyncTask(task, "SendCastEventFalse");
700         TLOGI(WmsLogTag::DMS, "PostAsyncTask SendCastEventFalse");
701     }
702 }
703 
PhyMirrorConnectWakeupScreen()704 void ScreenSessionManager::PhyMirrorConnectWakeupScreen()
705 {
706     if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "mirror") {
707         TLOGI(WmsLogTag::DMS, "Connect to an external screen to wakeup the phone screen");
708         FixPowerStatus();
709     }
710 }
711 
HandleScreenEvent(sptr<ScreenSession> screenSession,ScreenId screenId,ScreenEvent screenEvent)712 void ScreenSessionManager::HandleScreenEvent(sptr<ScreenSession> screenSession,
713     ScreenId screenId, ScreenEvent screenEvent)
714 {
715     bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
716     if (screenEvent == ScreenEvent::CONNECTED) {
717         if (phyMirrorEnable) {
718             PhyMirrorConnectWakeupScreen();
719             NotifyCastWhenScreenConnectChange(true);
720         }
721         if (foldScreenController_ != nullptr) {
722             if ((screenId == 0 || (screenId == SCREEN_ID_MAIN && isCoordinationFlag_ ==true)) &&
723                 clientProxy_) {
724                 clientProxy_->OnScreenConnectionChanged(screenId, ScreenEvent::CONNECTED,
725                     screenSession->GetRSScreenId(), screenSession->GetName());
726             }
727             return;
728         }
729 
730         if (clientProxy_ && !phyMirrorEnable) {
731             clientProxy_->OnScreenConnectionChanged(screenId, ScreenEvent::CONNECTED,
732                 screenSession->GetRSScreenId(), screenSession->GetName());
733         }
734         if (phyMirrorEnable) {
735             NotifyScreenConnected(screenSession->ConvertToScreenInfo());
736             NotifyDisplayCreate(screenSession->ConvertToDisplayInfo());
737             isPhyScreenConnected_ = true;
738         }
739         return;
740     } else if (screenEvent == ScreenEvent::DISCONNECTED) {
741         if (phyMirrorEnable) {
742             NotifyScreenDisconnected(screenSession->GetScreenId());
743             NotifyDisplayDestroy(screenSession->GetScreenId());
744             NotifyCastWhenScreenConnectChange(false);
745             FreeDisplayMirrorNodeInner(screenSession);
746             isPhyScreenConnected_ = false;
747         }
748         if (clientProxy_) {
749             clientProxy_->OnScreenConnectionChanged(screenId, ScreenEvent::DISCONNECTED,
750                 screenSession->GetRSScreenId(), screenSession->GetName());
751         }
752         if (!(screenId == SCREEN_ID_MAIN && isCoordinationFlag_ == true)) {
753             std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
754             screenSessionMap_.erase(screenId);
755         }
756         {
757             std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
758             phyScreenPropMap_.erase(screenId);
759         }
760         TLOGI(WmsLogTag::DMS, "DisconnectScreenSession success. ScreenId: %{public}" PRIu64 "", screenId);
761     }
762 }
763 
OnHgmRefreshRateChange(uint32_t refreshRate)764 void ScreenSessionManager::OnHgmRefreshRateChange(uint32_t refreshRate)
765 {
766     GetDefaultScreenId();
767     TLOGD(WmsLogTag::DMS, "Set refreshRate: %{public}u, defaultscreenid: %{public}" PRIu64"",
768         refreshRate, defaultScreenId_);
769     sptr<ScreenSession> screenSession = GetScreenSession(defaultScreenId_);
770     if (screenSession) {
771         screenSession->UpdateRefreshRate(refreshRate);
772         NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
773             DisplayChangeEvent::UPDATE_REFRESHRATE);
774     } else {
775         TLOGE(WmsLogTag::DMS, "Get default screen session failed.");
776     }
777     return;
778 }
779 
GetScreenSession(ScreenId screenId) const780 sptr<ScreenSession> ScreenSessionManager::GetScreenSession(ScreenId screenId) const
781 {
782     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
783     if (screenSessionMap_.empty()) {
784         screenEventTracker_.LogWarningAllInfos();
785     }
786     auto iter = screenSessionMap_.find(screenId);
787     if (iter == screenSessionMap_.end()) {
788         TLOGI(WmsLogTag::DMS, "Error found screen session with id: %{public}" PRIu64"", screenId);
789         return nullptr;
790     }
791     return iter->second;
792 }
793 
GetDefaultScreenSession()794 sptr<ScreenSession> ScreenSessionManager::GetDefaultScreenSession()
795 {
796     GetDefaultScreenId();
797     return GetScreenSession(defaultScreenId_);
798 }
799 
HookDisplayInfoByUid(sptr<DisplayInfo> displayInfo,const sptr<ScreenSession> & screenSession)800 sptr<DisplayInfo> ScreenSessionManager::HookDisplayInfoByUid(sptr<DisplayInfo> displayInfo,
801     const sptr<ScreenSession>& screenSession)
802 {
803     if (displayInfo == nullptr) {
804         TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
805         return nullptr;
806     }
807     auto uid = IPCSkeleton::GetCallingUid();
808     std::shared_lock<std::shared_mutex> lock(hookInfoMutex_);
809     if (displayHookMap_.find(uid) != displayHookMap_.end()) {
810         auto info = displayHookMap_[uid];
811         TLOGI(WmsLogTag::DMS, "hW: %{public}u, hH: %{public}u, hD: %{public}f, hR: %{public}u, hER: %{public}d, "
812             "dW: %{public}u, dH: %{public}u, dR: %{public}u, dO: %{public}u", info.width_, info.height_, info.density_,
813             info.rotation_, info.enableHookRotation_, displayInfo->GetWidth(), displayInfo->GetHeight(),
814             displayInfo->GetRotation(), displayInfo->GetDisplayOrientation());
815 
816         displayInfo->SetWidth(info.width_);
817         displayInfo->SetHeight(info.height_);
818         displayInfo->SetVirtualPixelRatio(info.density_);
819         if (info.enableHookRotation_) {
820             if (screenSession) {
821                 Rotation targetRotation = screenSession->ConvertIntToRotation(static_cast<int32_t>(info.rotation_));
822                 displayInfo->SetRotation(targetRotation);
823                 DisplayOrientation targetOrientation = screenSession->CalcDisplayOrientation(targetRotation,
824                     FoldDisplayMode::UNKNOWN);
825                 TLOGI(WmsLogTag::DMS, "tR: %{public}u, tO: %{public}u", targetRotation, targetOrientation);
826                 displayInfo->SetDisplayOrientation(targetOrientation);
827             } else {
828                 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, screenSession is nullptr.");
829                 return nullptr;
830             }
831         }
832     }
833     return displayInfo;
834 }
835 
GetDefaultDisplayInfo()836 sptr<DisplayInfo> ScreenSessionManager::GetDefaultDisplayInfo()
837 {
838     DmsXcollie dmsXcollie("DMS:GetDefaultDisplayInfo", XCOLLIE_TIMEOUT_10S);
839     GetDefaultScreenId();
840     sptr<ScreenSession> screenSession = GetScreenSession(defaultScreenId_);
841     std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
842     if (screenSession) {
843         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
844         if (displayInfo == nullptr) {
845             TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
846             return nullptr;
847         }
848         // 在PC/PAD上安装的竖屏应用以及白名单中的应用在显示状态非全屏时需要hook displayinfo
849         displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
850         return displayInfo;
851     } else {
852         TLOGE(WmsLogTag::DMS, "Get default screen session failed.");
853         return nullptr;
854     }
855 }
856 
GetDisplayInfoById(DisplayId displayId)857 sptr<DisplayInfo> ScreenSessionManager::GetDisplayInfoById(DisplayId displayId)
858 {
859     TLOGD(WmsLogTag::DMS, "GetDisplayInfoById enter, displayId: %{public}" PRIu64" ", displayId);
860     DmsXcollie dmsXcollie("DMS:GetDisplayInfoById", XCOLLIE_TIMEOUT_10S);
861     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
862     for (auto sessionIt : screenSessionMap_) {
863         auto screenSession = sessionIt.second;
864         if (screenSession == nullptr) {
865             TLOGI(WmsLogTag::DMS, "GetDisplayInfoById screenSession is nullptr, ScreenId: %{public}" PRIu64 "",
866                 sessionIt.first);
867             continue;
868         }
869         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
870         if (displayInfo == nullptr) {
871             TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
872             continue;
873         }
874         if (displayId == displayInfo->GetDisplayId()) {
875             TLOGD(WmsLogTag::DMS, "GetDisplayInfoById success");
876             displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
877             return displayInfo;
878         }
879     }
880     TLOGE(WmsLogTag::DMS, "GetDisplayInfoById failed. displayId: %{public}" PRIu64" ", displayId);
881     return nullptr;
882 }
883 
GetDisplayInfoByScreen(ScreenId screenId)884 sptr<DisplayInfo> ScreenSessionManager::GetDisplayInfoByScreen(ScreenId screenId)
885 {
886     TLOGD(WmsLogTag::DMS, "enter, screenId: %{public}" PRIu64"", screenId);
887     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
888     for (auto sessionIt : screenSessionMap_) {
889         auto screenSession = sessionIt.second;
890         if (screenSession == nullptr) {
891             TLOGI(WmsLogTag::DMS, "GetDisplayInfoByScreen screenSession is nullptr, ScreenId:%{public}" PRIu64"",
892                 sessionIt.first);
893             continue;
894         }
895         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
896         if (displayInfo == nullptr) {
897             TLOGI(WmsLogTag::DMS, "GetDisplayInfoByScreen error, displayInfo is nullptr.");
898             continue;
899         }
900         if (screenId == displayInfo->GetScreenId()) {
901             return displayInfo;
902         }
903     }
904     TLOGE(WmsLogTag::DMS, "GetDisplayInfoByScreen failed. screenId: %{public}" PRIu64" ", screenId);
905     return nullptr;
906 }
907 
GetAllDisplayIds()908 std::vector<DisplayId> ScreenSessionManager::GetAllDisplayIds()
909 {
910     TLOGI(WmsLogTag::DMS, "GetAllDisplayIds enter");
911     std::vector<DisplayId> res;
912     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
913     for (auto sessionIt : screenSessionMap_) {
914         auto screenSession = sessionIt.second;
915         if (screenSession == nullptr) {
916             TLOGE(WmsLogTag::DMS, "GetAllDisplayIds screenSession is nullptr, ScreenId:%{public}" PRIu64"",
917                 sessionIt.first);
918             continue;
919         }
920         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
921         if (displayInfo == nullptr) {
922             TLOGE(WmsLogTag::DMS, "GetAllDisplayIds error, displayInfo is nullptr.");
923             continue;
924         }
925         DisplayId displayId = displayInfo->GetDisplayId();
926         res.push_back(displayId);
927     }
928     return res;
929 }
930 
GetScreenInfoById(ScreenId screenId)931 sptr<ScreenInfo> ScreenSessionManager::GetScreenInfoById(ScreenId screenId)
932 {
933     DmsXcollie dmsXcollie("DMS:GetScreenInfoById", XCOLLIE_TIMEOUT_10S);
934     if (!SessionPermission::IsSystemCalling()) {
935         TLOGE(WmsLogTag::DMS, "GetScreenInfoById permission denied!");
936         TLOGE(WmsLogTag::DMS, "calling clientName: %{public}s, calling pid: %{public}d",
937             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
938         return nullptr;
939     }
940     auto screenSession = GetScreenSession(screenId);
941     if (screenSession == nullptr) {
942         TLOGE(WmsLogTag::DMS, "GetScreenInfoById cannot find screenInfo: %{public}" PRIu64"", screenId);
943         return nullptr;
944     }
945     return screenSession->ConvertToScreenInfo();
946 }
947 
SetScreenActiveMode(ScreenId screenId,uint32_t modeId)948 DMError ScreenSessionManager::SetScreenActiveMode(ScreenId screenId, uint32_t modeId)
949 {
950     TLOGI(WmsLogTag::DMS, "SetScreenActiveMode: ScreenId: %{public}" PRIu64", modeId: %{public}u", screenId, modeId);
951     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
952         TLOGE(WmsLogTag::DMS, "Permission Denied!  calling clientName: %{public}s, calling pid: %{public}d",
953             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
954         return DMError::DM_ERROR_NOT_SYSTEM_APP;
955     }
956     if (screenId == SCREEN_ID_INVALID) {
957         TLOGE(WmsLogTag::DMS, "SetScreenActiveMode: invalid screenId");
958         return DMError::DM_ERROR_NULLPTR;
959     }
960     {
961         sptr<ScreenSession> screenSession = GetScreenSession(screenId);
962         if (screenSession == nullptr) {
963             TLOGE(WmsLogTag::DMS, "SetScreenActiveMode: Get ScreenSession failed");
964             return DMError::DM_ERROR_NULLPTR;
965         }
966         ScreenId rsScreenId = SCREEN_ID_INVALID;
967         if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
968             TLOGE(WmsLogTag::DMS, "SetScreenActiveMode: No corresponding rsId");
969             return DMError::DM_ERROR_NULLPTR;
970         }
971         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetScreenActiveMode(%" PRIu64", %u)", screenId, modeId);
972         rsInterface_.SetScreenActiveMode(rsScreenId, modeId);
973         screenSession->activeIdx_ = static_cast<int32_t>(modeId);
974         screenSession->UpdatePropertyByActiveMode();
975 
976         ScreenProperty property = screenSession->GetScreenProperty();
977         property.SetPropertyChangeReason("active mode change");
978         screenSession->PropertyChange(property, ScreenPropertyChangeReason::CHANGE_MODE);
979         NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
980         NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
981     }
982     return DMError::DM_OK;
983 }
984 
ConvertScreenIdToRsScreenId(ScreenId screenId,ScreenId & rsScreenId)985 bool ScreenSessionManager::ConvertScreenIdToRsScreenId(ScreenId screenId, ScreenId& rsScreenId)
986 {
987     return screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
988 }
989 
UpdateDisplayHookInfo(int32_t uid,bool enable,const DMHookInfo & hookInfo)990 void ScreenSessionManager::UpdateDisplayHookInfo(int32_t uid, bool enable, const DMHookInfo& hookInfo)
991 {
992     TLOGD(WmsLogTag::DMS, "DisplayHookInfo will update");
993     if (!SessionPermission::IsSystemCalling()) {
994         TLOGE(WmsLogTag::DMS, "UpdateDisplayHookInfo permission denied!");
995         return;
996     }
997 
998     std::unique_lock<std::shared_mutex> lock(hookInfoMutex_);
999     if (enable) {
1000         if (uid != 0) {
1001             displayHookMap_[uid] = hookInfo;
1002         }
1003     } else {
1004         displayHookMap_.erase(uid);
1005     }
1006 }
1007 
IsFreezed(const int32_t & agentPid,const DisplayManagerAgentType & agentType)1008 bool ScreenSessionManager::IsFreezed(const int32_t& agentPid, const DisplayManagerAgentType& agentType)
1009 {
1010     std::lock_guard<std::mutex> lock(freezedPidListMutex_);
1011     if (freezedPidList_.count(agentPid) == 0) {
1012         return false;
1013     }
1014     // 冻结的应用记录应用 pid 和注册的 agentType
1015     if (pidAgentTypeMap_.count(agentPid) == 0) {
1016         std::set agentTypes = { agentType };
1017         pidAgentTypeMap_[agentPid] = agentTypes;
1018     } else {
1019         pidAgentTypeMap_[agentPid].insert(agentType);
1020     }
1021     TLOGD(WmsLogTag::DMS, "Agent is freezed, no need notify. PID: %{public}d.", agentPid);
1022     return true;
1023 }
1024 
NotifyScreenChanged(sptr<ScreenInfo> screenInfo,ScreenChangeEvent event)1025 void ScreenSessionManager::NotifyScreenChanged(sptr<ScreenInfo> screenInfo, ScreenChangeEvent event)
1026 {
1027     if (screenInfo == nullptr) {
1028         TLOGE(WmsLogTag::DMS, "NotifyScreenChanged error, screenInfo is nullptr.");
1029         return;
1030     }
1031     {
1032         std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
1033         lastScreenChangeEvent_ = event;
1034     }
1035     auto task = [=] {
1036         TLOGI(WmsLogTag::DMS, "NotifyScreenChanged,  screenId:%{public}" PRIu64"", screenInfo->GetScreenId());
1037         auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
1038         if (agents.empty()) {
1039             TLOGI(WmsLogTag::DMS, "NotifyScreenChanged agents is empty");
1040             return;
1041         }
1042         for (auto& agent : agents) {
1043             int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
1044             if (!IsFreezed(agentPid, DisplayManagerAgentType::SCREEN_EVENT_LISTENER)) {
1045                 agent->OnScreenChange(screenInfo, event);
1046             }
1047         }
1048     };
1049     taskScheduler_->PostAsyncTask(task, "NotifyScreenChanged:SID:" + std::to_string(screenInfo->GetScreenId()));
1050 }
1051 
SetVirtualPixelRatio(ScreenId screenId,float virtualPixelRatio)1052 DMError ScreenSessionManager::SetVirtualPixelRatio(ScreenId screenId, float virtualPixelRatio)
1053 {
1054     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1055         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
1056             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1057         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1058     }
1059 
1060     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1061     if (!screenSession) {
1062         TLOGE(WmsLogTag::DMS, "screen session is nullptr");
1063         return DMError::DM_ERROR_UNKNOWN;
1064     }
1065     if (screenSession->isScreenGroup_) {
1066         TLOGE(WmsLogTag::DMS, "cannot set virtual pixel ratio to the combination. screen: %{public}" PRIu64"",
1067             screenId);
1068         return DMError::DM_ERROR_NULLPTR;
1069     }
1070     if (fabs(screenSession->GetScreenProperty().GetVirtualPixelRatio() - virtualPixelRatio) < 1e-6) {
1071         TLOGE(WmsLogTag::DMS,
1072             "The density is equivalent to the original value, no update operation is required, aborted.");
1073         return DMError::DM_OK;
1074     }
1075     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetVirtualPixelRatio(%" PRIu64", %f)", screenId,
1076         virtualPixelRatio);
1077     screenSession->SetVirtualPixelRatio(virtualPixelRatio);
1078     std::map<DisplayId, sptr<DisplayInfo>> emptyMap;
1079     NotifyDisplayStateChange(GetDefaultScreenId(), screenSession->ConvertToDisplayInfo(),
1080         emptyMap, DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE);
1081     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::VIRTUAL_PIXEL_RATIO_CHANGED);
1082     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
1083         DisplayChangeEvent::DISPLAY_VIRTUAL_PIXEL_RATIO_CHANGED);
1084     return DMError::DM_OK;
1085 }
1086 
SetVirtualPixelRatioSystem(ScreenId screenId,float virtualPixelRatio)1087 DMError ScreenSessionManager::SetVirtualPixelRatioSystem(ScreenId screenId, float virtualPixelRatio)
1088 {
1089     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1090         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
1091             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1092         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1093     }
1094 
1095     if (clientProxy_) {
1096         clientProxy_->SetVirtualPixelRatioSystem(screenId, virtualPixelRatio);
1097     }
1098     return DMError::DM_OK;
1099 }
1100 
SetResolution(ScreenId screenId,uint32_t width,uint32_t height,float virtualPixelRatio)1101 DMError ScreenSessionManager::SetResolution(ScreenId screenId, uint32_t width, uint32_t height, float virtualPixelRatio)
1102 {
1103     TLOGI(WmsLogTag::DMS,
1104         "SetResolution ScreenId: %{public}" PRIu64 ", w: %{public}u, h: %{public}u, virtualPixelRatio: %{public}f",
1105         screenId, width, height, virtualPixelRatio);
1106     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1107         TLOGE(WmsLogTag::DMS, "SetResolution permission denied! calling pid: %{public}d", IPCSkeleton::GetCallingPid());
1108         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1109     }
1110     if (screenId == SCREEN_ID_INVALID) {
1111         TLOGE(WmsLogTag::DMS, "SetResolution: invalid screenId");
1112         return DMError::DM_ERROR_NULLPTR;
1113     }
1114     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1115     if (screenSession == nullptr) {
1116         TLOGE(WmsLogTag::DMS, "SetResolution: Get ScreenSession failed");
1117         return DMError::DM_ERROR_NULLPTR;
1118     }
1119     sptr<SupportedScreenModes> screenSessionModes = screenSession->GetActiveScreenMode();
1120     if (screenSessionModes == nullptr) {
1121         TLOGE(WmsLogTag::DMS, "SetResolution: Get screenSessionModes failed");
1122         return DMError::DM_ERROR_NULLPTR;
1123     }
1124     if (width <= 0 || width > screenSessionModes->width_ ||
1125         height <= 0 || height > screenSessionModes->height_ ||
1126         virtualPixelRatio < (static_cast<float>(DOT_PER_INCH_MINIMUM_VALUE) / DOT_PER_INCH) ||
1127         virtualPixelRatio > (static_cast<float>(DOT_PER_INCH_MAXIMUM_VALUE) / DOT_PER_INCH)) {
1128         TLOGE(WmsLogTag::DMS, "SetResolution invalid param! w:%{public}u h:%{public}u min:%{public}f max:%{public}f",
1129             screenSessionModes->width_,
1130             screenSessionModes->height_,
1131             static_cast<float>(DOT_PER_INCH_MINIMUM_VALUE) / DOT_PER_INCH,
1132             static_cast<float>(DOT_PER_INCH_MAXIMUM_VALUE) / DOT_PER_INCH);
1133         return DMError::DM_ERROR_INVALID_PARAM;
1134     }
1135     screenSession->SetDensityInCurResolution(virtualPixelRatio);
1136     DMError ret = SetVirtualPixelRatio(screenId, virtualPixelRatio);
1137     if (ret != DMError::DM_OK) {
1138         TLOGE(WmsLogTag::DMS, "Failed to setVirtualPixelRatio when settingResolution");
1139         screenSession->SetDensityInCurResolution(screenSession->GetScreenProperty().GetVirtualPixelRatio());
1140         return ret;
1141     }
1142     {
1143         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetResolution(%" PRIu64", %u, %u, %f)",
1144             screenId, width, height, virtualPixelRatio);
1145         screenSession->UpdatePropertyByResolution(width, height);
1146         screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::CHANGE_MODE);
1147         NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
1148         NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
1149     }
1150     return DMError::DM_OK;
1151 }
1152 
GetDensityInCurResolution(ScreenId screenId,float & virtualPixelRatio)1153 DMError ScreenSessionManager::GetDensityInCurResolution(ScreenId screenId, float& virtualPixelRatio)
1154 {
1155     DmsXcollie dmsXcollie("DMS:GetDensityInCurResolution", XCOLLIE_TIMEOUT_10S);
1156     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1157     if (screenSession == nullptr) {
1158         TLOGE(WmsLogTag::DMS, "GetDensityInCurResolution: Get ScreenSession failed");
1159         return DMError::DM_ERROR_NULLPTR;
1160     }
1161 
1162     virtualPixelRatio = screenSession->GetScreenProperty().GetDensityInCurResolution();
1163     return DMError::DM_OK;
1164 }
1165 
GetScreenColorGamut(ScreenId screenId,ScreenColorGamut & colorGamut)1166 DMError ScreenSessionManager::GetScreenColorGamut(ScreenId screenId, ScreenColorGamut& colorGamut)
1167 {
1168     TLOGI(WmsLogTag::DMS, "GetScreenColorGamut::ScreenId: %{public}" PRIu64 "", screenId);
1169     if (screenId == SCREEN_ID_INVALID) {
1170         TLOGE(WmsLogTag::DMS, "GetScreenColorGamut screenId invalid");
1171         return DMError::DM_ERROR_INVALID_PARAM;
1172     }
1173     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1174     if (screenSession == nullptr) {
1175         return DMError::DM_ERROR_INVALID_PARAM;
1176     }
1177     return screenSession->GetScreenColorGamut(colorGamut);
1178 }
1179 
SetScreenColorGamut(ScreenId screenId,int32_t colorGamutIdx)1180 DMError ScreenSessionManager::SetScreenColorGamut(ScreenId screenId, int32_t colorGamutIdx)
1181 {
1182     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1183         TLOGE(WmsLogTag::DMS, "set screen color gamut  permission denied!");
1184         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1185     }
1186 
1187     TLOGI(WmsLogTag::DMS, "SetScreenColorGamut::ScreenId: %{public}" PRIu64 ", colorGamutIdx %{public}d",
1188         screenId, colorGamutIdx);
1189     if (screenId == SCREEN_ID_INVALID) {
1190         TLOGE(WmsLogTag::DMS, "SetScreenColorGamut screenId invalid");
1191         return DMError::DM_ERROR_INVALID_PARAM;
1192     }
1193     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1194     if (screenSession == nullptr) {
1195         return DMError::DM_ERROR_INVALID_PARAM;
1196     }
1197     return screenSession->SetScreenColorGamut(colorGamutIdx);
1198 }
1199 
GetScreenGamutMap(ScreenId screenId,ScreenGamutMap & gamutMap)1200 DMError ScreenSessionManager::GetScreenGamutMap(ScreenId screenId, ScreenGamutMap& gamutMap)
1201 {
1202     TLOGI(WmsLogTag::DMS, "GetScreenGamutMap::ScreenId: %{public}" PRIu64 "", screenId);
1203     if (screenId == SCREEN_ID_INVALID) {
1204         TLOGE(WmsLogTag::DMS, "GetScreenGamutMap screenId invalid");
1205         return DMError::DM_ERROR_INVALID_PARAM;
1206     }
1207     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1208     if (screenSession == nullptr) {
1209         return DMError::DM_ERROR_INVALID_PARAM;
1210     }
1211     return screenSession->GetScreenGamutMap(gamutMap);
1212 }
1213 
SetScreenGamutMap(ScreenId screenId,ScreenGamutMap gamutMap)1214 DMError ScreenSessionManager::SetScreenGamutMap(ScreenId screenId, ScreenGamutMap gamutMap)
1215 {
1216     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1217         TLOGE(WmsLogTag::DMS, "set screen gamut map permission denied!");
1218         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1219     }
1220 
1221     TLOGI(WmsLogTag::DMS, "SetScreenGamutMap::ScreenId: %{public}" PRIu64 ", ScreenGamutMap %{public}u",
1222         screenId, static_cast<uint32_t>(gamutMap));
1223     if (screenId == SCREEN_ID_INVALID) {
1224         TLOGE(WmsLogTag::DMS, "SetScreenGamutMap screenId invalid");
1225         return DMError::DM_ERROR_INVALID_PARAM;
1226     }
1227     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1228     if (screenSession == nullptr) {
1229         return DMError::DM_ERROR_INVALID_PARAM;
1230     }
1231     return screenSession->SetScreenGamutMap(gamutMap);
1232 }
1233 
SetScreenColorTransform(ScreenId screenId)1234 DMError ScreenSessionManager::SetScreenColorTransform(ScreenId screenId)
1235 {
1236     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1237         TLOGE(WmsLogTag::DMS, "set Screen color transform permission denied!");
1238         return DMError::DM_ERROR_NOT_SYSTEM_APP;
1239     }
1240 
1241     TLOGI(WmsLogTag::DMS, "SetScreenColorTransform::ScreenId: %{public}" PRIu64 "", screenId);
1242     if (screenId == SCREEN_ID_INVALID) {
1243         TLOGE(WmsLogTag::DMS, "SetScreenColorTransform screenId invalid");
1244         return DMError::DM_ERROR_INVALID_PARAM;
1245     }
1246     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1247     if (screenSession == nullptr) {
1248         return DMError::DM_ERROR_INVALID_PARAM;
1249     }
1250     return screenSession->SetScreenColorTransform();
1251 }
1252 
CreatePhysicalMirrorSessionInner(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)1253 sptr<ScreenSession> ScreenSessionManager::CreatePhysicalMirrorSessionInner(ScreenId screenId, ScreenId defScreenId,
1254     ScreenProperty property)
1255 {
1256     sptr<ScreenSession> screenSession = nullptr;
1257     if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
1258         TLOGW(WmsLogTag::DMS, "mirror disabled by edm!");
1259         return screenSession;
1260     }
1261     sptr<ScreenSession> defaultScreen = GetDefaultScreenSession();
1262     if (defaultScreen == nullptr || defaultScreen->GetDisplayNode() == nullptr) {
1263         TLOGE(WmsLogTag::DMS, "default screen null");
1264         return screenSession;
1265     }
1266     NodeId nodeId = defaultScreen->GetDisplayNode()->GetId();
1267     TLOGI(WmsLogTag::DMS, "physical mirror screen nodeId: %{public}" PRIu64 "", nodeId);
1268     ScreenSessionConfig config = {
1269         .screenId = screenId,
1270         .defaultScreenId = defScreenId,
1271         .mirrorNodeId = nodeId,
1272         .property = property,
1273     };
1274     screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_MIRROR);
1275     if (!screenSession) {
1276         TLOGE(WmsLogTag::DMS, "screenSession is null");
1277         return nullptr;
1278     }
1279     if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none") {
1280         // pc is none, pad&&phone is mirror
1281         screenSession->SetName("ExtendedDisplay");
1282     } else {
1283         screenSession->SetName("CastEngine");
1284     }
1285     screenSession->SetIsExtend(true);
1286     screenSession->SetMirrorScreenType(MirrorScreenType::PHYSICAL_MIRROR);
1287     screenSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
1288     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE);
1289     hdmiScreenCount_ = hdmiScreenCount_ + 1;
1290     NotifyCaptureStatusChanged();
1291     return screenSession;
1292 }
1293 
GetScreenSessionInner(ScreenId screenId,ScreenProperty property)1294 sptr<ScreenSession> ScreenSessionManager::GetScreenSessionInner(ScreenId screenId, ScreenProperty property)
1295 {
1296     ScreenId defScreenId = GetDefaultScreenId();
1297     TLOGI(WmsLogTag::DMS, "GetScreenSessionInner: screenId:%{public}" PRIu64 "", screenId);
1298     if (IsDefaultMirrorMode(screenId)) {
1299         return CreatePhysicalMirrorSessionInner(screenId, defScreenId, property);
1300     }
1301     std::string screenName = "UNKNOWN";
1302     if (screenId == SCREEN_ID_MAIN) {
1303         screenName = "SubScreen";
1304     }
1305     ScreenSessionConfig config = {
1306         .screenId = screenId,
1307         .defaultScreenId = defScreenId,
1308         .name = screenName,
1309         .property = property,
1310     };
1311     sptr<ScreenSession> screenSession = nullptr;
1312     screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_REAL);
1313     screenSession->SetIsExtend(false);
1314     return screenSession;
1315 }
1316 
CreateScreenProperty(ScreenId screenId,ScreenProperty & property)1317 void ScreenSessionManager::CreateScreenProperty(ScreenId screenId, ScreenProperty& property)
1318 {
1319     int id = HiviewDFX::XCollie::GetInstance().SetTimer("CreateScreenPropertyCallRS", XCOLLIE_TIMEOUT_10S, nullptr,
1320         nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
1321     TLOGI(WmsLogTag::DMS, "Call rsInterface_ GetScreenActiveMode ScreenId: %{public}" PRIu64 "", screenId);
1322     auto screenMode = rsInterface_.GetScreenActiveMode(screenId);
1323     auto screenBounds = RRect({ 0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight() }, 0.0f, 0.0f);
1324     auto screenRefreshRate = screenMode.GetScreenRefreshRate();
1325     TLOGI(WmsLogTag::DMS, "Call rsInterface_ GetScreenCapability ScreenId: %{public}" PRIu64 "", screenId);
1326     auto screenCapability = rsInterface_.GetScreenCapability(screenId);
1327     HiviewDFX::XCollie::GetInstance().CancelTimer(id);
1328     TLOGI(WmsLogTag::DMS, "Call RS interface end, create ScreenProperty begin");
1329     property.SetRotation(0.0f);
1330     property.SetPhyWidth(screenCapability.GetPhyWidth());
1331     property.SetPhyHeight(screenCapability.GetPhyHeight());
1332     property.SetDpiPhyBounds(screenCapability.GetPhyWidth(), screenCapability.GetPhyHeight());
1333     property.SetPhyBounds(screenBounds);
1334     property.SetBounds(screenBounds);
1335     property.SetAvailableArea({0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight()});
1336     if (isDensityDpiLoad_) {
1337         if (screenId == SCREEN_ID_MAIN) {
1338             TLOGI(WmsLogTag::DMS, "subDensityDpi_ = %{public}f", subDensityDpi_);
1339             property.SetVirtualPixelRatio(subDensityDpi_);
1340             property.SetDefaultDensity(subDensityDpi_);
1341             property.SetDensityInCurResolution(subDensityDpi_);
1342         } else {
1343             TLOGI(WmsLogTag::DMS, "densityDpi_ = %{public}f", densityDpi_);
1344             property.SetVirtualPixelRatio(densityDpi_);
1345             property.SetDefaultDensity(densityDpi_);
1346             property.SetDensityInCurResolution(densityDpi_);
1347         }
1348     } else {
1349         property.UpdateVirtualPixelRatio(screenBounds);
1350     }
1351     property.SetRefreshRate(screenRefreshRate);
1352     property.SetDefaultDeviceRotationOffset(defaultDeviceRotationOffset_);
1353 
1354     if (foldScreenController_ != nullptr && screenId == 0
1355         && (g_screenRotationOffSet == ROTATION_90 || g_screenRotationOffSet == ROTATION_270)) {
1356         screenBounds = RRect({ 0, 0, screenMode.GetScreenHeight(), screenMode.GetScreenWidth() }, 0.0f, 0.0f);
1357         property.SetBounds(screenBounds);
1358     }
1359     property.CalcDefaultDisplayOrientation();
1360 }
1361 
GetOrCreateScreenSession(ScreenId screenId)1362 sptr<ScreenSession> ScreenSessionManager::GetOrCreateScreenSession(ScreenId screenId)
1363 {
1364     TLOGI(WmsLogTag::DMS, "GetOrCreateScreenSession ENTER. ScreenId: %{public}" PRIu64 "", screenId);
1365     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1366     if (screenSession) {
1367         TLOGI(WmsLogTag::DMS, "screenSession Exist ScreenId: %{public}" PRIu64 "", screenId);
1368         return screenSession;
1369     }
1370 
1371     ScreenId rsId = screenId;
1372     screenIdManager_.UpdateScreenId(rsId, screenId);
1373 
1374     ScreenProperty property;
1375     CreateScreenProperty(screenId, property);
1376     TLOGI(WmsLogTag::DMS, "CreateScreenProperty end");
1377     screenEventTracker_.RecordEvent("CreateScreenProperty by rsInterface success.");
1378     {
1379         std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
1380         phyScreenPropMap_[screenId] = property;
1381     }
1382 
1383     if (HandleFoldScreenSessionCreate(screenId) == false) {
1384         return nullptr;
1385     }
1386 
1387     sptr<ScreenSession> session = GetScreenSessionInner(screenId, property);
1388     if (session == nullptr) {
1389         TLOGE(WmsLogTag::DMS, "get screen session fail ScreenId: %{public}" PRIu64, screenId);
1390         return session;
1391     }
1392     session->RegisterScreenChangeListener(this);
1393     InitAbstractScreenModesInfo(session);
1394     session->groupSmsId_ = 1;
1395     {
1396         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1397         screenSessionMap_[screenId] = session;
1398     }
1399     screenEventTracker_.RecordEvent("create screen session success.");
1400     SetHdrFormats(screenId, session);
1401     SetColorSpaces(screenId, session);
1402     RegisterRefreshRateChangeListener();
1403     TLOGI(WmsLogTag::DMS, "CreateScreenSession success. ScreenId: %{public}" PRIu64 "", screenId);
1404     return session;
1405 }
1406 
HandleFoldScreenSessionCreate(ScreenId screenId)1407 bool ScreenSessionManager::HandleFoldScreenSessionCreate(ScreenId screenId)
1408 {
1409     if (foldScreenController_ != nullptr) {
1410         // sensor may earlier than screen connect, when physical screen property changed, update
1411         foldScreenController_->UpdateForPhyScreenPropertyChange();
1412         /* folder screen outer screenId is 5 */
1413         if (screenId == SCREEN_ID_MAIN) {
1414             SetPostureAndHallSensorEnabled();
1415             ScreenSensorConnector::SubscribeTentSensor();
1416             isFoldScreenOuterScreenReady_ = true;
1417             if (!FoldScreenStateInternel::IsDualDisplayFoldDevice() && isCoordinationFlag_ == false) {
1418                 return false;
1419             }
1420         }
1421     }
1422     return true;
1423 }
1424 
SetHdrFormats(ScreenId screenId,sptr<ScreenSession> & session)1425 void ScreenSessionManager::SetHdrFormats(ScreenId screenId, sptr<ScreenSession>& session)
1426 {
1427     TLOGI(WmsLogTag::DMS, "SetHdrFormats %{public}" PRIu64, screenId);
1428     std::vector<ScreenHDRFormat> rsHdrFormat;
1429     auto status = rsInterface_.GetScreenSupportedHDRFormats(screenId, rsHdrFormat);
1430     if (static_cast<StatusCode>(status) != StatusCode::SUCCESS) {
1431         TLOGE(WmsLogTag::DMS, "get hdr format failed! status code: %{public}d", status);
1432     } else {
1433         std::vector<uint32_t> hdrFormat(rsHdrFormat.size());
1434         std::transform(rsHdrFormat.begin(), rsHdrFormat.end(), hdrFormat.begin(), [](int val) {
1435             return static_cast<uint32_t>(val);
1436         });
1437         session->SetHdrFormats(std::move(hdrFormat));
1438     }
1439 }
1440 
SetColorSpaces(ScreenId screenId,sptr<ScreenSession> & session)1441 void ScreenSessionManager::SetColorSpaces(ScreenId screenId, sptr<ScreenSession>& session)
1442 {
1443     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1444         TLOGE(WmsLogTag::DMS, "set Screen color spaces permission denied!");
1445         return;
1446     }
1447 
1448     TLOGI(WmsLogTag::DMS, "SetColorSpaces %{public}" PRIu64, screenId);
1449     std::vector<GraphicCM_ColorSpaceType> rsColorSpace;
1450     auto status = rsInterface_.GetScreenSupportedColorSpaces(screenId, rsColorSpace);
1451     if (static_cast<StatusCode>(status) != StatusCode::SUCCESS) {
1452         TLOGE(WmsLogTag::DMS, "get color space failed! status code: %{public}d", status);
1453     } else {
1454         std::vector<uint32_t> colorSpace(rsColorSpace.size());
1455         std::transform(rsColorSpace.begin(), rsColorSpace.end(), colorSpace.begin(), [](int val) {
1456             return static_cast<uint32_t>(val);
1457         });
1458         session->SetColorSpaces(std::move(colorSpace));
1459     }
1460 }
1461 
GetDefaultScreenId()1462 ScreenId ScreenSessionManager::GetDefaultScreenId()
1463 {
1464     if (defaultScreenId_ == INVALID_SCREEN_ID) {
1465         defaultScreenId_ = rsInterface_.GetDefaultScreenId();
1466         std::ostringstream oss;
1467         oss << "Default screen id : " << defaultScreenId_;
1468         TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
1469         screenEventTracker_.RecordEvent(oss.str());
1470     }
1471     return defaultScreenId_;
1472 }
1473 
WakeUpBegin(PowerStateChangeReason reason)1474 bool ScreenSessionManager::WakeUpBegin(PowerStateChangeReason reason)
1475 {
1476     // 该接口当前只有Power调用
1477     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:WakeUpBegin(%u)", reason);
1478     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1479         TLOGE(WmsLogTag::DMS, "permission denied! calling clientName: %{public}s, calling pid: %{public}d",
1480             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1481         return false;
1482     }
1483     currentWakeUpReason_ = reason;
1484     TLOGI(WmsLogTag::DMS, "[UL_POWER]WakeUpBegin reason: %{public}u", static_cast<uint32_t>(reason));
1485     // 多屏协作灭屏不通知锁屏
1486     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
1487         isMultiScreenCollaboration_ = true;
1488         return true;
1489     }
1490     lastWakeUpReason_ = reason;
1491     return NotifyDisplayPowerEvent(DisplayPowerEvent::WAKE_UP, EventStatus::BEGIN, reason);
1492 }
1493 
WakeUpEnd()1494 bool ScreenSessionManager::WakeUpEnd()
1495 {
1496     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:WakeUpEnd");
1497     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1498         TLOGE(WmsLogTag::DMS, "permission denied! calling clientName: %{public}s, calling pid: %{public}d",
1499             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1500         return false;
1501     }
1502     TLOGI(WmsLogTag::DMS, "[UL_POWER]WakeUpEnd enter");
1503     // 多屏协作灭屏不通知锁屏
1504     if (isMultiScreenCollaboration_) {
1505         isMultiScreenCollaboration_ = false;
1506         return true;
1507     }
1508     return NotifyDisplayPowerEvent(DisplayPowerEvent::WAKE_UP, EventStatus::END,
1509         PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
1510 }
1511 
SuspendBegin(PowerStateChangeReason reason)1512 bool ScreenSessionManager::SuspendBegin(PowerStateChangeReason reason)
1513 {
1514     // 该接口当前只有Power调用
1515     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:SuspendBegin(%u)", reason);
1516     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1517         TLOGE(WmsLogTag::DMS, "permission denied! calling clientName: %{public}s, calling pid: %{public}d",
1518             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1519         return false;
1520     }
1521 
1522     gotScreenlockFingerprint_ = false;
1523     TLOGI(WmsLogTag::DMS, "[UL_POWER]Reason: %{public}u", static_cast<uint32_t>(reason));
1524     lastWakeUpReason_ = PowerStateChangeReason::STATE_CHANGE_REASON_INIT;
1525     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
1526         lastWakeUpReason_ = PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF;
1527     }
1528     // 多屏协作灭屏不通知锁屏
1529     gotScreenOffNotify_  = false;
1530     sessionDisplayPowerController_->canCancelSuspendNotify_ = true;
1531     sessionDisplayPowerController_->SuspendBegin(reason);
1532     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
1533         isMultiScreenCollaboration_ = true;
1534         return true;
1535     }
1536     return NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::BEGIN, reason);
1537 }
1538 
SuspendEnd()1539 bool ScreenSessionManager::SuspendEnd()
1540 {
1541     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1542         TLOGE(WmsLogTag::DMS, "permission denied! calling clientName: %{public}s, calling pid: %{public}d",
1543             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1544         return false;
1545     }
1546     TLOGI(WmsLogTag::DMS, "[UL_POWER]SuspendEnd enter");
1547     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:SuspendEnd");
1548     // 多屏协作灭屏不通知锁屏
1549     if (isMultiScreenCollaboration_) {
1550         isMultiScreenCollaboration_ = false;
1551         return true;
1552     }
1553     return NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::END,
1554         PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
1555 }
1556 
IsPreBrightAuthFail(void)1557 bool ScreenSessionManager::IsPreBrightAuthFail(void)
1558 {
1559     return lastWakeUpReason_ == PowerStateChangeReason::
1560         STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF;
1561 }
1562 
BlockSetDisplayState(void)1563 bool ScreenSessionManager::BlockSetDisplayState(void)
1564 {
1565     return prePowerStateChangeReason_ == PowerStateChangeReason::POWER_BUTTON;
1566 }
1567 
SetDisplayState(DisplayState state)1568 bool ScreenSessionManager::SetDisplayState(DisplayState state)
1569 {
1570     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1571         TLOGE(WmsLogTag::DMS, "permission denied! calling clientName: %{public}s, calling pid: %{public}d",
1572             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1573         return false;
1574     }
1575     if (!sessionDisplayPowerController_) {
1576         TLOGE(WmsLogTag::DMS, "[UL_POWER]sessionDisplayPowerController_ is null");
1577         return false;
1578     }
1579     TLOGI(WmsLogTag::DMS, "[UL_POWER]SetDisplayState enter");
1580     auto screenIds = GetAllScreenIds();
1581     if (screenIds.empty()) {
1582         TLOGI(WmsLogTag::DMS, "[UL_POWER]no screen info");
1583         return sessionDisplayPowerController_->SetDisplayState(state);
1584     }
1585 
1586     UpdateDisplayState(screenIds, state);
1587     bool ret = sessionDisplayPowerController_->SetDisplayState(state);
1588     if (!ret && state == DisplayState::OFF) {
1589         state = lastDisplayState_;
1590         UpdateDisplayState(screenIds, state);
1591     }
1592     lastDisplayState_ = state;
1593     return ret;
1594 }
1595 
UpdateDisplayState(std::vector<ScreenId> screenIds,DisplayState state)1596 void ScreenSessionManager::UpdateDisplayState(std::vector<ScreenId> screenIds, DisplayState state)
1597 {
1598     for (auto screenId : screenIds) {
1599         sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1600         if (screenSession == nullptr) {
1601             TLOGW(WmsLogTag::DMS, "[UL_POWER]SetDisplayState cannot get ScreenSession, screenId: %{public}" PRIu64"",
1602                 screenId);
1603             continue;
1604         }
1605         screenSession->UpdateDisplayState(state);
1606         TLOGI(WmsLogTag::DMS, "[UL_POWER]set screenSession displayState property: %{public}u",
1607             screenSession->GetScreenProperty().GetDisplayState());
1608     }
1609 }
1610 
BlockScreenOnByCV(void)1611 void ScreenSessionManager::BlockScreenOnByCV(void)
1612 {
1613     if (keyguardDrawnDone_ == false) {
1614         TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOnCV_ set");
1615         needScreenOnWhenKeyguardNotify_ = true;
1616         std::unique_lock<std::mutex> lock(screenOnMutex_);
1617         if (screenOnCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_SCREENON_MS)) == std::cv_status::timeout) {
1618             TLOGI(WmsLogTag::DMS, "[UL_POWER]wait ScreenOnCV_ timeout");
1619         }
1620     }
1621 }
1622 
BlockScreenOffByCV(void)1623 void ScreenSessionManager::BlockScreenOffByCV(void)
1624 {
1625     if (gotScreenOffNotify_  == false) {
1626         TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOffCV_ set, delay:%{public}d", screenOffDelay_);
1627         needScreenOffNotify_ = true;
1628         std::unique_lock<std::mutex> lock(screenOffMutex_);
1629         if (screenOffCV_.wait_for(lock, std::chrono::milliseconds(screenOffDelay_)) == std::cv_status::timeout) {
1630             isScreenLockSuspend_ = false;
1631             needScreenOffNotify_ = false;
1632             TLOGI(WmsLogTag::DMS, "[UL_POWER]wait ScreenOffCV_ timeout, isScreenLockSuspend_ is false");
1633         }
1634     }
1635 }
1636 
TryToCancelScreenOff()1637 bool ScreenSessionManager::TryToCancelScreenOff()
1638 {
1639     std::lock_guard<std::mutex> notifyLock(sessionDisplayPowerController_->notifyMutex_);
1640     TLOGI(WmsLogTag::DMS, "[UL_POWER]about to cancel suspend, can:%{public}d, got:%{public}d, need:%{public}d",
1641         sessionDisplayPowerController_->canCancelSuspendNotify_, gotScreenOffNotify_, needScreenOffNotify_);
1642     if (sessionDisplayPowerController_->canCancelSuspendNotify_) {
1643         sessionDisplayPowerController_->needCancelNotify_ = true;
1644         TLOGI(WmsLogTag::DMS, "[UL_POWER]notify cancel screenoff");
1645         ScreenSessionManager::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_OFF_CANCELED,
1646             EventStatus::BEGIN, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
1647         return true;
1648     }
1649     if (gotScreenOffNotify_ == false && needScreenOffNotify_ == true) {
1650         std::unique_lock <std::mutex> lock(screenOffMutex_);
1651         sessionDisplayPowerController_->canceledSuspend_ = true;
1652         screenOffCV_.notify_all();
1653         needScreenOffNotify_ = false;
1654         TLOGI(WmsLogTag::DMS, "[UL_POWER]cancel wait and notify cancel screenoff");
1655         ScreenSessionManager::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_OFF_CANCELED,
1656             EventStatus::BEGIN, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
1657             return true;
1658     }
1659     TLOGW(WmsLogTag::DMS, "[UL_POWER]failed to cancel suspend");
1660     return false;
1661 }
1662 
ForceSkipScreenOffAnimation()1663 void ScreenSessionManager::ForceSkipScreenOffAnimation()
1664 {
1665     std::lock_guard<std::mutex> notifyLock(sessionDisplayPowerController_->notifyMutex_);
1666     TLOGI(WmsLogTag::DMS, "[UL_POWER]about to skip animation, can:%{public}d, got:%{public}d, need:%{public}d",
1667         sessionDisplayPowerController_->canCancelSuspendNotify_, gotScreenOffNotify_, needScreenOffNotify_);
1668     if (sessionDisplayPowerController_->canCancelSuspendNotify_) {
1669         sessionDisplayPowerController_->skipScreenOffBlock_ = true;
1670         TLOGI(WmsLogTag::DMS, "[UL_POWER]skip screenoff animation");
1671         return;
1672     }
1673     if (gotScreenOffNotify_ == false && needScreenOffNotify_ == true) {
1674         std::unique_lock <std::mutex> lock(screenOffMutex_);
1675         screenOffCV_.notify_all();
1676         needScreenOffNotify_ = false;
1677         TLOGI(WmsLogTag::DMS, "[UL_POWER]skip wait");
1678         return;
1679     }
1680 }
1681 
SetScreenBrightness(uint64_t screenId,uint32_t level)1682 bool ScreenSessionManager::SetScreenBrightness(uint64_t screenId, uint32_t level)
1683 {
1684     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1685         TLOGE(WmsLogTag::DMS, "set screen brightness permission denied!");
1686         return false;
1687     }
1688     TLOGI(WmsLogTag::DMS, "SetScreenBrightness screenId:%{public}" PRIu64", level:%{public}u,", screenId, level);
1689     RSInterfaces::GetInstance().SetScreenBacklight(screenId, level);
1690     return true;
1691 }
1692 
GetScreenBrightness(uint64_t screenId)1693 uint32_t ScreenSessionManager::GetScreenBrightness(uint64_t screenId)
1694 {
1695     uint32_t level = static_cast<uint32_t>(RSInterfaces::GetInstance().GetScreenBacklight(screenId));
1696     TLOGI(WmsLogTag::DMS, "GetScreenBrightness screenId:%{public}" PRIu64", level:%{public}u,", screenId, level);
1697     return level;
1698 }
1699 
SetScreenOffDelayTime(int32_t delay)1700 int32_t ScreenSessionManager::SetScreenOffDelayTime(int32_t delay)
1701 {
1702     DmsXcollie dmsXcollie("DMS:SetScreenOffDelayTime", XCOLLIE_TIMEOUT_10S);
1703     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1704         TLOGE(WmsLogTag::DMS, "set screen off delay time permission denied!");
1705         return 0;
1706     }
1707 
1708     if (delay < CV_WAIT_SCREENOFF_MS) {
1709         screenOffDelay_ = CV_WAIT_SCREENOFF_MS;
1710     } else if (delay > CV_WAIT_SCREENOFF_MS_MAX) {
1711         screenOffDelay_ = CV_WAIT_SCREENOFF_MS_MAX;
1712     } else {
1713         screenOffDelay_ = delay;
1714     }
1715     TLOGI(WmsLogTag::DMS, "SetScreenOffDelayTime, delay:%{public}d, screenOffDelay_:%{public}d",
1716         delay, screenOffDelay_);
1717     return screenOffDelay_;
1718 }
1719 
SetCameraStatus(int32_t cameraStatus,int32_t cameraPosition)1720 void ScreenSessionManager::SetCameraStatus(int32_t cameraStatus, int32_t cameraPosition)
1721 {
1722     if ((cameraStatus_ == cameraStatus) && (cameraPosition_ == cameraPosition)) {
1723         return;  // no need to update
1724     }
1725     cameraStatus_ = cameraStatus;
1726     cameraPosition_ = cameraPosition;
1727     TLOGI(WmsLogTag::DMS, "SetCameraStatus, cameraStatus:%{public}d, cameraPosition:%{public}d",
1728         cameraStatus, cameraPosition);
1729 }
1730 
IsScreenLockSuspend(void)1731 bool ScreenSessionManager::IsScreenLockSuspend(void)
1732 {
1733     return isScreenLockSuspend_;
1734 }
1735 
NotifyDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)1736 void ScreenSessionManager::NotifyDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
1737     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
1738 {
1739     if (clientProxy_) {
1740         clientProxy_->OnDisplayStateChanged(defaultDisplayId, displayInfo, displayInfoMap, type);
1741     }
1742 }
1743 
NotifyScreenshot(DisplayId displayId)1744 void ScreenSessionManager::NotifyScreenshot(DisplayId displayId)
1745 {
1746     if (clientProxy_) {
1747         clientProxy_->OnScreenshot(displayId);
1748     }
1749 }
1750 
SetSpecifiedScreenPower(ScreenId screenId,ScreenPowerState state,PowerStateChangeReason reason)1751 bool ScreenSessionManager::SetSpecifiedScreenPower(ScreenId screenId, ScreenPowerState state,
1752     PowerStateChangeReason reason)
1753 {
1754     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1755         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
1756             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1757         return false;
1758     }
1759     TLOGI(WmsLogTag::DMS, "[UL_POWER]SetSpecifiedScreenPower: screen id:%{public}" PRIu64 ", state:%{public}u",
1760         screenId, state);
1761 
1762     ScreenPowerStatus status;
1763     switch (state) {
1764         case ScreenPowerState::POWER_ON: {
1765             status = ScreenPowerStatus::POWER_STATUS_ON;
1766             break;
1767         }
1768         case ScreenPowerState::POWER_OFF: {
1769             status = ScreenPowerStatus::POWER_STATUS_OFF;
1770             break;
1771         }
1772         default: {
1773             TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerStatus state not support");
1774             return false;
1775         }
1776     }
1777 
1778     CallRsSetScreenPowerStatusSync(screenId, status);
1779     if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
1780         return true;
1781     }
1782     return NotifyDisplayPowerEvent(state == ScreenPowerState::POWER_ON ? DisplayPowerEvent::DISPLAY_ON :
1783         DisplayPowerEvent::DISPLAY_OFF, EventStatus::END, reason);
1784 }
1785 
SetScreenPowerForAll(ScreenPowerState state,PowerStateChangeReason reason)1786 bool ScreenSessionManager::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)
1787 {
1788     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1789         TLOGE(WmsLogTag::DMS, "permission denied! calling clientName: %{public}s, calling pid: %{public}d",
1790             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1791         return false;
1792     }
1793     TLOGI(WmsLogTag::DMS, "[UL_POWER]state: %{public}u, reason: %{public}u",
1794         static_cast<uint32_t>(state), static_cast<uint32_t>(reason));
1795     ScreenPowerStatus status;
1796 
1797     if (!GetPowerStatus(state, reason, status)) {
1798         return false;
1799     }
1800     gotScreenOffNotify_  = false;
1801     keyguardDrawnDone_ = false;
1802     TLOGI(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerForAll keyguardDrawnDone_ is false");
1803     prePowerStateChangeReason_ = reason;
1804     return SetScreenPower(status, reason);
1805 }
1806 
GetPowerStatus(ScreenPowerState state,PowerStateChangeReason reason,ScreenPowerStatus & status)1807 bool ScreenSessionManager::GetPowerStatus(ScreenPowerState state, PowerStateChangeReason reason,
1808     ScreenPowerStatus& status)
1809 {
1810     switch (state) {
1811         case ScreenPowerState::POWER_ON: {
1812             if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT) {
1813                 // 预亮屏
1814                 status = ScreenPowerStatus::POWER_STATUS_ON_ADVANCED;
1815                 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_ON_ADVANCED");
1816             } else {
1817                 status = ScreenPowerStatus::POWER_STATUS_ON;
1818                 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_ON");
1819             }
1820             break;
1821         }
1822         case ScreenPowerState::POWER_OFF: {
1823             if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
1824                 // 预亮屏时指纹认证失败
1825                 status = ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED;
1826                 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_OFF_ADVANCED");
1827             } else {
1828                 status = ScreenPowerStatus::POWER_STATUS_OFF;
1829                 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_OFF");
1830             }
1831             rsInterface_.MarkPowerOffNeedProcessOneFrame();
1832             break;
1833         }
1834         case ScreenPowerState::POWER_SUSPEND: {
1835             status = ScreenPowerStatus::POWER_STATUS_SUSPEND;
1836             TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_SUSPEND");
1837             rsInterface_.MarkPowerOffNeedProcessOneFrame();
1838             break;
1839         }
1840         default: {
1841             TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerStatus state not support");
1842             return false;
1843         }
1844     }
1845     return true;
1846 }
1847 
ExitCoordination(const std::string & reason)1848 void ScreenSessionManager::ExitCoordination(const std::string& reason)
1849 {
1850     if (GetFoldDisplayMode() != FoldDisplayMode::COORDINATION) {
1851         return;
1852     }
1853     if (foldScreenController_ != nullptr) {
1854         TLOGI(WmsLogTag::DMS, "[UL_POWER]ExitCoordination, reason:%{public}s", reason.c_str());
1855         foldScreenController_->ExitCoordination();
1856     }
1857 }
1858 
TryToRecoverFoldDisplayMode(ScreenPowerStatus status)1859 void ScreenSessionManager::TryToRecoverFoldDisplayMode(ScreenPowerStatus status)
1860 {
1861     if (foldScreenController_ == nullptr) {
1862         TLOGW(WmsLogTag::DMS, "foldScreenController_ is null");
1863         return;
1864     }
1865     if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED ||
1866         status == ScreenPowerStatus::POWER_STATUS_OFF_FAKE || status == ScreenPowerStatus::POWER_STATUS_SUSPEND) {
1867         foldScreenController_->RecoverDisplayMode();
1868     }
1869 }
1870 
SetScreenPower(ScreenPowerStatus status,PowerStateChangeReason reason)1871 bool ScreenSessionManager::SetScreenPower(ScreenPowerStatus status, PowerStateChangeReason reason)
1872 {
1873     TLOGI(WmsLogTag::DMS, "[UL_POWER]SetScreenPower enter status:%{public}u", status);
1874     auto screenIds = GetAllScreenIds();
1875     if (screenIds.empty()) {
1876         TLOGI(WmsLogTag::DMS, "[UL_POWER]SetScreenPower screenIds empty");
1877         return false;
1878     }
1879 
1880     if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND) {
1881         ExitCoordination("Press PowerKey");
1882     }
1883 
1884     if (((status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND) &&
1885         gotScreenlockFingerprint_ == true) &&
1886         prePowerStateChangeReason_ != PowerStateChangeReason::STATE_CHANGE_REASON_SHUT_DOWN) {
1887         gotScreenlockFingerprint_ = false;
1888         TLOGI(WmsLogTag::DMS, "[UL_POWER]SetScreenPower screenlockFingerprint or shutdown");
1889         return NotifyDisplayPowerEvent(status == ScreenPowerStatus::POWER_STATUS_ON ? DisplayPowerEvent::DISPLAY_ON :
1890             DisplayPowerEvent::DISPLAY_OFF, EventStatus::END, reason);
1891     }
1892 
1893     if (foldScreenController_ != nullptr) {
1894         CallRsSetScreenPowerStatusSyncForFold(status);
1895         TryToRecoverFoldDisplayMode(status);
1896     } else {
1897         for (auto screenId : screenIds) {
1898             CallRsSetScreenPowerStatusSync(screenId, status);
1899         }
1900     }
1901     HandlerSensor(status, reason);
1902     if ((status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND) &&
1903         gotScreenlockFingerprint_ == true) {
1904         gotScreenlockFingerprint_ = false;
1905     }
1906 
1907     return NotifyDisplayPowerEvent(status == ScreenPowerStatus::POWER_STATUS_ON ? DisplayPowerEvent::DISPLAY_ON :
1908         DisplayPowerEvent::DISPLAY_OFF, EventStatus::END, reason);
1909 }
1910 
SetScreenPowerForFold(ScreenPowerStatus status)1911 void ScreenSessionManager::SetScreenPowerForFold(ScreenPowerStatus status)
1912 {
1913     if (foldScreenController_ == nullptr) {
1914         TLOGW(WmsLogTag::DMS, "foldScreenController_ is null");
1915         return;
1916     }
1917     SetScreenPowerForFold(foldScreenController_->GetCurrentScreenId(), status);
1918 }
1919 
SetScreenPowerForFold(ScreenId screenId,ScreenPowerStatus status)1920 void ScreenSessionManager::SetScreenPowerForFold(ScreenId screenId, ScreenPowerStatus status)
1921 {
1922     rsInterface_.SetScreenPowerStatus(screenId, status);
1923 }
1924 
TriggerDisplayModeUpdate(FoldDisplayMode targetDisplayMode)1925 void ScreenSessionManager::TriggerDisplayModeUpdate(FoldDisplayMode targetDisplayMode)
1926 {
1927     auto updateDisplayModeTask = [=] {
1928         TLOGI(WmsLogTag::DMS, "start change displaymode to lastest mode");
1929         foldScreenController_->SetDisplayMode(targetDisplayMode);
1930     };
1931     taskScheduler_->PostAsyncTask(updateDisplayModeTask, "updateDisplayModeTask");
1932 }
1933 
CallRsSetScreenPowerStatusSync(ScreenId screenId,ScreenPowerStatus status)1934 void ScreenSessionManager::CallRsSetScreenPowerStatusSync(ScreenId screenId, ScreenPowerStatus status)
1935 {
1936     auto rsSetScreenPowerStatusTask = [=] {
1937         rsInterface_.SetScreenPowerStatus(screenId, status);
1938     };
1939     screenPowerTaskScheduler_->PostVoidSyncTask(rsSetScreenPowerStatusTask, "rsInterface_.SetScreenPowerStatus task");
1940 }
1941 
CallRsSetScreenPowerStatusSyncForFold(ScreenPowerStatus status)1942 void ScreenSessionManager::CallRsSetScreenPowerStatusSyncForFold(ScreenPowerStatus status)
1943 {
1944     auto rsSetScreenPowerStatusTask = [=] {
1945         if (foldScreenController_ == nullptr) {
1946             TLOGW(WmsLogTag::DMS, "foldScreenController_ is null");
1947             return;
1948         }
1949         rsInterface_.SetScreenPowerStatus(foldScreenController_->GetCurrentScreenId(), status);
1950     };
1951     screenPowerTaskScheduler_->PostVoidSyncTask(rsSetScreenPowerStatusTask, "rsInterface_.SetScreenPowerStatus task");
1952 }
1953 
SetKeyguardDrawnDoneFlag(bool flag)1954 void ScreenSessionManager::SetKeyguardDrawnDoneFlag(bool flag)
1955 {
1956     keyguardDrawnDone_ = flag;
1957 }
1958 
HandlerSensor(ScreenPowerStatus status,PowerStateChangeReason reason)1959 void ScreenSessionManager::HandlerSensor(ScreenPowerStatus status, PowerStateChangeReason reason)
1960 {
1961     if (ScreenSceneConfig::IsSupportRotateWithSensor()) {
1962         if (status == ScreenPowerStatus::POWER_STATUS_ON) {
1963             DmsXcollie dmsXcollie("DMS:SubscribeRotationSensor", XCOLLIE_TIMEOUT_5S);
1964             TLOGI(WmsLogTag::DMS, "subscribe rotation and posture sensor when phone turn on");
1965             ScreenSensorConnector::SubscribeRotationSensor();
1966 #ifdef SENSOR_ENABLE
1967             if (g_foldScreenFlag && reason != PowerStateChangeReason::STATE_CHANGE_REASON_DISPLAY_SWITCH) {
1968                 FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
1969             } else {
1970                 TLOGI(WmsLogTag::DMS, "not fold product, switch screen reason, failed register posture.");
1971             }
1972 #endif
1973         } else if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND) {
1974             TLOGI(WmsLogTag::DMS, "unsubscribe rotation and posture sensor when phone turn off");
1975             if (isMultiScreenCollaboration_) {
1976                 TLOGI(WmsLogTag::DMS, "[UL_POWER]MultiScreenCollaboration, not unsubscribe rotation sensor");
1977             } else {
1978                 DmsXcollie dmsXcollie("DMS:UnsubscribeRotationSensor", XCOLLIE_TIMEOUT_5S);
1979                 ScreenSensorConnector::UnsubscribeRotationSensor();
1980             }
1981 #ifdef SENSOR_ENABLE
1982             if (g_foldScreenFlag && reason != PowerStateChangeReason::STATE_CHANGE_REASON_DISPLAY_SWITCH) {
1983                 FoldScreenSensorManager::GetInstance().UnRegisterPostureCallback();
1984             } else {
1985                 TLOGI(WmsLogTag::DMS, "not fold product, switch screen reason, failed unregister posture.");
1986             }
1987 #endif
1988         } else {
1989             TLOGI(WmsLogTag::DMS, "SetScreenPower state not support");
1990             screenEventTracker_.RecordEvent("HandlerSensor start!");
1991         }
1992     }
1993 }
1994 
BootFinishedCallback(const char * key,const char * value,void * context)1995 void ScreenSessionManager::BootFinishedCallback(const char *key, const char *value, void *context)
1996 {
1997     if (strcmp(key, BOOTEVENT_BOOT_COMPLETED.c_str()) == 0 && strcmp(value, "true") == 0) {
1998         TLOGI(WmsLogTag::DMS, "BootFinishedCallback boot animation finished");
1999         auto &that = *reinterpret_cast<ScreenSessionManager *>(context);
2000         that.SetRotateLockedFromSettingData();
2001         that.SetDpiFromSettingData();
2002         that.SetDisplayState(DisplayState::ON);
2003         that.RegisterSettingDpiObserver();
2004         if (that.foldScreenPowerInit_ != nullptr) {
2005             that.foldScreenPowerInit_();
2006         }
2007         that.RegisterSettingRotationObserver();
2008         if (that.defaultDpi) {
2009             auto ret = ScreenSettingHelper::SetSettingDefaultDpi(that.defaultDpi, SET_SETTING_DPI_KEY);
2010             if (!ret) {
2011                 TLOGE(WmsLogTag::DMS, "set setting defaultDpi failed");
2012             } else {
2013                 TLOGI(WmsLogTag::DMS, "set setting defaultDpi:%{public}d", that.defaultDpi);
2014             }
2015         }
2016     }
2017 }
2018 
SetFoldScreenPowerInit(std::function<void ()> foldScreenPowerInit)2019 void ScreenSessionManager::SetFoldScreenPowerInit(std::function<void()> foldScreenPowerInit)
2020 {
2021     foldScreenPowerInit_ = foldScreenPowerInit;
2022 }
2023 
SetRotateLockedFromSettingData()2024 void ScreenSessionManager::SetRotateLockedFromSettingData()
2025 {
2026     uint32_t autoRotateStatus = AUTO_ROTATE_OFF;  // 0代表自动旋转关闭,1代表自动旋转打开
2027     bool islocked = true;
2028     // ret为true表示从数据库读到了值,并赋给了autoRotateStatus
2029     bool ret = ScreenSettingHelper::GetSettingValue(autoRotateStatus, SETTING_LOCKED_KEY);
2030     TLOGI(WmsLogTag::DMS, "get autoRotateStatus from settingdata: %{public}u", autoRotateStatus);
2031     if (autoRotateStatus) {
2032         islocked =false;
2033     }
2034     if (ret) {
2035         TLOGI(WmsLogTag::DMS, "get islocked success");
2036         SetScreenRotationLockedFromJs(islocked);
2037     }
2038 }
2039 
RegisterSettingDpiObserver()2040 void ScreenSessionManager::RegisterSettingDpiObserver()
2041 {
2042     TLOGI(WmsLogTag::DMS, "Register Setting Dpi Observer");
2043     SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetDpiFromSettingData(); };
2044     ScreenSettingHelper::RegisterSettingDpiObserver(updateFunc);
2045 }
2046 
SetDpiFromSettingData()2047 void ScreenSessionManager::SetDpiFromSettingData()
2048 {
2049     uint32_t settingDpi;
2050     bool ret = ScreenSettingHelper::GetSettingDpi(settingDpi);
2051     if (!ret) {
2052         TLOGW(WmsLogTag::DMS, "get setting dpi failed,use default dpi");
2053         settingDpi = defaultDpi;
2054     } else {
2055         TLOGI(WmsLogTag::DMS, "get setting dpi success,settingDpi: %{public}u", settingDpi);
2056     }
2057     if (settingDpi >= DOT_PER_INCH_MINIMUM_VALUE && settingDpi <= DOT_PER_INCH_MAXIMUM_VALUE
2058         && cachedSettingDpi_ != settingDpi) {
2059         cachedSettingDpi_ = settingDpi;
2060         float dpi = static_cast<float>(settingDpi) / BASELINE_DENSITY;
2061         ScreenId defaultScreenId = GetDefaultScreenId();
2062         SetVirtualPixelRatio(defaultScreenId, dpi);
2063     }
2064 }
2065 
GetAllScreenIds()2066 std::vector<ScreenId> ScreenSessionManager::GetAllScreenIds()
2067 {
2068     std::vector<ScreenId> res;
2069     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2070     for (const auto& iter : screenSessionMap_) {
2071         res.emplace_back(iter.first);
2072     }
2073     return res;
2074 }
2075 
GetDisplayState(DisplayId displayId)2076 DisplayState ScreenSessionManager::GetDisplayState(DisplayId displayId)
2077 {
2078     return sessionDisplayPowerController_->GetDisplayState(displayId);
2079 }
2080 
NotifyDisplayEvent(DisplayEvent event)2081 void ScreenSessionManager::NotifyDisplayEvent(DisplayEvent event)
2082 {
2083     TLOGI(WmsLogTag::DMS, "[UL_POWER]NotifyDisplayEvent receive keyguardDrawnDone");
2084     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2085         TLOGE(WmsLogTag::DMS, "permission denied! calling clientName: %{public}s, calling pid: %{public}d",
2086             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2087         return;
2088     }
2089     sessionDisplayPowerController_->NotifyDisplayEvent(event);
2090     if (event == DisplayEvent::KEYGUARD_DRAWN) {
2091         keyguardDrawnDone_ = true;
2092         TLOGI(WmsLogTag::DMS, "[UL_POWER]keyguardDrawnDone_ is true");
2093         if (needScreenOnWhenKeyguardNotify_) {
2094             std::unique_lock <std::mutex> lock(screenOnMutex_);
2095             screenOnCV_.notify_all();
2096             TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOnCV_ notify one");
2097             needScreenOnWhenKeyguardNotify_=false;
2098         }
2099     }
2100 
2101     if (event == DisplayEvent::SCREEN_LOCK_SUSPEND) {
2102         TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock suspend");
2103         gotScreenOffNotify_ = true;
2104         if (isPhyScreenConnected_) {
2105             isScreenLockSuspend_ = false;
2106             TLOGI(WmsLogTag::DMS, "[UL_POWER]isScreenLockSuspend__  is false");
2107         } else {
2108             isScreenLockSuspend_ = true;
2109         }
2110         if (needScreenOffNotify_) {
2111             ScreenOffCVNotify();
2112         }
2113     }
2114 
2115     if (event == DisplayEvent::SCREEN_LOCK_OFF) {
2116         TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock off");
2117         gotScreenOffNotify_ = true;
2118         isScreenLockSuspend_ = false;
2119         TLOGI(WmsLogTag::DMS, "[UL_POWER]isScreenLockSuspend__  is false");
2120         if (needScreenOffNotify_) {
2121             ScreenOffCVNotify();
2122         }
2123     }
2124 
2125     if (event == DisplayEvent::SCREEN_LOCK_FINGERPRINT) {
2126         TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock fingerprint");
2127         gotScreenOffNotify_ = true;
2128         gotScreenlockFingerprint_ = true;
2129         if (needScreenOffNotify_) {
2130             ScreenOffCVNotify();
2131         }
2132     }
2133 }
2134 
ScreenOffCVNotify(void)2135 void ScreenSessionManager::ScreenOffCVNotify(void)
2136 {
2137     std::unique_lock <std::mutex> lock(screenOffMutex_);
2138     screenOffCV_.notify_all();
2139     needScreenOffNotify_ = false;
2140     TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOffCV_ notify one");
2141 }
2142 
GetScreenPower(ScreenId screenId)2143 ScreenPowerState ScreenSessionManager::GetScreenPower(ScreenId screenId)
2144 {
2145     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2146         TLOGE(WmsLogTag::DMS, "permission denied! calling clientName: %{public}s, calling pid: %{public}d",
2147             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2148         return ScreenPowerState::INVALID_STATE;
2149     }
2150     auto state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance().GetScreenPowerStatus(screenId));
2151     std::ostringstream oss;
2152     oss << "GetScreenPower state:" << static_cast<uint32_t>(state) << " screenId:" << static_cast<uint64_t>(screenId);
2153     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
2154     screenEventTracker_.RecordEvent(oss.str());
2155     return state;
2156 }
2157 
IsScreenRotationLocked(bool & isLocked)2158 DMError ScreenSessionManager::IsScreenRotationLocked(bool& isLocked)
2159 {
2160     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2161         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2162             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2163         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2164     }
2165     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
2166     if (screenSession == nullptr) {
2167         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
2168         return DMError::DM_ERROR_INVALID_PARAM;
2169     }
2170     isLocked = screenSession->IsScreenRotationLocked();
2171     TLOGI(WmsLogTag::DMS, "IsScreenRotationLocked:isLocked: %{public}u", isLocked);
2172     return DMError::DM_OK;
2173 }
2174 
SetScreenRotationLocked(bool isLocked)2175 DMError ScreenSessionManager::SetScreenRotationLocked(bool isLocked)
2176 {
2177     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2178         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2179             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2180         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2181     }
2182     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
2183     if (screenSession == nullptr) {
2184         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
2185         return DMError::DM_ERROR_INVALID_PARAM;
2186     }
2187     screenSession->SetScreenRotationLocked(isLocked);
2188     TLOGI(WmsLogTag::DMS, "SetScreenRotationLocked: isLocked: %{public}u", isLocked);
2189     return DMError::DM_OK;
2190 }
2191 
SetScreenRotationLockedFromJs(bool isLocked)2192 DMError ScreenSessionManager::SetScreenRotationLockedFromJs(bool isLocked)
2193 {
2194     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2195         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2196             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2197         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2198     }
2199     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
2200     if (screenSession == nullptr) {
2201         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
2202         return DMError::DM_ERROR_INVALID_PARAM;
2203     }
2204     screenSession->SetScreenRotationLockedFromJs(isLocked);
2205     TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
2206     return DMError::DM_OK;
2207 }
2208 
NotifyAndPublishEvent(sptr<DisplayInfo> displayInfo,ScreenId screenId,sptr<ScreenSession> screenSession)2209 void ScreenSessionManager::NotifyAndPublishEvent(sptr<DisplayInfo> displayInfo, ScreenId screenId,
2210     sptr<ScreenSession> screenSession)
2211 {
2212     if (displayInfo == nullptr || screenSession == nullptr) {
2213         TLOGE(WmsLogTag::DMS, "NotifyAndPublishEvent error, displayInfo or screenSession is nullptr");
2214         return;
2215     }
2216     NotifyDisplayChanged(displayInfo, DisplayChangeEvent::UPDATE_ROTATION);
2217     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
2218     UpdateDisplayScaleState(screenId);
2219     std::map<DisplayId, sptr<DisplayInfo>> emptyMap;
2220     NotifyDisplayStateChange(GetDefaultScreenId(), screenSession->ConvertToDisplayInfo(),
2221         emptyMap, DisplayStateChangeType::UPDATE_ROTATION);
2222     std::string identity = IPCSkeleton::ResetCallingIdentity();
2223     ScreenSessionPublish::GetInstance().PublishDisplayRotationEvent(
2224         displayInfo->GetScreenId(), displayInfo->GetRotation());
2225     IPCSkeleton::SetCallingIdentity(identity);
2226 }
2227 
UpdateScreenDirectionInfo(ScreenId screenId,float screenComponentRotation,float rotation,float phyRotation,ScreenPropertyChangeType screenPropertyChangeType)2228 void ScreenSessionManager::UpdateScreenDirectionInfo(ScreenId screenId, float screenComponentRotation, float rotation,
2229     float phyRotation, ScreenPropertyChangeType screenPropertyChangeType)
2230 {
2231     if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_END) {
2232         TLOGI(WmsLogTag::DMS, "ROTATION_END");
2233         return;
2234     }
2235     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2236     if (screenSession == nullptr) {
2237         TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"", screenId);
2238         return;
2239     }
2240     screenSession->SetPhysicalRotation(phyRotation);
2241     screenSession->SetScreenComponentRotation(screenComponentRotation);
2242     screenSession->UpdateRotationOrientation(rotation);
2243     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", rotation: %{public}f, screenComponentRotation: %{public}f",
2244         screenId, rotation, screenComponentRotation);
2245 }
2246 
UpdateScreenRotationProperty(ScreenId screenId,const RRect & bounds,float rotation,ScreenPropertyChangeType screenPropertyChangeType)2247 void ScreenSessionManager::UpdateScreenRotationProperty(ScreenId screenId, const RRect& bounds, float rotation,
2248     ScreenPropertyChangeType screenPropertyChangeType)
2249 {
2250     std::ostringstream oss;
2251     std::string changeType = TransferPropertyChangeTypeToString(screenPropertyChangeType);
2252     oss << "screenId: " << screenId << " rotation: " << rotation << " width: " << bounds.rect_.width_ \
2253         << " height: " << bounds.rect_.height_ << " type: " << changeType;
2254     screenEventTracker_.RecordBoundsEvent(oss.str());
2255     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2256         TLOGE(WmsLogTag::DMS, "update screen rotation property permission denied!");
2257         return;
2258     }
2259     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2260     {
2261         DmsXcollie dmsXcollie("DMS:UpdateScreenRotationProperty:CacheForRotation", XCOLLIE_TIMEOUT_10S);
2262         if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_BEGIN) {
2263             // Rs is used to mark the start of the rotation animation
2264             TLOGI(WmsLogTag::DMS, "EnableCacheForRotation");
2265             RSInterfaces::GetInstance().EnableCacheForRotation();
2266         } else if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_END) {
2267             // Rs is used to mark the end of the rotation animation
2268             TLOGI(WmsLogTag::DMS, "DisableCacheForRotation");
2269             RSInterfaces::GetInstance().DisableCacheForRotation();
2270             return;
2271         } else if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY) {
2272             if (screenSession == nullptr) {
2273                 TLOGE(WmsLogTag::DMS, "fail to update screen rotation property, cannot find screen "
2274                     "%{public}" PRIu64"", screenId);
2275                 return;
2276             }
2277             sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
2278             TLOGI(WmsLogTag::DMS, "Update Screen Rotation Property Only");
2279             {
2280                 std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
2281                 screenSession->UpdatePropertyOnly(bounds, rotation, GetFoldDisplayMode());
2282             }
2283             NotifyDisplayChanged(displayInfo, DisplayChangeEvent::UPDATE_ROTATION);
2284             NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
2285             return;
2286         }
2287     }
2288     if (screenSession == nullptr) {
2289         TLOGE(WmsLogTag::DMS, "fail to update screen rotation property, cannot find screen %{public}" PRIu64"",
2290             screenId);
2291         return;
2292     }
2293     {
2294         std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
2295         screenSession->UpdatePropertyAfterRotation(bounds, rotation, GetFoldDisplayMode());
2296     }
2297     sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
2298     NotifyAndPublishEvent(displayInfo, screenId, screenSession);
2299 }
2300 
NotifyDisplayChanged(sptr<DisplayInfo> displayInfo,DisplayChangeEvent event)2301 void ScreenSessionManager::NotifyDisplayChanged(sptr<DisplayInfo> displayInfo, DisplayChangeEvent event)
2302 {
2303     if (displayInfo == nullptr) {
2304         TLOGE(WmsLogTag::DMS, "NotifyDisplayChanged error, displayInfo is nullptr.");
2305         return;
2306     }
2307     auto task = [=] {
2308         if (event == DisplayChangeEvent::UPDATE_REFRESHRATE) {
2309             TLOGD(WmsLogTag::DMS, "evevt:%{public}d, displayId:%{public}" PRIu64"",
2310                 event, displayInfo->GetDisplayId());
2311         } else {
2312             TLOGI(WmsLogTag::DMS, "evevt:%{public}d, displayId:%{public}" PRIu64"",
2313                 event, displayInfo->GetDisplayId());
2314         }
2315         auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
2316         if (agents.empty()) {
2317             TLOGI(WmsLogTag::DMS, "NotifyDisplayChanged agents is empty");
2318             return;
2319         }
2320         for (auto& agent : agents) {
2321             int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
2322             if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
2323                 agent->OnDisplayChange(displayInfo, event);
2324             }
2325         }
2326     };
2327     taskScheduler_->PostAsyncTask(task, "NotifyDisplayChanged");
2328 }
2329 
SetOrientation(ScreenId screenId,Orientation orientation)2330 DMError ScreenSessionManager::SetOrientation(ScreenId screenId, Orientation orientation)
2331 {
2332     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2333         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2334             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2335         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2336     }
2337     if (orientation < Orientation::UNSPECIFIED || orientation > Orientation::REVERSE_HORIZONTAL) {
2338         TLOGE(WmsLogTag::DMS, "set orientation: %{public}u", static_cast<uint32_t>(orientation));
2339         return DMError::DM_ERROR_INVALID_PARAM;
2340     }
2341     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2342     if (screenSession == nullptr) {
2343         TLOGE(WmsLogTag::DMS, "fail to set orientation, cannot find screen %{public}" PRIu64"", screenId);
2344         return DMError::DM_ERROR_NULLPTR;
2345     }
2346     // just for get orientation test
2347     screenSession->SetOrientation(orientation);
2348     screenSession->ScreenOrientationChange(orientation, GetFoldDisplayMode());
2349     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetOrientation");
2350     return DMError::DM_OK;
2351 }
2352 
SetRotation(ScreenId screenId,Rotation rotationAfter,bool isFromWindow)2353 bool ScreenSessionManager::SetRotation(ScreenId screenId, Rotation rotationAfter, bool isFromWindow)
2354 {
2355     TLOGI(WmsLogTag::DMS,
2356         "Enter SetRotation, screenId: %{public}" PRIu64 ", rotation: %{public}u, isFromWindow: %{public}u,",
2357         screenId, rotationAfter, isFromWindow);
2358     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2359     if (screenSession == nullptr) {
2360         TLOGE(WmsLogTag::DMS, "SetRotation error, cannot get screen with screenId: %{public}" PRIu64, screenId);
2361         return false;
2362     }
2363     if (rotationAfter == screenSession->GetRotation()) {
2364         TLOGE(WmsLogTag::DMS, "rotation not changed. screen %{public}" PRIu64" rotation %{public}u",
2365             screenId, rotationAfter);
2366         return false;
2367     }
2368     TLOGI(WmsLogTag::DMS, "set orientation. rotation %{public}u", rotationAfter);
2369     SetDisplayBoundary(screenSession);
2370     screenSession->SetRotation(rotationAfter);
2371     screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::ROTATION);
2372     NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
2373     NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::UPDATE_ROTATION);
2374     return true;
2375 }
2376 
SetSensorSubscriptionEnabled()2377 void ScreenSessionManager::SetSensorSubscriptionEnabled()
2378 {
2379     isAutoRotationOpen_ = system::GetParameter("persist.display.ar.enabled", "1") == "1";
2380     if (!isAutoRotationOpen_) {
2381         TLOGE(WmsLogTag::DMS, "autoRotation is not open");
2382         return;
2383     }
2384     ScreenSensorConnector::SubscribeRotationSensor();
2385     TLOGI(WmsLogTag::DMS, "subscribe rotation sensor successful");
2386 }
2387 
SetPostureAndHallSensorEnabled()2388 void ScreenSessionManager::SetPostureAndHallSensorEnabled()
2389 {
2390 #ifdef SENSOR_ENABLE
2391     if (!g_foldScreenFlag) {
2392         TLOGI(WmsLogTag::DMS, "current device is not fold phone.");
2393         return;
2394     }
2395     FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
2396     FoldScreenSensorManager::GetInstance().RegisterHallCallback();
2397     TLOGI(WmsLogTag::DMS, "subscribe Posture and Hall sensor successful");
2398     screenEventTracker_.RecordEvent("Dms subscribe Posture and Hall sensor finished.");
2399 #endif
2400 }
2401 
SetRotationFromWindow(Rotation targetRotation)2402 bool ScreenSessionManager::SetRotationFromWindow(Rotation targetRotation)
2403 {
2404     sptr<DisplayInfo> displayInfo = GetDefaultDisplayInfo();
2405     if (displayInfo == nullptr) {
2406         return false;
2407     }
2408     return SetRotation(displayInfo->GetScreenId(), targetRotation, true);
2409 }
2410 
GetScreenModesByDisplayId(DisplayId displayId)2411 sptr<SupportedScreenModes> ScreenSessionManager::GetScreenModesByDisplayId(DisplayId displayId)
2412 {
2413     auto displayInfo = GetDisplayInfoById(displayId);
2414     if (displayInfo == nullptr) {
2415         TLOGE(WmsLogTag::DMS, "can not get display.");
2416         return nullptr;
2417     }
2418     auto screenInfo = GetScreenInfoById(displayInfo->GetScreenId());
2419     if (screenInfo == nullptr) {
2420         TLOGE(WmsLogTag::DMS, "can not get screen.");
2421         return nullptr;
2422     }
2423     auto modes = screenInfo->GetModes();
2424     auto id = screenInfo->GetModeId();
2425     if (id >= modes.size()) {
2426         TLOGE(WmsLogTag::DMS, "can not get screenMode.");
2427         return nullptr;
2428     }
2429     return modes[id];
2430 }
2431 
GetScreenInfoByDisplayId(DisplayId displayId)2432 sptr<ScreenInfo> ScreenSessionManager::GetScreenInfoByDisplayId(DisplayId displayId)
2433 {
2434     auto displayInfo = GetDisplayInfoById(displayId);
2435     if (displayInfo == nullptr) {
2436         TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
2437         return nullptr;
2438     }
2439     return GetScreenInfoById(displayInfo->GetScreenId());
2440 }
2441 
NotifyPowerEventForDualDisplay(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)2442 int ScreenSessionManager::NotifyPowerEventForDualDisplay(DisplayPowerEvent event, EventStatus status,
2443     PowerStateChangeReason reason)
2444 {
2445     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2446     if (screenSessionMap_.empty()) {
2447         TLOGE(WmsLogTag::DMS, "[UL_POWER]screenSessionMap is empty");
2448         return NOTIFY_EVENT_FOR_DUAL_FAILED;
2449     }
2450     // The on/off screen will send a notification based on the number of screens.
2451     // The dual display device just notify the current screen usage
2452     if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
2453         ScreenId currentScreenId = foldScreenController_->GetCurrentScreenId();
2454         auto iter = screenSessionMap_.find(currentScreenId);
2455         if (iter != screenSessionMap_.end() && iter->second != nullptr) {
2456             iter->second->PowerStatusChange(event, status, reason);
2457         }
2458         return NOTIFY_EVENT_FOR_DUAL_SUCESS;
2459     }
2460     return NO_NEED_NOTIFY_EVENT_FOR_DUAL;
2461 }
2462 
NotifyDisplayPowerEvent(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)2463 bool ScreenSessionManager::NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status,
2464     PowerStateChangeReason reason)
2465 {
2466     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER);
2467     if (agents.empty()) {
2468         TLOGI(WmsLogTag::DMS, "[UL_POWER]NotifyDisplayPowerEvent agents is empty");
2469         return false;
2470     }
2471     TLOGD(WmsLogTag::DMS, "[UL_POWER]NotifyDisplayPowerEvent");
2472     for (auto& agent : agents) {
2473         agent->NotifyDisplayPowerEvent(event, status);
2474     }
2475     auto ret = NotifyPowerEventForDualDisplay(event, status, reason);
2476     if (ret == NOTIFY_EVENT_FOR_DUAL_FAILED) {
2477         TLOGE(WmsLogTag::DMS, "[UL_POWER]NotifyPowerEventForDualDisplay ret false");
2478         return false;
2479     } else if (ret == NOTIFY_EVENT_FOR_DUAL_SUCESS) {
2480         TLOGD(WmsLogTag::DMS, "[UL_POWER]NotifyPowerEventForDualDisplay ret sucess");
2481         return true;
2482     }
2483     auto screenIds = GetAllScreenIds();
2484     if (screenIds.empty()) {
2485         TLOGI(WmsLogTag::DMS, "[UL_POWER]no screenID");
2486         return false;
2487     }
2488     auto screenId = screenIds[0];
2489     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2490     if (screenSession == nullptr) {
2491         TLOGE(WmsLogTag::DMS, "[UL_POWER]Cannot get ScreenSession, screenId: %{public}" PRIu64"", screenId);
2492         return false;
2493     }
2494     screenSession->PowerStatusChange(event, status, reason);
2495     return true;
2496 }
2497 
NotifyDisplayStateChanged(DisplayId id,DisplayState state)2498 bool ScreenSessionManager::NotifyDisplayStateChanged(DisplayId id, DisplayState state)
2499 {
2500     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_STATE_LISTENER);
2501     if (agents.empty()) {
2502         TLOGI(WmsLogTag::DMS, "agents is empty");
2503         return false;
2504     }
2505     TLOGI(WmsLogTag::DMS, "notify enter!");
2506     for (auto& agent : agents) {
2507         agent->NotifyDisplayStateChanged(id, state);
2508     }
2509     return true;
2510 }
GetAllScreenInfos(std::vector<sptr<ScreenInfo>> & screenInfos)2511 DMError ScreenSessionManager::GetAllScreenInfos(std::vector<sptr<ScreenInfo>>& screenInfos)
2512 {
2513     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2514         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2515             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2516         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2517     }
2518     std::vector<ScreenId> screenIds = GetAllScreenIds();
2519     for (auto screenId : screenIds) {
2520         auto screenInfo = GetScreenInfoById(screenId);
2521         if (screenInfo == nullptr) {
2522             TLOGE(WmsLogTag::DMS, "GetAllScreenInfos cannot find screenInfo: %{public}" PRIu64"", screenId);
2523             continue;
2524         }
2525         screenInfos.emplace_back(screenInfo);
2526     }
2527     return DMError::DM_OK;
2528 }
2529 
GetAllScreenIds() const2530 std::vector<ScreenId> ScreenSessionManager::GetAllScreenIds() const
2531 {
2532     std::vector<ScreenId> res;
2533     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2534     for (const auto& iter : screenSessionMap_) {
2535         res.emplace_back(iter.first);
2536     }
2537     return res;
2538 }
2539 
GetScreenSupportedColorGamuts(ScreenId screenId,std::vector<ScreenColorGamut> & colorGamuts)2540 DMError ScreenSessionManager::GetScreenSupportedColorGamuts(ScreenId screenId,
2541     std::vector<ScreenColorGamut>& colorGamuts)
2542 {
2543     TLOGI(WmsLogTag::DMS, "GetScreenSupportedColorGamuts ENTER");
2544     if (!SessionPermission::IsSystemCalling()) {
2545         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2546             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2547         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2548     }
2549     sptr<ScreenSession> screen = GetScreenSession(screenId);
2550     if (screen == nullptr) {
2551         TLOGE(WmsLogTag::DMS, "GetScreenSupportedColorGamuts nullptr");
2552         return DMError::DM_ERROR_INVALID_PARAM;
2553     }
2554     return screen->GetScreenSupportedColorGamuts(colorGamuts);
2555 }
2556 
GetPixelFormat(ScreenId screenId,GraphicPixelFormat & pixelFormat)2557 DMError ScreenSessionManager::GetPixelFormat(ScreenId screenId, GraphicPixelFormat& pixelFormat)
2558 {
2559     TLOGI(WmsLogTag::DMS, "GetPixelFormat::ScreenId: %{public}" PRIu64, screenId);
2560     if (screenId == SCREEN_ID_INVALID) {
2561         TLOGE(WmsLogTag::DMS, "GetPixelFormat screenId invalid");
2562         return DMError::DM_ERROR_INVALID_PARAM;
2563     }
2564     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2565     if (screenSession == nullptr) {
2566         return DMError::DM_ERROR_INVALID_PARAM;
2567     }
2568     return screenSession->GetPixelFormat(pixelFormat);
2569 }
2570 
SetPixelFormat(ScreenId screenId,GraphicPixelFormat pixelFormat)2571 DMError ScreenSessionManager::SetPixelFormat(ScreenId screenId, GraphicPixelFormat pixelFormat)
2572 {
2573     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2574         TLOGE(WmsLogTag::DMS, "set pixel format  permission denied!");
2575         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2576     }
2577 
2578     TLOGI(WmsLogTag::DMS, "SetPixelFormat::ScreenId: %{public}" PRIu64 ", pixelFormat %{public}d",
2579         screenId, pixelFormat);
2580     if (screenId == SCREEN_ID_INVALID) {
2581         TLOGE(WmsLogTag::DMS, "SetPixelFormat screenId invalid");
2582         return DMError::DM_ERROR_INVALID_PARAM;
2583     }
2584     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2585     if (screenSession == nullptr) {
2586         return DMError::DM_ERROR_INVALID_PARAM;
2587     }
2588     return screenSession->SetPixelFormat(pixelFormat);
2589 }
2590 
GetSupportedHDRFormats(ScreenId screenId,std::vector<ScreenHDRFormat> & hdrFormats)2591 DMError ScreenSessionManager::GetSupportedHDRFormats(ScreenId screenId,
2592     std::vector<ScreenHDRFormat>& hdrFormats)
2593 {
2594     TLOGI(WmsLogTag::DMS, "GetSupportedHDRFormats %{public}" PRIu64, screenId);
2595     sptr<ScreenSession> screen = GetScreenSession(screenId);
2596     if (screen == nullptr) {
2597         TLOGE(WmsLogTag::DMS, "GetSupportedHDRFormats nullptr");
2598         return DMError::DM_ERROR_INVALID_PARAM;
2599     }
2600     return screen->GetSupportedHDRFormats(hdrFormats);
2601 }
2602 
GetScreenHDRFormat(ScreenId screenId,ScreenHDRFormat & hdrFormat)2603 DMError ScreenSessionManager::GetScreenHDRFormat(ScreenId screenId, ScreenHDRFormat& hdrFormat)
2604 {
2605     TLOGI(WmsLogTag::DMS, "GetScreenHDRFormat::ScreenId: %{public}" PRIu64, screenId);
2606     if (screenId == SCREEN_ID_INVALID) {
2607         TLOGE(WmsLogTag::DMS, "screenId invalid");
2608         return DMError::DM_ERROR_INVALID_PARAM;
2609     }
2610     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2611     if (screenSession == nullptr) {
2612         return DMError::DM_ERROR_INVALID_PARAM;
2613     }
2614     return screenSession->GetScreenHDRFormat(hdrFormat);
2615 }
2616 
SetScreenHDRFormat(ScreenId screenId,int32_t modeIdx)2617 DMError ScreenSessionManager::SetScreenHDRFormat(ScreenId screenId, int32_t modeIdx)
2618 {
2619     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2620         TLOGE(WmsLogTag::DMS, "set screen HDR format permission denied!");
2621         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2622     }
2623 
2624     TLOGI(WmsLogTag::DMS, "SetScreenHDRFormat::ScreenId: %{public}" PRIu64 ", modeIdx %{public}d", screenId, modeIdx);
2625     if (screenId == SCREEN_ID_INVALID) {
2626         TLOGE(WmsLogTag::DMS, "SetScreenHDRFormat screenId invalid");
2627         return DMError::DM_ERROR_INVALID_PARAM;
2628     }
2629     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2630     if (screenSession == nullptr) {
2631         return DMError::DM_ERROR_INVALID_PARAM;
2632     }
2633     return screenSession->SetScreenHDRFormat(modeIdx);
2634 }
2635 
GetSupportedColorSpaces(ScreenId screenId,std::vector<GraphicCM_ColorSpaceType> & colorSpaces)2636 DMError ScreenSessionManager::GetSupportedColorSpaces(ScreenId screenId,
2637     std::vector<GraphicCM_ColorSpaceType>& colorSpaces)
2638 {
2639     TLOGI(WmsLogTag::DMS, "GetSupportedColorSpaces %{public}" PRIu64, screenId);
2640     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2641     if (screenSession == nullptr) {
2642         TLOGE(WmsLogTag::DMS, "GetSupportedColorSpaces nullptr");
2643         return DMError::DM_ERROR_INVALID_PARAM;
2644     }
2645     return screenSession->GetSupportedColorSpaces(colorSpaces);
2646 }
2647 
GetScreenColorSpace(ScreenId screenId,GraphicCM_ColorSpaceType & colorSpace)2648 DMError ScreenSessionManager::GetScreenColorSpace(ScreenId screenId, GraphicCM_ColorSpaceType& colorSpace)
2649 {
2650     TLOGI(WmsLogTag::DMS, "GetScreenColorSpace::ScreenId: %{public}" PRIu64, screenId);
2651     if (screenId == SCREEN_ID_INVALID) {
2652         TLOGE(WmsLogTag::DMS, "screenId invalid");
2653         return DMError::DM_ERROR_INVALID_PARAM;
2654     }
2655     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2656     if (screenSession == nullptr) {
2657         return DMError::DM_ERROR_INVALID_PARAM;
2658     }
2659     return screenSession->GetScreenColorSpace(colorSpace);
2660 }
2661 
SetScreenColorSpace(ScreenId screenId,GraphicCM_ColorSpaceType colorSpace)2662 DMError ScreenSessionManager::SetScreenColorSpace(ScreenId screenId, GraphicCM_ColorSpaceType colorSpace)
2663 {
2664     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2665         TLOGE(WmsLogTag::DMS, "set screen color space permission denied!");
2666         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2667     }
2668 
2669     TLOGI(WmsLogTag::DMS, "SetScreenColorSpace::ScreenId: %{public}" PRIu64 ", colorSpace %{public}d",
2670         screenId, colorSpace);
2671     if (screenId == SCREEN_ID_INVALID) {
2672         TLOGE(WmsLogTag::DMS, "SetScreenColorSpace screenId invalid");
2673         return DMError::DM_ERROR_INVALID_PARAM;
2674     }
2675     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2676     if (screenSession == nullptr) {
2677         return DMError::DM_ERROR_INVALID_PARAM;
2678     }
2679     return screenSession->SetScreenColorSpace(colorSpace);
2680 }
2681 
AddVirtualScreenDeathRecipient(const sptr<IRemoteObject> & displayManagerAgent,ScreenId smsScreenId)2682 void ScreenSessionManager::AddVirtualScreenDeathRecipient(const sptr<IRemoteObject>& displayManagerAgent,
2683     ScreenId smsScreenId)
2684 {
2685     if (deathRecipient_ == nullptr) {
2686         TLOGI(WmsLogTag::DMS, "CreateVirtualScreen Create deathRecipient");
2687         deathRecipient_ =
2688             new(std::nothrow) AgentDeathRecipient([this](const sptr<IRemoteObject>& agent) { OnRemoteDied(agent); });
2689     }
2690     if (deathRecipient_ != nullptr) {
2691         auto agIter = screenAgentMap_.find(displayManagerAgent);
2692         if (agIter == screenAgentMap_.end()) {
2693             displayManagerAgent->AddDeathRecipient(deathRecipient_);
2694         }
2695     }
2696     screenAgentMap_[displayManagerAgent].emplace_back(smsScreenId);
2697 }
2698 
CreateVirtualScreen(VirtualScreenOption option,const sptr<IRemoteObject> & displayManagerAgent)2699 ScreenId ScreenSessionManager::CreateVirtualScreen(VirtualScreenOption option,
2700                                                    const sptr<IRemoteObject>& displayManagerAgent)
2701 {
2702     if (!Permission::IsSystemCalling() && !SessionPermission::IsShellCall()) {
2703         return ERROR_ID_NOT_SYSTEM_APP;
2704     }
2705     if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
2706         !SessionPermission::IsShellCall()) {
2707         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2708             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2709         return SCREEN_ID_INVALID;
2710     }
2711     ExitCoordination("CreateVirtualScreen");
2712     TLOGI(WmsLogTag::DMS, "ENTER");
2713     if (SessionPermission::IsBetaVersion()) {
2714         CheckAndSendHiSysEvent("CREATE_VIRTUAL_SCREEN", "hmos.screenrecorder");
2715     }
2716     if (clientProxy_ && option.missionIds_.size() > 0) {
2717         std::vector<uint64_t> surfaceNodeIds;
2718         clientProxy_->OnGetSurfaceNodeIdsFromMissionIdsChanged(option.missionIds_, surfaceNodeIds, false);
2719         option.missionIds_ = surfaceNodeIds;
2720     }
2721     TLOGI(WmsLogTag::DMS, "missionID size:%{public}ud", static_cast<uint32_t>(option.missionIds_.size()));
2722     ScreenId rsId = rsInterface_.CreateVirtualScreen(option.name_, option.width_,
2723         option.height_, option.surface_, SCREEN_ID_INVALID, option.flags_, option.missionIds_);
2724     if (rsId == SCREEN_ID_INVALID) {
2725         TLOGI(WmsLogTag::DMS, "rsId is invalid");
2726         return SCREEN_ID_INVALID;
2727     }
2728     TLOGI(WmsLogTag::DMS, "rsId: %{public}" PRIu64"", rsId);
2729     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CreateVirtualScreen(%s)", option.name_.c_str());
2730     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2731     ScreenId smsScreenId = SCREEN_ID_INVALID;
2732     if (!screenIdManager_.ConvertToSmsScreenId(rsId, smsScreenId)) {
2733         smsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsId);
2734         auto screenSession = InitVirtualScreen(smsScreenId, rsId, option);
2735         if (screenSession == nullptr) {
2736             TLOGI(WmsLogTag::DMS, "screenSession is nullptr");
2737             screenIdManager_.DeleteScreenId(smsScreenId);
2738             return SCREEN_ID_INVALID;
2739         }
2740         screenSession->SetName(option.name_);
2741         screenSession->SetMirrorScreenType(MirrorScreenType::VIRTUAL_MIRROR);
2742         screenSessionMap_.insert(std::make_pair(smsScreenId, screenSession));
2743         if (option.name_ == "CastEngine") {
2744             screenSession->SetVirtualScreenFlag(VirtualScreenFlag::CAST);
2745         }
2746         NotifyScreenConnected(screenSession->ConvertToScreenInfo());
2747         TLOGI(WmsLogTag::DMS, "create screenId: %{public}" PRIu64", rsId: %{public}" PRIu64"", smsScreenId, rsId);
2748         if (displayManagerAgent == nullptr) {
2749             virtualScreenCount_ = virtualScreenCount_ + 1;
2750             NotifyCaptureStatusChanged();
2751             return smsScreenId;
2752         }
2753         AddVirtualScreenDeathRecipient(displayManagerAgent, smsScreenId);
2754     }
2755     virtualScreenCount_ = virtualScreenCount_ + 1;
2756     NotifyCaptureStatusChanged();
2757     return smsScreenId;
2758 }
2759 
SetVirtualScreenSurface(ScreenId screenId,sptr<IBufferProducer> surface)2760 DMError ScreenSessionManager::SetVirtualScreenSurface(ScreenId screenId, sptr<IBufferProducer> surface)
2761 {
2762     if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
2763         !SessionPermission::IsShellCall()) {
2764         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2765             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2766         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2767     }
2768     if (surface == nullptr) {
2769         TLOGE(WmsLogTag::DMS, "surface is null");
2770         return DMError::DM_ERROR_INVALID_PARAM;
2771     }
2772     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2773     if (screenSession == nullptr) {
2774         TLOGE(WmsLogTag::DMS, "No such screen.");
2775         return DMError::DM_ERROR_INVALID_PARAM;
2776     }
2777     TLOGI(WmsLogTag::DMS, "enter set virtual screen surface");
2778     ScreenId rsScreenId;
2779     int32_t res = -1;
2780     if (screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
2781         sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(surface);
2782         if (pSurface != nullptr) {
2783             res = rsInterface_.SetVirtualScreenSurface(rsScreenId, pSurface);
2784         }
2785     }
2786     if (res != 0) {
2787         TLOGE(WmsLogTag::DMS, "fail to set virtual screen surface in RenderService");
2788         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
2789     }
2790     return DMError::DM_OK;
2791 }
2792 
SetVirtualMirrorScreenScaleMode(ScreenId screenId,ScreenScaleMode scaleMode)2793 DMError ScreenSessionManager::SetVirtualMirrorScreenScaleMode(ScreenId screenId, ScreenScaleMode scaleMode)
2794 {
2795     if (!SessionPermission::IsSystemCalling()) {
2796         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2797             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2798         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2799     }
2800     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2801     if (screenSession == nullptr) {
2802         TLOGE(WmsLogTag::DMS, "No such screen.");
2803         return DMError::DM_ERROR_INVALID_PARAM;
2804     }
2805     ScreenId rsScreenId;
2806     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
2807         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
2808         return DMError::DM_ERROR_INVALID_PARAM;
2809     }
2810     bool res = rsInterface_.SetVirtualMirrorScreenScaleMode(rsScreenId, scaleMode);
2811     if (!res) {
2812         TLOGE(WmsLogTag::DMS, "failed in RenderService");
2813         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
2814     }
2815     return DMError::DM_OK;
2816 }
2817 
SetVirtualMirrorScreenCanvasRotation(ScreenId screenId,bool autoRotate)2818 DMError ScreenSessionManager::SetVirtualMirrorScreenCanvasRotation(ScreenId screenId, bool autoRotate)
2819 {
2820     if (!SessionPermission::IsSystemCalling()) {
2821         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2822             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2823         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2824     }
2825     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2826     if (screenSession == nullptr) {
2827         TLOGE(WmsLogTag::DMS, "No such screen.");
2828         return DMError::DM_ERROR_INVALID_PARAM;
2829     }
2830     TLOGI(WmsLogTag::DMS, "enter set virtual mirror screen canvas rotation");
2831     bool res = false;
2832     ScreenId rsScreenId;
2833     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
2834         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
2835         return DMError::DM_ERROR_INVALID_PARAM;
2836     }
2837     res = rsInterface_.SetVirtualMirrorScreenCanvasRotation(rsScreenId, autoRotate);
2838     if (!res) {
2839         TLOGE(WmsLogTag::DMS, "failed in RenderService");
2840         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
2841     }
2842     TLOGI(WmsLogTag::DMS, "set virtual mirror screen canvas rotation success");
2843     return DMError::DM_OK;
2844 }
2845 
ResizeVirtualScreen(ScreenId screenId,uint32_t width,uint32_t height)2846 DMError ScreenSessionManager::ResizeVirtualScreen(ScreenId screenId, uint32_t width, uint32_t height)
2847 {
2848     if (!SessionPermission::IsSystemCalling()) {
2849         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2850             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2851         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2852     }
2853     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64", width: %{public}u, height: %{public}u.",
2854         screenId, width, height);
2855     sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2856     if (screenSession == nullptr) {
2857         TLOGE(WmsLogTag::DMS, "No such screen.");
2858         return DMError::DM_ERROR_INVALID_PARAM;
2859     }
2860     ScreenId rsScreenId;
2861     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
2862         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
2863         return DMError::DM_ERROR_INVALID_PARAM;
2864     }
2865     rsInterface_.ResizeVirtualScreen(rsScreenId, width, height);
2866     screenSession->Resize(width, height);
2867     screenSession->PropertyChange(screenSession->GetScreenProperty(),
2868         ScreenPropertyChangeReason::VIRTUAL_SCREEN_RESIZE);
2869     return DMError::DM_OK;
2870 }
2871 
DestroyVirtualScreen(ScreenId screenId)2872 DMError ScreenSessionManager::DestroyVirtualScreen(ScreenId screenId)
2873 {
2874     if (!SessionPermission::IsSystemCalling()) {
2875         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2876             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2877         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2878     }
2879     if (static_cast<uint64_t>(screenId) < static_cast<uint64_t>(MINIMUM_VIRTUAL_SCREEN_ID)) {
2880         TLOGE(WmsLogTag::DMS, "virtual screenId is invalid, id: %{public}" PRIu64"", static_cast<uint64_t>(screenId));
2881         return DMError::DM_ERROR_INVALID_PARAM;
2882     }
2883     // virtual screen destroy callback to notify scb
2884     TLOGI(WmsLogTag::DMS, "destroy virtual screen");
2885     OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED);
2886     ScreenId rsScreenId = SCREEN_ID_INVALID;
2887     {
2888         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2889         screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
2890         for (auto &agentIter : screenAgentMap_) {
2891             auto iter = std::find(agentIter.second.begin(), agentIter.second.end(), screenId);
2892             if (iter != agentIter.second.end()) {
2893                 iter = agentIter.second.erase(iter);
2894                 if (agentIter.first != nullptr && agentIter.second.empty()) {
2895                     screenAgentMap_.erase(agentIter.first);
2896                 }
2897                 break;
2898             }
2899         }
2900     }
2901     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyVirtualScreen(%" PRIu64")", screenId);
2902     auto screen = GetScreenSession(screenId);
2903     if (rsScreenId != SCREEN_ID_INVALID && screen != nullptr) {
2904         if (CheckScreenInScreenGroup(screen)) {
2905             NotifyDisplayDestroy(screenId);
2906         }
2907         {
2908             std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2909             auto screenGroup = RemoveFromGroupLocked(screen);
2910             if (screenGroup != nullptr) {
2911                 NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
2912             }
2913             screenSessionMap_.erase(screenId);
2914         }
2915         NotifyScreenDisconnected(screenId);
2916         TLOGI(WmsLogTag::DMS, "DestroyVirtualScreen success, id: %{public}" PRIu64"", screenId);
2917     }
2918     screenIdManager_.DeleteScreenId(screenId);
2919     virtualScreenCount_ = virtualScreenCount_ > 0 ? virtualScreenCount_ - 1 : 0;
2920     NotifyCaptureStatusChanged();
2921     if (rsScreenId == SCREEN_ID_INVALID) {
2922         TLOGE(WmsLogTag::DMS, "DestroyVirtualScreen: No corresponding rsScreenId");
2923         return DMError::DM_ERROR_INVALID_PARAM;
2924     }
2925     rsInterface_.RemoveVirtualScreen(rsScreenId);
2926     return DMError::DM_OK;
2927 }
2928 
DisableMirror(bool disableOrNot)2929 DMError ScreenSessionManager::DisableMirror(bool disableOrNot)
2930 {
2931     TLOGI(WmsLogTag::DMS, "DisableMirror %{public}d", disableOrNot);
2932     if (!SessionPermission::IsSystemCalling()) {
2933         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2934             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2935         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2936     }
2937     TLOGI(WmsLogTag::DMS, "DisableMirror enter %{public}d", disableOrNot);
2938     if (disableOrNot) {
2939         std::vector<ScreenId> screenIds;
2940         auto allScreenIds = GetAllScreenIds();
2941         for (auto screenId : allScreenIds) {
2942             auto screen = GetScreenSession(screenId);
2943             if (screen && screen->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
2944                 screenIds.push_back(screenId);
2945             }
2946         }
2947         StopMirror(screenIds);
2948     }
2949     return DMError::DM_OK;
2950 }
2951 
MirrorSwitchNotify(ScreenId screenId)2952 void ScreenSessionManager::MirrorSwitchNotify(ScreenId screenId)
2953 {
2954     auto mirrorScreen = GetScreenSession(screenId);
2955     if (mirrorScreen != nullptr) {
2956         mirrorScreen->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
2957         NotifyScreenChanged(mirrorScreen->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE);
2958     }
2959 }
2960 
MakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,ScreenId & screenGroupId)2961 DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
2962                                          ScreenId& screenGroupId)
2963 {
2964     TLOGI(WmsLogTag::DMS, "enter!");
2965     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2966         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
2967             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2968         return DMError::DM_ERROR_NOT_SYSTEM_APP;
2969     }
2970     if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
2971         TLOGW(WmsLogTag::DMS, "disabled by edm!");
2972         return DMError::DM_ERROR_INVALID_PERMISSION;
2973     }
2974 
2975     TLOGI(WmsLogTag::DMS, "mainScreenId :%{public}" PRIu64"", mainScreenId);
2976     auto allMirrorScreenIds = GetAllValidScreenIds(mirrorScreenIds);
2977     auto iter = std::find(allMirrorScreenIds.begin(), allMirrorScreenIds.end(), mainScreenId);
2978     if (iter != allMirrorScreenIds.end()) {
2979         allMirrorScreenIds.erase(iter);
2980     }
2981     auto mainScreen = GetScreenSession(mainScreenId);
2982     if (mainScreen == nullptr || allMirrorScreenIds.empty()) {
2983         TLOGE(WmsLogTag::DMS, "MakeMirror fail. mainScreen :%{public}" PRIu64", screens size:%{public}u",
2984             mainScreenId, static_cast<uint32_t>(allMirrorScreenIds.size()));
2985         return DMError::DM_ERROR_INVALID_PARAM;
2986     }
2987     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeMirror start");
2988     TLOGI(WmsLogTag::DMS, "make mirror start");
2989     for (ScreenId screenId : allMirrorScreenIds) {
2990         OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED);
2991     }
2992     DMError makeResult = MultiScreenManager::GetInstance().MirrorSwitch(mainScreenId,
2993         allMirrorScreenIds, screenGroupId);
2994     if (makeResult != DMError::DM_OK) {
2995         TLOGE(WmsLogTag::DMS, "MakeMirror set mirror failed.");
2996         return makeResult;
2997     }
2998     for (ScreenId screenId : allMirrorScreenIds) {
2999         MirrorSwitchNotify(screenId);
3000     }
3001     RegisterCastObserver(allMirrorScreenIds);
3002     TLOGI(WmsLogTag::DMS, "make mirror notify scb end makeResult=%{public}d", makeResult);
3003     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeMirror end");
3004     return makeResult;
3005 }
3006 
RegisterCastObserver(std::vector<ScreenId> & mirrorScreenIds)3007 void ScreenSessionManager::RegisterCastObserver(std::vector<ScreenId>& mirrorScreenIds)
3008 {
3009     for (ScreenId screenId : mirrorScreenIds) {
3010         if (GetVirtualScreenFlag(screenId) == VirtualScreenFlag::CAST) {
3011             mirrorScreenIds_ = mirrorScreenIds;
3012             TLOGI(WmsLogTag::DMS, "Register Setting cast Observer");
3013             SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetCastFromSettingData(); };
3014             ScreenSettingHelper::RegisterSettingCastObserver(updateFunc);
3015         }
3016     }
3017 }
3018 
SetCastFromSettingData()3019 void ScreenSessionManager::SetCastFromSettingData()
3020 {
3021     bool enable;
3022     bool ret = ScreenSettingHelper::GetSettingCast(enable);
3023     if (!ret) {
3024         TLOGW(WmsLogTag::DMS, "get setting cast failed, default enable false");
3025         enable = false;
3026     } else {
3027         TLOGI(WmsLogTag::DMS, "get setting cast success, enable: %{public}u", enable);
3028     }
3029     for (ScreenId screenId : mirrorScreenIds_) {
3030         ScreenId rsScreenId;
3031         if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
3032             TLOGE(WmsLogTag::DMS, "No corresponding rsId");
3033             continue;
3034         }
3035         rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, enable);
3036     }
3037 }
3038 
RegisterSettingRotationObserver()3039 void ScreenSessionManager::RegisterSettingRotationObserver()
3040 {
3041     TLOGI(WmsLogTag::DMS, "Register setting rotation observer");
3042     SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) {
3043         int32_t rotation = -1;
3044         int32_t screenId = -1;
3045         if (ScreenSettingHelper::GetSettingRotation(rotation) &&
3046             ScreenSettingHelper::GetSettingRotationScreenId(screenId)) {
3047             TLOGI(WmsLogTag::DMS, "current dms setting rotation:%{public}d, screenId:%{public}d",
3048                 rotation, screenId);
3049         } else {
3050             TLOGI(WmsLogTag::DMS, "get current dms setting rotation and screenId failed");
3051         }
3052     };
3053     ScreenSettingHelper::RegisterSettingRotationObserver(updateFunc);
3054 }
3055 
StopMirror(const std::vector<ScreenId> & mirrorScreenIds)3056 DMError ScreenSessionManager::StopMirror(const std::vector<ScreenId>& mirrorScreenIds)
3057 {
3058     if (!SessionPermission::IsSystemCalling()) {
3059         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
3060             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3061         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3062     }
3063     auto allMirrorScreenIds = GetAllValidScreenIds(mirrorScreenIds);
3064     if (allMirrorScreenIds.empty()) {
3065         TLOGI(WmsLogTag::DMS, "StopMirror done. screens' size:%{public}u",
3066             static_cast<uint32_t>(allMirrorScreenIds.size()));
3067         return DMError::DM_OK;
3068     }
3069 
3070     DMError ret = StopScreens(allMirrorScreenIds, ScreenCombination::SCREEN_MIRROR);
3071     if (ret != DMError::DM_OK) {
3072         TLOGE(WmsLogTag::DMS, "StopMirror failed.");
3073         return ret;
3074     }
3075     UnRegisterCastObserver(allMirrorScreenIds);
3076     return DMError::DM_OK;
3077 }
3078 
UnRegisterCastObserver(std::vector<ScreenId> & mirrorScreenIds)3079 void ScreenSessionManager::UnRegisterCastObserver(std::vector<ScreenId>& mirrorScreenIds)
3080 {
3081     for (ScreenId screenId : mirrorScreenIds) {
3082         if (GetVirtualScreenFlag(screenId) == VirtualScreenFlag::CAST) {
3083             ScreenSettingHelper::UnregisterSettingCastObserver();
3084         }
3085     }
3086 }
3087 
StopScreens(const std::vector<ScreenId> & screenIds,ScreenCombination stopCombination)3088 DMError ScreenSessionManager::StopScreens(const std::vector<ScreenId>& screenIds, ScreenCombination stopCombination)
3089 {
3090     for (ScreenId screenId : screenIds) {
3091         TLOGI(WmsLogTag::DMS, "StopScreens ScreenId: %{public}" PRIu64"", screenId);
3092         auto screen = GetScreenSession(screenId);
3093         if (screen == nullptr) {
3094             TLOGW(WmsLogTag::DMS, "StopScreens screen:%{public}" PRIu64" is nullptr", screenId);
3095             continue;
3096         }
3097         sptr<ScreenSessionGroup> screenGroup = GetAbstractScreenGroup(screen->groupSmsId_);
3098         if (!screenGroup) {
3099             TLOGW(WmsLogTag::DMS, "StopScreens groupDmsId:%{public}" PRIu64"is not in smsScreenGroupMap_",
3100                 screen->groupSmsId_);
3101             continue;
3102         }
3103         if (screenGroup->combination_ != stopCombination) {
3104             TLOGW(WmsLogTag::DMS, "StopScreens try to stop screen in another combination");
3105             continue;
3106         }
3107         if (screenGroup->combination_ == ScreenCombination::SCREEN_MIRROR &&
3108             screen->screenId_ == screenGroup->mirrorScreenId_) {
3109             TLOGW(WmsLogTag::DMS, "StopScreens try to stop main mirror screen");
3110             continue;
3111         }
3112         bool res = RemoveChildFromGroup(screen, screenGroup);
3113         if (res) {
3114             NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
3115         }
3116     }
3117     return DMError::DM_OK;
3118 }
3119 
GetVirtualScreenFlag(ScreenId screenId)3120 VirtualScreenFlag ScreenSessionManager::GetVirtualScreenFlag(ScreenId screenId)
3121 {
3122     if (!SessionPermission::IsSystemCalling()) {
3123         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
3124             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3125         return VirtualScreenFlag::DEFAULT;
3126     }
3127     auto screen = GetScreenSession(screenId);
3128     if (screen == nullptr) {
3129         TLOGE(WmsLogTag::DMS, "get virtual screen flag screen session null");
3130         return VirtualScreenFlag::DEFAULT;
3131     }
3132     return screen->GetVirtualScreenFlag();
3133 }
3134 
SetVirtualScreenFlag(ScreenId screenId,VirtualScreenFlag screenFlag)3135 DMError ScreenSessionManager::SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag)
3136 {
3137     if (!SessionPermission::IsSystemCalling()) {
3138         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
3139             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3140         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3141     }
3142     if (screenFlag < VirtualScreenFlag::DEFAULT || screenFlag >= VirtualScreenFlag::MAX) {
3143         TLOGE(WmsLogTag::DMS, "set virtual screen flag range error");
3144         return DMError::DM_ERROR_INVALID_PARAM;
3145     }
3146     auto screen = GetScreenSession(screenId);
3147     if (screen == nullptr) {
3148         TLOGE(WmsLogTag::DMS, "set virtual screen flag screen session null");
3149         return DMError::DM_ERROR_INVALID_PARAM;
3150     }
3151     screen->SetVirtualScreenFlag(screenFlag);
3152     return DMError::DM_OK;
3153 }
3154 
SetVirtualScreenRefreshRate(ScreenId screenId,uint32_t refreshInterval)3155 DMError ScreenSessionManager::SetVirtualScreenRefreshRate(ScreenId screenId, uint32_t refreshInterval)
3156 {
3157     if (!SessionPermission::IsSystemCalling()) {
3158         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
3159             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3160         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3161     }
3162     TLOGI(WmsLogTag::DMS, "SetVirtualScreenRefreshRate, screenId: %{public}" PRIu64", refreshInterval:  %{public}u",
3163         screenId, refreshInterval);
3164     if (screenId == GetDefaultScreenId()) {
3165         TLOGE(WmsLogTag::DMS,
3166         "cannot set refresh rate of main screen, main screen id: %{public}" PRIu64".", GetDefaultScreenId());
3167         return DMError::DM_ERROR_INVALID_PARAM;
3168     }
3169     if (refreshInterval == 0) {
3170         TLOGE(WmsLogTag::DMS, "SetVirtualScreenRefreshRate, refresh interval is 0.");
3171         return DMError::DM_ERROR_INVALID_PARAM;
3172     }
3173     auto screenSession = GetScreenSession(screenId);
3174     auto defaultScreenSession = GetDefaultScreenSession();
3175     if (screenSession == nullptr || defaultScreenSession == nullptr) {
3176         TLOGE(WmsLogTag::DMS, "SetVirtualScreenRefreshRate, screenSession is null.");
3177         return DMError::DM_ERROR_INVALID_PARAM;
3178     }
3179     ScreenId rsScreenId;
3180     if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
3181         TLOGE(WmsLogTag::DMS, "SetVirtualScreenRefreshRate, No corresponding rsId.");
3182         return DMError::DM_ERROR_INVALID_PARAM;
3183     }
3184     int32_t res = rsInterface_.SetScreenSkipFrameInterval(rsScreenId, refreshInterval);
3185     if (res != StatusCode::SUCCESS) {
3186         TLOGE(WmsLogTag::DMS, "SetVirtualScreenRefreshRate, rsInterface error: %{public}d", res);
3187         return DMError::DM_ERROR_INVALID_PARAM;
3188     }
3189     // when skipFrameInterval > 10 means the skipFrameInterval is the virtual screen refresh rate
3190     if (refreshInterval > IRREGULAR_REFRESH_RATE_SKIP_THRETHOLD) {
3191         screenSession->UpdateRefreshRate(refreshInterval);
3192     } else {
3193         screenSession->UpdateRefreshRate(defaultScreenSession->GetRefreshRate() / refreshInterval);
3194     }
3195     TLOGI(WmsLogTag::DMS, "refreshInterval is %{public}d", refreshInterval);
3196     return DMError::DM_OK;
3197 }
3198 
VirtualScreenUniqueSwitch(const std::vector<ScreenId> & screenIds)3199 DMError ScreenSessionManager::VirtualScreenUniqueSwitch(const std::vector<ScreenId>& screenIds)
3200 {
3201     TLOGI(WmsLogTag::DMS, "enter");
3202     auto defaultScreen = GetDefaultScreenSession();
3203     if (!defaultScreen) {
3204         TLOGE(WmsLogTag::DMS, "default screen is nullptr");
3205         return DMError::DM_ERROR_NULLPTR;
3206     }
3207     defaultScreen->groupSmsId_ = 1;
3208     {
3209         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3210         auto iter = smsScreenGroupMap_.find(defaultScreen->groupSmsId_);
3211         if (iter != smsScreenGroupMap_.end()) {
3212             smsScreenGroupMap_.erase(iter);
3213         }
3214     }
3215     DMError uniqueSwitchRet = MultiScreenManager::GetInstance().VirtualScreenUniqueSwitch(defaultScreen, screenIds);
3216     TLOGI(WmsLogTag::DMS, "virtual screen unique switch result: %{public}d", uniqueSwitchRet);
3217     return uniqueSwitchRet;
3218 }
3219 
MakeUniqueScreen(const std::vector<ScreenId> & screenIds)3220 DMError ScreenSessionManager::MakeUniqueScreen(const std::vector<ScreenId>& screenIds)
3221 {
3222     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3223         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
3224             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3225         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3226     }
3227     TLOGI(WmsLogTag::DMS, "enter!");
3228     if (screenIds.empty()) {
3229         TLOGE(WmsLogTag::DMS, "screen is empty");
3230         return DMError::DM_ERROR_INVALID_PARAM;
3231     }
3232     ScreenId uniqueScreenId = screenIds[0];
3233     auto uniqueScreen = GetScreenSession(uniqueScreenId);
3234     if (uniqueScreen != nullptr) {
3235         if (uniqueScreen->GetSourceMode() == ScreenSourceMode::SCREEN_UNIQUE) {
3236             TLOGI(WmsLogTag::DMS, "make unique ignore");
3237             return DMError::DM_OK;
3238         }
3239         return MultiScreenManager::GetInstance().UniqueSwitch(screenIds);
3240     }
3241     for (auto screenId : screenIds) {
3242         ScreenId rsScreenId = SCREEN_ID_INVALID;
3243         bool res = ConvertScreenIdToRsScreenId(screenId, rsScreenId);
3244         TLOGI(WmsLogTag::DMS, "unique screenId: %{public}" PRIu64" rsScreenId: %{public}" PRIu64"",
3245             screenId, rsScreenId);
3246         if (!res) {
3247             TLOGE(WmsLogTag::DMS, "convert screenId to rsScreenId failed");
3248             continue;
3249         }
3250         auto screenSession = GetScreenSession(screenId);
3251         if (!screenSession) {
3252             TLOGE(WmsLogTag::DMS, "screen session is nullptr");
3253             continue;
3254         }
3255         Rosen::RSDisplayNodeConfig rsConfig;
3256         rsConfig.screenId = rsScreenId;
3257         screenSession->CreateDisplayNode(rsConfig);
3258         screenSession->SetDisplayNodeScreenId(rsScreenId);
3259         // notify scb to build Screen widget
3260         OnVirtualScreenChange(screenId, ScreenEvent::CONNECTED);
3261     }
3262     auto transactionProxy = RSTransactionProxy::GetInstance();
3263     if (transactionProxy != nullptr) {
3264         TLOGD(WmsLogTag::DMS, "flush data");
3265         transactionProxy->FlushImplicitTransaction();
3266     }
3267     TLOGI(WmsLogTag::DMS, "end");
3268     return DMError::DM_OK;
3269 }
3270 
MakeExpand(std::vector<ScreenId> screenId,std::vector<Point> startPoint,ScreenId & screenGroupId)3271 DMError ScreenSessionManager::MakeExpand(std::vector<ScreenId> screenId,
3272                                          std::vector<Point> startPoint,
3273                                          ScreenId& screenGroupId)
3274 {
3275     TLOGI(WmsLogTag::DMS, "MakeExpand enter!");
3276     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3277         TLOGE(WmsLogTag::DMS, "MakeExpand permission denied! pid: %{public}d", IPCSkeleton::GetCallingPid());
3278         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3279     }
3280     if (screenId.empty() || startPoint.empty() || screenId.size() != startPoint.size()) {
3281         TLOGE(WmsLogTag::DMS, "create expand fail, screenId size:%{public}ud,startPoint size:%{public}ud",
3282             static_cast<uint32_t>(screenId.size()), static_cast<uint32_t>(startPoint.size()));
3283         return DMError::DM_ERROR_INVALID_PARAM;
3284     }
3285     std::map<ScreenId, Point> pointsMap;
3286     uint32_t size = screenId.size();
3287     for (uint32_t i = 0; i < size; i++) {
3288         if (pointsMap.find(screenId[i]) != pointsMap.end()) {
3289             continue;
3290         }
3291         pointsMap[screenId[i]] = startPoint[i];
3292     }
3293     ScreenId defaultScreenId = GetDefaultScreenId();
3294     auto allExpandScreenIds = GetAllValidScreenIds(screenId);
3295     auto iter = std::find(allExpandScreenIds.begin(), allExpandScreenIds.end(), defaultScreenId);
3296     if (iter != allExpandScreenIds.end()) {
3297         allExpandScreenIds.erase(iter);
3298     }
3299     if (allExpandScreenIds.empty()) {
3300         TLOGE(WmsLogTag::DMS, "allExpandScreenIds is empty. make expand failed.");
3301         return DMError::DM_ERROR_NULLPTR;
3302     }
3303     std::shared_ptr<RSDisplayNode> rsDisplayNode;
3304     std::vector<Point> points;
3305     for (uint32_t i = 0; i < allExpandScreenIds.size(); i++) {
3306         rsDisplayNode = GetRSDisplayNodeByScreenId(allExpandScreenIds[i]);
3307         points.emplace_back(pointsMap[allExpandScreenIds[i]]);
3308         if (rsDisplayNode != nullptr) {
3309             rsDisplayNode->SetDisplayOffset(pointsMap[allExpandScreenIds[i]].posX_,
3310                 pointsMap[allExpandScreenIds[i]].posY_);
3311         }
3312     }
3313     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeExpand");
3314     if (!OnMakeExpand(allExpandScreenIds, points)) {
3315         return DMError::DM_ERROR_NULLPTR;
3316     }
3317     auto screen = GetScreenSession(allExpandScreenIds[0]);
3318     if (screen == nullptr || GetAbstractScreenGroup(screen->groupSmsId_) == nullptr) {
3319         return DMError::DM_ERROR_NULLPTR;
3320     }
3321     screenGroupId = screen->groupSmsId_;
3322     return DMError::DM_OK;
3323 }
3324 
OnMakeExpand(std::vector<ScreenId> screenId,std::vector<Point> startPoint)3325 bool ScreenSessionManager::OnMakeExpand(std::vector<ScreenId> screenId, std::vector<Point> startPoint)
3326 {
3327     ScreenId defaultScreenId = GetDefaultScreenId();
3328     TLOGI(WmsLogTag::DMS, "OnMakeExpand, defaultScreenId:%{public}" PRIu64"", defaultScreenId);
3329     auto defaultScreen = GetScreenSession(defaultScreenId);
3330     if (defaultScreen == nullptr) {
3331         TLOGI(WmsLogTag::DMS, "OnMakeExpand failed.");
3332         return false;
3333     }
3334     auto group = GetAbstractScreenGroup(defaultScreen->groupSmsId_);
3335     if (group == nullptr) {
3336         group = AddToGroupLocked(defaultScreen);
3337         if (group == nullptr) {
3338             TLOGE(WmsLogTag::DMS, "group is nullptr");
3339             return false;
3340         }
3341         NotifyScreenGroupChanged(defaultScreen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
3342     }
3343     bool filterExpandScreen = group->combination_ == ScreenCombination::SCREEN_EXPAND;
3344     ChangeScreenGroup(group, screenId, startPoint, filterExpandScreen, ScreenCombination::SCREEN_EXPAND);
3345     TLOGI(WmsLogTag::DMS, "OnMakeExpand success");
3346     return true;
3347 }
3348 
StopExpand(const std::vector<ScreenId> & expandScreenIds)3349 DMError ScreenSessionManager::StopExpand(const std::vector<ScreenId>& expandScreenIds)
3350 {
3351     if (!SessionPermission::IsSystemCalling()) {
3352         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
3353             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3354         return DMError::DM_ERROR_NOT_SYSTEM_APP;
3355     }
3356     auto allExpandScreenIds = GetAllValidScreenIds(expandScreenIds);
3357     if (allExpandScreenIds.empty()) {
3358         TLOGI(WmsLogTag::DMS, "StopExpand done. screens' size:%{public}u",
3359             static_cast<uint32_t>(allExpandScreenIds.size()));
3360         return DMError::DM_OK;
3361     }
3362 
3363     DMError ret = StopScreens(allExpandScreenIds, ScreenCombination::SCREEN_EXPAND);
3364     if (ret != DMError::DM_OK) {
3365         TLOGE(WmsLogTag::DMS, "StopExpand stop expand failed.");
3366         return ret;
3367     }
3368 
3369     return DMError::DM_OK;
3370 }
3371 
ConvertToRsScreenId(ScreenId smsScreenId,ScreenId & rsScreenId) const3372 bool ScreenSessionManager::ScreenIdManager::ConvertToRsScreenId(ScreenId smsScreenId, ScreenId& rsScreenId) const
3373 {
3374     std::shared_lock lock(screenIdMapMutex_);
3375     auto iter = sms2RsScreenIdMap_.find(smsScreenId);
3376     if (iter == sms2RsScreenIdMap_.end()) {
3377         return false;
3378     }
3379     rsScreenId = iter->second;
3380     return true;
3381 }
3382 
ConvertToRsScreenId(ScreenId screenId) const3383 ScreenId ScreenSessionManager::ScreenIdManager::ConvertToRsScreenId(ScreenId screenId) const
3384 {
3385     ScreenId rsScreenId = SCREEN_ID_INVALID;
3386     ConvertToRsScreenId(screenId, rsScreenId);
3387     return rsScreenId;
3388 }
3389 
ConvertToSmsScreenId(ScreenId rsScreenId) const3390 ScreenId ScreenSessionManager::ScreenIdManager::ConvertToSmsScreenId(ScreenId rsScreenId) const
3391 {
3392     ScreenId smsScreenId = SCREEN_ID_INVALID;
3393     ConvertToSmsScreenId(rsScreenId, smsScreenId);
3394     return smsScreenId;
3395 }
3396 
ConvertToSmsScreenId(ScreenId rsScreenId,ScreenId & smsScreenId) const3397 bool ScreenSessionManager::ScreenIdManager::ConvertToSmsScreenId(ScreenId rsScreenId, ScreenId& smsScreenId) const
3398 {
3399     std::shared_lock lock(screenIdMapMutex_);
3400     auto iter = rs2SmsScreenIdMap_.find(rsScreenId);
3401     if (iter == rs2SmsScreenIdMap_.end()) {
3402         return false;
3403     }
3404     smsScreenId = iter->second;
3405     return true;
3406 }
3407 
CreateAndGetNewScreenId(ScreenId rsScreenId)3408 ScreenId ScreenSessionManager::ScreenIdManager::CreateAndGetNewScreenId(ScreenId rsScreenId)
3409 {
3410     std::unique_lock lock(screenIdMapMutex_);
3411     ScreenId smsScreenId = smsScreenCount_++;
3412     TLOGI(WmsLogTag::DMS, "CreateAndGetNewScreenId screenId: %{public}" PRIu64"", smsScreenId);
3413     if (sms2RsScreenIdMap_.find(smsScreenId) != sms2RsScreenIdMap_.end()) {
3414         TLOGW(WmsLogTag::DMS, "CreateAndGetNewScreenId screenId: %{public}" PRIu64" exit", smsScreenId);
3415     }
3416     sms2RsScreenIdMap_[smsScreenId] = rsScreenId;
3417     if (rsScreenId == SCREEN_ID_INVALID) {
3418         return smsScreenId;
3419     }
3420     if (rs2SmsScreenIdMap_.find(rsScreenId) != rs2SmsScreenIdMap_.end()) {
3421         TLOGW(WmsLogTag::DMS, "CreateAndGetNewScreenId rsScreenId: %{public}" PRIu64" exit", rsScreenId);
3422     }
3423     rs2SmsScreenIdMap_[rsScreenId] = smsScreenId;
3424     return smsScreenId;
3425 }
3426 
UpdateScreenId(ScreenId rsScreenId,ScreenId smsScreenId)3427 void ScreenSessionManager::ScreenIdManager::UpdateScreenId(ScreenId rsScreenId, ScreenId smsScreenId)
3428 {
3429     std::unique_lock lock(screenIdMapMutex_);
3430     rs2SmsScreenIdMap_[rsScreenId] = smsScreenId;
3431     sms2RsScreenIdMap_[smsScreenId] = rsScreenId;
3432 }
3433 
DeleteScreenId(ScreenId smsScreenId)3434 bool ScreenSessionManager::ScreenIdManager::DeleteScreenId(ScreenId smsScreenId)
3435 {
3436     std::unique_lock lock(screenIdMapMutex_);
3437     auto iter = sms2RsScreenIdMap_.find(smsScreenId);
3438     if (iter == sms2RsScreenIdMap_.end()) {
3439         return false;
3440     }
3441     ScreenId rsScreenId = iter->second;
3442     sms2RsScreenIdMap_.erase(smsScreenId);
3443     rs2SmsScreenIdMap_.erase(rsScreenId);
3444     return true;
3445 }
3446 
HasRsScreenId(ScreenId smsScreenId) const3447 bool ScreenSessionManager::ScreenIdManager::HasRsScreenId(ScreenId smsScreenId) const
3448 {
3449     std::shared_lock lock(screenIdMapMutex_);
3450     return rs2SmsScreenIdMap_.find(smsScreenId) != rs2SmsScreenIdMap_.end();
3451 }
3452 
InitVirtualScreen(ScreenId smsScreenId,ScreenId rsId,VirtualScreenOption option)3453 sptr<ScreenSession> ScreenSessionManager::InitVirtualScreen(ScreenId smsScreenId, ScreenId rsId,
3454     VirtualScreenOption option)
3455 {
3456     TLOGI(WmsLogTag::DMS, "InitVirtualScreen: Enter");
3457     ScreenSessionConfig config = {
3458         .screenId = smsScreenId,
3459         .rsId = rsId,
3460         .defaultScreenId = GetDefaultScreenId(),
3461         .name = option.name_,
3462     };
3463     sptr<ScreenSession> screenSession =
3464         new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
3465     sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
3466     if (screenSession == nullptr || info == nullptr) {
3467         TLOGI(WmsLogTag::DMS, "InitVirtualScreen: new screenSession or info failed");
3468         screenIdManager_.DeleteScreenId(smsScreenId);
3469         rsInterface_.RemoveVirtualScreen(rsId);
3470         return nullptr;
3471     }
3472     info->width_ = option.width_;
3473     info->height_ = option.height_;
3474     auto defaultScreen = GetScreenSession(GetDefaultScreenId());
3475     if (defaultScreen != nullptr && defaultScreen->GetActiveScreenMode() != nullptr) {
3476         info->refreshRate_ = defaultScreen->GetActiveScreenMode()->refreshRate_;
3477     }
3478     screenSession->modes_.emplace_back(info);
3479     screenSession->activeIdx_ = 0;
3480     screenSession->SetScreenType(ScreenType::VIRTUAL);
3481     screenSession->SetVirtualPixelRatio(option.density_);
3482     screenSession->SetDisplayBoundary(RectF(0, 0, option.width_, option.height_), 0);
3483     screenSession->RegisterScreenChangeListener(this);
3484     return screenSession;
3485 }
3486 
InitAbstractScreenModesInfo(sptr<ScreenSession> & screenSession)3487 bool ScreenSessionManager::InitAbstractScreenModesInfo(sptr<ScreenSession>& screenSession)
3488 {
3489     TLOGI(WmsLogTag::DMS, "Call rsInterface_ GetScreenSupportedModes");
3490     std::vector<RSScreenModeInfo> allModes = rsInterface_.GetScreenSupportedModes(
3491         screenIdManager_.ConvertToRsScreenId(screenSession->screenId_));
3492     if (allModes.size() == 0) {
3493         TLOGE(WmsLogTag::DMS, "allModes.size() == 0, screenId=%{public}" PRIu64"", screenSession->rsId_);
3494         return false;
3495     }
3496     for (const RSScreenModeInfo& rsScreenModeInfo : allModes) {
3497         sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
3498         if (info == nullptr) {
3499             TLOGE(WmsLogTag::DMS, "create SupportedScreenModes failed");
3500             return false;
3501         }
3502         info->id_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenModeId());
3503         info->width_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenWidth());
3504         info->height_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenHeight());
3505         info->refreshRate_ = rsScreenModeInfo.GetScreenRefreshRate();
3506         screenSession->modes_.push_back(info);
3507         TLOGI(WmsLogTag::DMS, "fill screen idx:%{public}d w/h:%{public}d/%{public}d",
3508             rsScreenModeInfo.GetScreenModeId(), info->width_, info->height_);
3509     }
3510     TLOGI(WmsLogTag::DMS, "Call rsInterface_ GetScreenActiveMode");
3511     int32_t activeModeId = rsInterface_.GetScreenActiveMode(screenSession->rsId_).GetScreenModeId();
3512     TLOGI(WmsLogTag::DMS, "fill screen activeModeId:%{public}d", activeModeId);
3513     if (static_cast<std::size_t>(activeModeId) >= allModes.size()) {
3514         TLOGE(WmsLogTag::DMS, "activeModeId exceed, screenId=%{public}" PRIu64", activeModeId:%{public}d/%{public}ud",
3515             screenSession->rsId_, activeModeId, static_cast<uint32_t>(allModes.size()));
3516         return false;
3517     }
3518     screenSession->activeIdx_ = activeModeId;
3519     return true;
3520 }
3521 
InitAndGetScreen(ScreenId rsScreenId)3522 sptr<ScreenSession> ScreenSessionManager::InitAndGetScreen(ScreenId rsScreenId)
3523 {
3524     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3525     ScreenId smsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsScreenId);
3526     RSScreenCapability screenCapability = rsInterface_.GetScreenCapability(rsScreenId);
3527     TLOGI(WmsLogTag::DMS, "Screen name is %{public}s, phyWidth is %{public}u, phyHeight is %{public}u",
3528         screenCapability.GetName().c_str(), screenCapability.GetPhyWidth(), screenCapability.GetPhyHeight());
3529     ScreenSessionConfig config = {
3530         .screenId = smsScreenId,
3531         .rsId = rsScreenId,
3532         .defaultScreenId = GetDefaultScreenId(),
3533         .name = screenCapability.GetName(),
3534     };
3535     sptr<ScreenSession> screenSession =
3536         new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_VIRTUAL);
3537     if (screenSession == nullptr) {
3538         TLOGE(WmsLogTag::DMS, "InitAndGetScreen: screenSession == nullptr.");
3539         screenIdManager_.DeleteScreenId(smsScreenId);
3540         return nullptr;
3541     }
3542     if (!InitAbstractScreenModesInfo(screenSession)) {
3543         screenIdManager_.DeleteScreenId(smsScreenId);
3544         TLOGE(WmsLogTag::DMS, "InitAndGetScreen: InitAndGetScreen failed.");
3545         return nullptr;
3546     }
3547     TLOGI(WmsLogTag::DMS, "InitAndGetScreen: screenSessionMap_ add screenId=%{public}" PRIu64"", smsScreenId);
3548     screenSessionMap_.insert(std::make_pair(smsScreenId, screenSession));
3549     return screenSession;
3550 }
3551 
AddToGroupLocked(sptr<ScreenSession> newScreen,bool isUnique)3552 sptr<ScreenSessionGroup> ScreenSessionManager::AddToGroupLocked(sptr<ScreenSession> newScreen, bool isUnique)
3553 {
3554     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3555     sptr<ScreenSessionGroup> res;
3556     if (smsScreenGroupMap_.empty()) {
3557         TLOGI(WmsLogTag::DMS, "connect the first screen");
3558         res = AddAsFirstScreenLocked(newScreen, isUnique);
3559     } else {
3560         res = AddAsSuccedentScreenLocked(newScreen);
3561     }
3562     return res;
3563 }
3564 
AddAsFirstScreenLocked(sptr<ScreenSession> newScreen,bool isUnique)3565 sptr<ScreenSessionGroup> ScreenSessionManager::AddAsFirstScreenLocked(sptr<ScreenSession> newScreen, bool isUnique)
3566 {
3567     ScreenId smsGroupScreenId(1);
3568     std::ostringstream buffer;
3569     buffer << "ScreenGroup_" << smsGroupScreenId;
3570     std::string name = buffer.str();
3571     // default ScreenCombination is mirror
3572     isExpandCombination_ = system::GetParameter("persist.display.expand.enabled", "0") == "1";
3573     sptr<ScreenSessionGroup> screenGroup;
3574     if (isExpandCombination_) {
3575         screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
3576             SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_EXPAND);
3577         newScreen->SetScreenCombination(ScreenCombination::SCREEN_EXPAND);
3578     } else if (isUnique) {
3579         screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
3580             SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_UNIQUE);
3581         newScreen->SetScreenCombination(ScreenCombination::SCREEN_UNIQUE);
3582     } else {
3583         screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
3584             SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_MIRROR);
3585         newScreen->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
3586     }
3587     if (screenGroup == nullptr) {
3588         TLOGE(WmsLogTag::DMS, "new ScreenSessionGroup failed");
3589         screenIdManager_.DeleteScreenId(smsGroupScreenId);
3590         return nullptr;
3591     }
3592     screenGroup->groupSmsId_ = 1;
3593     Point point;
3594     if (!screenGroup->AddChild(newScreen, point, GetScreenSession(GetDefaultScreenId()))) {
3595         TLOGE(WmsLogTag::DMS, "fail to add screen to group. screen=%{public}" PRIu64"", newScreen->screenId_);
3596         screenIdManager_.DeleteScreenId(smsGroupScreenId);
3597         return nullptr;
3598     }
3599     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3600     auto iter = smsScreenGroupMap_.find(smsGroupScreenId);
3601     if (iter != smsScreenGroupMap_.end()) {
3602         TLOGE(WmsLogTag::DMS, "group screen existed. id=%{public}" PRIu64"", smsGroupScreenId);
3603         smsScreenGroupMap_.erase(iter);
3604     }
3605     smsScreenGroupMap_.insert(std::make_pair(smsGroupScreenId, screenGroup));
3606     screenGroup->mirrorScreenId_ = newScreen->screenId_;
3607     TLOGI(WmsLogTag::DMS, "connect new group screen, screenId: %{public}" PRIu64", screenGroupId: %{public}" PRIu64", "
3608         "combination:%{public}u", newScreen->screenId_, smsGroupScreenId,
3609         newScreen->GetScreenProperty().GetScreenType());
3610     return screenGroup;
3611 }
3612 
AddAsSuccedentScreenLocked(sptr<ScreenSession> newScreen)3613 sptr<ScreenSessionGroup> ScreenSessionManager::AddAsSuccedentScreenLocked(sptr<ScreenSession> newScreen)
3614 {
3615     ScreenId defaultScreenId = GetDefaultScreenId();
3616     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3617     auto iter = screenSessionMap_.find(defaultScreenId);
3618     if (iter == screenSessionMap_.end()) {
3619         TLOGE(WmsLogTag::DMS, "defaultScreenId:%{public}" PRIu64" is not in screenSessionMap_.",
3620             defaultScreenId);
3621         return nullptr;
3622     }
3623     auto screen = iter->second;
3624     auto screenGroupIter = smsScreenGroupMap_.find(screen->groupSmsId_);
3625     if (screenGroupIter == smsScreenGroupMap_.end()) {
3626         TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64" is not in smsScreenGroupMap_.",
3627             screen->groupSmsId_);
3628         return nullptr;
3629     }
3630     auto screenGroup = screenGroupIter->second;
3631     Point point;
3632     if (screenGroup->combination_ == ScreenCombination::SCREEN_EXPAND) {
3633         point = {screen->GetActiveScreenMode()->width_, 0};
3634     }
3635     screenGroup->AddChild(newScreen, point, screen);
3636     return screenGroup;
3637 }
3638 
RemoveFromGroupLocked(sptr<ScreenSession> screen)3639 sptr<ScreenSessionGroup> ScreenSessionManager::RemoveFromGroupLocked(sptr<ScreenSession> screen)
3640 {
3641     TLOGI(WmsLogTag::DMS, "RemoveFromGroupLocked.");
3642     auto groupSmsId = screen->groupSmsId_;
3643     sptr<ScreenSessionGroup> screenGroup = GetAbstractScreenGroup(groupSmsId);
3644     if (!screenGroup) {
3645         TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64"is not in smsScreenGroupMap_.",
3646             groupSmsId);
3647         return nullptr;
3648     }
3649     if (!RemoveChildFromGroup(screen, screenGroup)) {
3650         return nullptr;
3651     }
3652     return screenGroup;
3653 }
3654 
RemoveChildFromGroup(sptr<ScreenSession> screen,sptr<ScreenSessionGroup> screenGroup)3655 bool ScreenSessionManager::RemoveChildFromGroup(sptr<ScreenSession> screen, sptr<ScreenSessionGroup> screenGroup)
3656 {
3657     bool res = screenGroup->RemoveChild(screen);
3658     auto transactionProxy = RSTransactionProxy::GetInstance();
3659     if (transactionProxy != nullptr) {
3660         transactionProxy->FlushImplicitTransaction();
3661         TLOGI(WmsLogTag::DMS, "remove child and call flush.");
3662     }
3663     if (!res) {
3664         TLOGE(WmsLogTag::DMS, "remove screen:%{public}" PRIu64" failed from screenGroup:%{public}" PRIu64".",
3665             screen->screenId_, screen->groupSmsId_);
3666         return false;
3667     }
3668     if (screenGroup->GetChildCount() == 0) {
3669         // Group removed, need to do something.
3670         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3671         smsScreenGroupMap_.erase(screenGroup->screenId_);
3672         screenSessionMap_.erase(screenGroup->screenId_);
3673         TLOGE(WmsLogTag::DMS, "screenSessionMap_ remove screen:%{public}" PRIu64, screenGroup->screenId_);
3674     }
3675     return true;
3676 }
3677 
SetMirror(ScreenId screenId,std::vector<ScreenId> screens)3678 DMError ScreenSessionManager::SetMirror(ScreenId screenId, std::vector<ScreenId> screens)
3679 {
3680     TLOGI(WmsLogTag::DMS, "SetMirror, screenId:%{public}" PRIu64"", screenId);
3681     sptr<ScreenSession> screen = GetScreenSession(screenId);
3682     if (screen == nullptr || screen->GetScreenProperty().GetScreenType() != ScreenType::REAL) {
3683         TLOGE(WmsLogTag::DMS, "SetMirror screen is nullptr, or screenType is not real.");
3684         return DMError::DM_ERROR_NULLPTR;
3685     }
3686     screen->groupSmsId_ = 1;
3687     auto group = GetAbstractScreenGroup(screen->groupSmsId_);
3688     if (group == nullptr) {
3689         group = AddToGroupLocked(screen);
3690         if (group == nullptr) {
3691             TLOGE(WmsLogTag::DMS, "SetMirror group is nullptr");
3692             return DMError::DM_ERROR_NULLPTR;
3693         }
3694         NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
3695     }
3696     Point point;
3697     std::vector<Point> startPoints;
3698     startPoints.insert(startPoints.begin(), screens.size(), point);
3699     bool filterMirroredScreen =
3700         group->combination_ == ScreenCombination::SCREEN_MIRROR && group->mirrorScreenId_ == screen->screenId_;
3701     group->mirrorScreenId_ = screen->screenId_;
3702     ChangeScreenGroup(group, screens, startPoints, filterMirroredScreen, ScreenCombination::SCREEN_MIRROR);
3703     TLOGI(WmsLogTag::DMS, "SetMirror success");
3704     return DMError::DM_OK;
3705 }
3706 
GetAbstractScreenGroup(ScreenId smsScreenId)3707 sptr<ScreenSessionGroup> ScreenSessionManager::GetAbstractScreenGroup(ScreenId smsScreenId)
3708 {
3709     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3710     auto iter = smsScreenGroupMap_.find(smsScreenId);
3711     if (iter == smsScreenGroupMap_.end()) {
3712         TLOGE(WmsLogTag::DMS, "did not find screen:%{public}" PRIu64"", smsScreenId);
3713         return nullptr;
3714     }
3715     return iter->second;
3716 }
3717 
CheckScreenInScreenGroup(sptr<ScreenSession> screen) const3718 bool ScreenSessionManager::CheckScreenInScreenGroup(sptr<ScreenSession> screen) const
3719 {
3720     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3721     auto groupSmsId = screen->groupSmsId_;
3722     auto iter = smsScreenGroupMap_.find(groupSmsId);
3723     if (iter == smsScreenGroupMap_.end()) {
3724         TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64"is not in smsScreenGroupMap_.", groupSmsId);
3725         return false;
3726     }
3727     sptr<ScreenSessionGroup> screenGroup = iter->second;
3728     return screenGroup->HasChild(screen->screenId_);
3729 }
3730 
ChangeScreenGroup(sptr<ScreenSessionGroup> group,const std::vector<ScreenId> & screens,const std::vector<Point> & startPoints,bool filterScreen,ScreenCombination combination)3731 void ScreenSessionManager::ChangeScreenGroup(sptr<ScreenSessionGroup> group, const std::vector<ScreenId>& screens,
3732     const std::vector<Point>& startPoints, bool filterScreen, ScreenCombination combination)
3733 {
3734     std::map<ScreenId, bool> removeChildResMap;
3735     std::vector<ScreenId> addScreens;
3736     std::vector<Point> addChildPos;
3737     for (uint64_t i = 0; i != screens.size(); i++) {
3738         ScreenId screenId = screens[i];
3739         TLOGI(WmsLogTag::DMS, "ChangeScreenGroup ScreenId: %{public}" PRIu64"", screenId);
3740         auto screen = GetScreenSession(screenId);
3741         if (screen == nullptr) {
3742             TLOGE(WmsLogTag::DMS, "ChangeScreenGroup screen:%{public}" PRIu64" is nullptr", screenId);
3743             continue;
3744         }
3745         TLOGI(WmsLogTag::DMS, "ChangeScreenGroup Screen->groupSmsId_: %{public}" PRIu64"", screen->groupSmsId_);
3746         screen->groupSmsId_ = 1;
3747         if (filterScreen && screen->groupSmsId_ == group->screenId_ && group->HasChild(screen->screenId_)) {
3748             continue;
3749         }
3750         if (CheckScreenInScreenGroup(screen)) {
3751             NotifyDisplayDestroy(screenId);
3752         }
3753         auto originGroup = RemoveFromGroupLocked(screen);
3754         addChildPos.emplace_back(startPoints[i]);
3755         removeChildResMap[screenId] = originGroup != nullptr;
3756         addScreens.emplace_back(screenId);
3757     }
3758     group->combination_ = combination;
3759     AddScreenToGroup(group, addScreens, addChildPos, removeChildResMap);
3760 }
3761 
AddScreenToGroup(sptr<ScreenSessionGroup> group,const std::vector<ScreenId> & addScreens,const std::vector<Point> & addChildPos,std::map<ScreenId,bool> & removeChildResMap)3762 void ScreenSessionManager::AddScreenToGroup(sptr<ScreenSessionGroup> group,
3763     const std::vector<ScreenId>& addScreens, const std::vector<Point>& addChildPos,
3764     std::map<ScreenId, bool>& removeChildResMap)
3765 {
3766     std::vector<sptr<ScreenInfo>> addToGroup;
3767     std::vector<sptr<ScreenInfo>> removeFromGroup;
3768     std::vector<sptr<ScreenInfo>> changeGroup;
3769     for (uint64_t i = 0; i != addScreens.size(); i++) {
3770         ScreenId screenId = addScreens[i];
3771         sptr<ScreenSession> screen = GetScreenSession(screenId);
3772         if (screen == nullptr) {
3773             continue;
3774         }
3775         Point expandPoint = addChildPos[i];
3776         TLOGI(WmsLogTag::DMS, "AddScreenToGroup screenId: %{public}" PRIu64", Point: %{public}d, %{public}d",
3777             screen->screenId_, expandPoint.posX_, expandPoint.posY_);
3778         bool addChildRes = group->AddChild(screen, expandPoint, GetScreenSession(GetDefaultScreenId()));
3779         if (removeChildResMap[screenId] && addChildRes) {
3780             changeGroup.emplace_back(screen->ConvertToScreenInfo());
3781             TLOGD(WmsLogTag::DMS, "changeGroup");
3782         } else if (removeChildResMap[screenId]) {
3783             TLOGD(WmsLogTag::DMS, "removeChild");
3784             removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
3785         } else if (addChildRes) {
3786             TLOGD(WmsLogTag::DMS, "AddChild");
3787             addToGroup.emplace_back(screen->ConvertToScreenInfo());
3788         } else {
3789             TLOGD(WmsLogTag::DMS, "default, AddChild failed");
3790         }
3791         NotifyDisplayCreate(screen->ConvertToDisplayInfo());
3792     }
3793 
3794     NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
3795     NotifyScreenGroupChanged(changeGroup, ScreenGroupChangeEvent::CHANGE_GROUP);
3796     NotifyScreenGroupChanged(addToGroup, ScreenGroupChangeEvent::ADD_TO_GROUP);
3797 }
3798 
RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)3799 void ScreenSessionManager::RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)
3800 {
3801     TLOGI(WmsLogTag::DMS, "RemoveVirtualScreenFromGroup enter!");
3802     if (!SessionPermission::IsSystemCalling()) {
3803         TLOGE(WmsLogTag::DMS, "permission denied calling clientName: %{public}s, calling pid: %{public}d",
3804             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3805         return;
3806     }
3807     if (screens.empty()) {
3808         return;
3809     }
3810     std::vector<sptr<ScreenInfo>> removeFromGroup;
3811     for (ScreenId screenId : screens) {
3812         auto screen = GetScreenSession(screenId);
3813         if (screen == nullptr || screen->GetScreenProperty().GetScreenType() != ScreenType::VIRTUAL) {
3814             continue;
3815         }
3816         auto originGroup = GetAbstractScreenGroup(screen->groupSmsId_);
3817         if (originGroup == nullptr) {
3818             continue;
3819         }
3820         if (!originGroup->HasChild(screenId)) {
3821             continue;
3822         }
3823         RemoveFromGroupLocked(screen);
3824         removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
3825     }
3826     NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
3827 }
3828 
GetRSDisplayNodeByScreenId(ScreenId smsScreenId) const3829 const std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetRSDisplayNodeByScreenId(ScreenId smsScreenId) const
3830 {
3831     static std::shared_ptr<RSDisplayNode> notFound = nullptr;
3832     sptr<ScreenSession> screen = GetScreenSession(smsScreenId);
3833     if (screen == nullptr) {
3834         TLOGE(WmsLogTag::DMS, "GetRSDisplayNodeByScreenId screen == nullptr!");
3835         return notFound;
3836     }
3837     if (screen->GetDisplayNode() == nullptr) {
3838         TLOGE(WmsLogTag::DMS, "GetRSDisplayNodeByScreenId displayNode_ == nullptr!");
3839         return notFound;
3840     }
3841     TLOGI(WmsLogTag::DMS, "GetRSDisplayNodeByScreenId: screen: %{public}" PRIu64", nodeId: %{public}" PRIu64" ",
3842         screen->screenId_, screen->GetDisplayNode()->GetId());
3843     return screen->GetDisplayNode();
3844 }
3845 
GetScreenSnapshot(DisplayId displayId,bool isUseDma)3846 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetScreenSnapshot(DisplayId displayId, bool isUseDma)
3847 {
3848     ScreenId screenId = SCREEN_ID_INVALID;
3849     std::shared_ptr<RSDisplayNode> displayNode = nullptr;
3850     {
3851         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3852         for (auto sessionIt : screenSessionMap_) {
3853             auto screenSession = sessionIt.second;
3854             if (screenSession == nullptr) {
3855                 TLOGE(WmsLogTag::DMS, "GetScreenSnapshot screenSession is nullptr!");
3856                 continue;
3857             }
3858             sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
3859             if (displayInfo == nullptr) {
3860                 TLOGE(WmsLogTag::DMS, "GetScreenSnapshot displayInfo is nullptr!");
3861                 continue;
3862             }
3863             TLOGI(WmsLogTag::DMS, "GetScreenSnapshot: displayId %{public}" PRIu64"", displayInfo->GetDisplayId());
3864             if (displayId == displayInfo->GetDisplayId()) {
3865                 displayNode = screenSession->GetDisplayNode();
3866                 screenId = sessionIt.first;
3867                 break;
3868             }
3869         }
3870     }
3871     if (screenId == SCREEN_ID_INVALID || displayNode == nullptr) {
3872         TLOGE(WmsLogTag::DMS, "screenId is invalid or displayNode is null!");
3873         return nullptr;
3874     }
3875 
3876     std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
3877     RSSurfaceCaptureConfig config;
3878     config.useDma = isUseDma;
3879     TLOGW(WmsLogTag::DMS, "take surface capture with dma=%{public}d", isUseDma);
3880     bool ret = rsInterface_.TakeSurfaceCapture(displayNode, callback, config);
3881     if (!ret) {
3882         TLOGE(WmsLogTag::DMS, "GetScreenSnapshot TakeSurfaceCapture failed");
3883         return nullptr;
3884     }
3885     std::shared_ptr<Media::PixelMap> screenshot = callback->GetResult(2000); // wait for <= 2000ms
3886     if (screenshot == nullptr) {
3887         TLOGE(WmsLogTag::DMS, "Failed to get pixelmap from RS, return nullptr!");
3888     } else {
3889         TLOGI(WmsLogTag::DMS, "Sucess to get pixelmap from RS!");
3890     }
3891 
3892     // notify dm listener
3893     sptr<ScreenshotInfo> snapshotInfo = new ScreenshotInfo();
3894     snapshotInfo->SetTrigger(SysCapUtil::GetClientName());
3895     snapshotInfo->SetDisplayId(displayId);
3896     OnScreenshot(snapshotInfo);
3897 
3898     return screenshot;
3899 }
3900 
GetDisplaySnapshot(DisplayId displayId,DmErrorCode * errorCode,bool isUseDma)3901 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetDisplaySnapshot(DisplayId displayId,
3902     DmErrorCode* errorCode, bool isUseDma)
3903 {
3904     TLOGD(WmsLogTag::DMS, "ENTER!");
3905 
3906     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall() && errorCode) {
3907         *errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
3908         return nullptr;
3909     }
3910 
3911     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
3912         TLOGI(WmsLogTag::DMS, "GetDisplaySnapshot was disabled by edm!");
3913         return nullptr;
3914     }
3915     if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
3916         SessionPermission::IsShellCall()) {
3917         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplaySnapshot(%" PRIu64")", displayId);
3918         auto res = GetScreenSnapshot(displayId, isUseDma);
3919         if (res != nullptr) {
3920             NotifyScreenshot(displayId);
3921             if (SessionPermission::IsBetaVersion()) {
3922                 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
3923             }
3924         }
3925         isScreenShot_ = true;
3926         NotifyCaptureStatusChanged();
3927         return res;
3928     } else if (errorCode) {
3929         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
3930     }
3931     return nullptr;
3932 }
3933 
GetDisplaySnapshotWithOption(const CaptureOption & option,DmErrorCode * errorCode)3934 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetDisplaySnapshotWithOption(const CaptureOption& option,
3935     DmErrorCode* errorCode)
3936 {
3937     TLOGD(WmsLogTag::DMS, "enter!");
3938     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall() && errorCode) {
3939         *errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
3940         return nullptr;
3941     }
3942     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
3943         TLOGI(WmsLogTag::DMS, "snapshot was disabled by edm!");
3944         return nullptr;
3945     }
3946     if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
3947         SessionPermission::IsShellCall()) {
3948         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplaySnapshot(%" PRIu64")", option.displayId_);
3949         auto res = GetScreenSnapshot(option.displayId_, true);
3950         if (res != nullptr) {
3951             if (SessionPermission::IsBetaVersion()) {
3952                 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
3953             }
3954             TLOGI(WmsLogTag::DMS, "isNeedNotify_:%{public}d", option.isNeedNotify_);
3955             if (option.isNeedNotify_) {
3956                 isScreenShot_ = true;
3957                 NotifyScreenshot(option.displayId_);
3958                 NotifyCaptureStatusChanged();
3959             }
3960         }
3961         return res;
3962     } else if (errorCode) {
3963         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
3964     }
3965     return nullptr;
3966 }
3967 
GetSnapshotByPicker(Media::Rect & rect,DmErrorCode * errorCode)3968 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetSnapshotByPicker(Media::Rect &rect, DmErrorCode* errorCode)
3969 {
3970     TLOGD(WmsLogTag::DMS, "ENTER!");
3971     *errorCode = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
3972     std::lock_guard<std::mutex> lock(snapBypickerMutex_);
3973 
3974     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
3975         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
3976         TLOGI(WmsLogTag::DMS, "snapshot was disabled by edm!");
3977         return nullptr;
3978     }
3979     ScreenId screenId = SCREEN_ID_INVALID;
3980     // get snapshot area frome Screenshot extension
3981     if (!GetSnapshotArea(rect, errorCode, screenId)) {
3982         return nullptr;
3983     }
3984     auto screenSession = GetScreenSession(screenId);
3985     if (screenSession == nullptr) {
3986         TLOGE(WmsLogTag::DMS, "can not get screen session");
3987         return nullptr;
3988     }
3989     sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
3990     if (displayInfo == nullptr) {
3991         TLOGE(WmsLogTag::DMS, "can not get default display");
3992         return nullptr;
3993     }
3994     DisplayId displayId = displayInfo->GetDisplayId();
3995     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSnapshotByPicker(%" PRIu64")", displayId);
3996     auto pixelMap = GetScreenSnapshot(displayId, false);
3997     if (pixelMap != nullptr && SessionPermission::IsBetaVersion()) {
3998         CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
3999     }
4000     isScreenShot_ = true;
4001     NotifyCaptureStatusChanged();
4002     *errorCode = DmErrorCode::DM_OK;
4003     return pixelMap;
4004 }
4005 
GetSnapshotArea(Media::Rect & rect,DmErrorCode * errorCode,ScreenId & screenId)4006 bool ScreenSessionManager::GetSnapshotArea(Media::Rect &rect, DmErrorCode* errorCode, ScreenId &screenId)
4007 {
4008     ConfigureScreenSnapshotParams();
4009     if (ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerConnectExtension()) {
4010         int32_t ret = ScreenSnapshotPickerConnection::GetInstance().GetScreenSnapshotInfo(rect, screenId);
4011         if (ret != 0) {
4012             TLOGE(WmsLogTag::DMS, "GetScreenSnapshotInfo failed");
4013             ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerDisconnectExtension();
4014             if (ret == RES_FAILURE_FOR_PRIVACY_WINDOW) {
4015                 *errorCode = DmErrorCode::DM_ERROR_INVALID_CALLING;
4016             } else {
4017                 *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
4018             }
4019             return false;
4020         }
4021         ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerDisconnectExtension();
4022     } else {
4023         *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
4024         TLOGE(WmsLogTag::DMS, "SnapshotPickerConnectExtension failed");
4025         return false;
4026     }
4027     return true;
4028 }
4029 
OnRemoteDied(const sptr<IRemoteObject> & agent)4030 bool ScreenSessionManager::OnRemoteDied(const sptr<IRemoteObject>& agent)
4031 {
4032     if (agent == nullptr) {
4033         return false;
4034     }
4035     auto agentIter = screenAgentMap_.find(agent);
4036     if (agentIter != screenAgentMap_.end()) {
4037         while (screenAgentMap_[agent].size() > 0) {
4038             auto diedId = screenAgentMap_[agent][0];
4039             TLOGI(WmsLogTag::DMS, "destroy screenId in OnRemoteDied: %{public}" PRIu64"", diedId);
4040             DMError res = DestroyVirtualScreen(diedId);
4041             if (res != DMError::DM_OK) {
4042                 TLOGE(WmsLogTag::DMS, "destroy failed in OnRemoteDied: %{public}" PRIu64"", diedId);
4043             }
4044         }
4045         screenAgentMap_.erase(agent);
4046     }
4047     return true;
4048 }
4049 
GetAllValidScreenIds(const std::vector<ScreenId> & screenIds) const4050 std::vector<ScreenId> ScreenSessionManager::GetAllValidScreenIds(const std::vector<ScreenId>& screenIds) const
4051 {
4052     std::vector<ScreenId> validScreenIds;
4053     for (ScreenId screenId : screenIds) {
4054         auto screenIdIter = std::find(validScreenIds.begin(), validScreenIds.end(), screenId);
4055         if (screenIdIter != validScreenIds.end()) {
4056             continue;
4057         }
4058         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4059         auto iter = screenSessionMap_.find(screenId);
4060         if (iter != screenSessionMap_.end() && iter->second != nullptr &&
4061                 iter->second->GetScreenProperty().GetScreenType() != ScreenType::UNDEFINED) {
4062             validScreenIds.emplace_back(screenId);
4063         }
4064     }
4065     return validScreenIds;
4066 }
4067 
GetScreenGroupInfoById(ScreenId screenId)4068 sptr<ScreenGroupInfo> ScreenSessionManager::GetScreenGroupInfoById(ScreenId screenId)
4069 {
4070     if (!SessionPermission::IsSystemCalling()) {
4071         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4072             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4073         return nullptr;
4074     }
4075     auto screenSessionGroup = GetAbstractScreenGroup(screenId);
4076     if (screenSessionGroup == nullptr) {
4077         TLOGE(WmsLogTag::DMS, "GetScreenGroupInfoById cannot find screenGroupInfo: %{public}" PRIu64"", screenId);
4078         return nullptr;
4079     }
4080     return screenSessionGroup->ConvertToScreenGroupInfo();
4081 }
4082 
NotifyScreenConnected(sptr<ScreenInfo> screenInfo)4083 void ScreenSessionManager::NotifyScreenConnected(sptr<ScreenInfo> screenInfo)
4084 {
4085     if (screenInfo == nullptr) {
4086         TLOGE(WmsLogTag::DMS, "NotifyScreenConnected error, screenInfo is nullptr.");
4087         return;
4088     }
4089     auto task = [=] {
4090         TLOGI(WmsLogTag::DMS, "NotifyScreenConnected, screenId:%{public}" PRIu64"", screenInfo->GetScreenId());
4091         OnScreenConnect(screenInfo);
4092     };
4093     taskScheduler_->PostAsyncTask(task, "NotifyScreenConnected");
4094 }
4095 
NotifyScreenDisconnected(ScreenId screenId)4096 void ScreenSessionManager::NotifyScreenDisconnected(ScreenId screenId)
4097 {
4098     auto task = [=] {
4099         TLOGI(WmsLogTag::DMS, "NotifyScreenDisconnected, screenId:%{public}" PRIu64"", screenId);
4100         OnScreenDisconnect(screenId);
4101     };
4102     taskScheduler_->PostAsyncTask(task, "NotifyScreenDisconnected");
4103 }
4104 
NotifyDisplayCreate(sptr<DisplayInfo> displayInfo)4105 void ScreenSessionManager::NotifyDisplayCreate(sptr<DisplayInfo> displayInfo)
4106 {
4107     if (displayInfo == nullptr) {
4108         return;
4109     }
4110     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
4111     if (agents.empty()) {
4112         return;
4113     }
4114     TLOGI(WmsLogTag::DMS, "NotifyDisplayCreate");
4115     for (auto& agent : agents) {
4116         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
4117         if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
4118             agent->OnDisplayCreate(displayInfo);
4119         }
4120     }
4121 }
4122 
NotifyDisplayDestroy(DisplayId displayId)4123 void ScreenSessionManager::NotifyDisplayDestroy(DisplayId displayId)
4124 {
4125     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
4126     if (agents.empty()) {
4127         return;
4128     }
4129     TLOGI(WmsLogTag::DMS, "NotifyDisplayDestroy");
4130     for (auto& agent : agents) {
4131         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
4132         if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
4133             agent->OnDisplayDestroy(displayId);
4134         }
4135     }
4136 }
4137 
NotifyScreenGroupChanged(const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent event)4138 void ScreenSessionManager::NotifyScreenGroupChanged(
4139     const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent event)
4140 {
4141     if (screenInfo == nullptr) {
4142         TLOGE(WmsLogTag::DMS, "screenInfo is nullptr.");
4143         return;
4144     }
4145     std::string trigger = SysCapUtil::GetClientName();
4146     auto task = [=] {
4147         TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", trigger:[%{public}s]",
4148             screenInfo->GetScreenId(), trigger.c_str());
4149         OnScreenGroupChange(trigger, screenInfo, event);
4150     };
4151     taskScheduler_->PostAsyncTask(task, "NotifyScreenGroupChanged:PID");
4152 }
4153 
NotifyScreenGroupChanged(const std::vector<sptr<ScreenInfo>> & screenInfo,ScreenGroupChangeEvent event)4154 void ScreenSessionManager::NotifyScreenGroupChanged(
4155     const std::vector<sptr<ScreenInfo>>& screenInfo, ScreenGroupChangeEvent event)
4156 {
4157     if (screenInfo.empty()) {
4158         return;
4159     }
4160     std::string trigger = SysCapUtil::GetClientName();
4161     auto task = [=] {
4162         TLOGI(WmsLogTag::DMS, "trigger:[%{public}s]", trigger.c_str());
4163         OnScreenGroupChange(trigger, screenInfo, event);
4164     };
4165     taskScheduler_->PostAsyncTask(task, "NotifyScreenGroupChanged");
4166 }
4167 
NotifyPrivateSessionStateChanged(bool hasPrivate)4168 void ScreenSessionManager::NotifyPrivateSessionStateChanged(bool hasPrivate)
4169 {
4170     if (hasPrivate == screenPrivacyStates) {
4171         TLOGD(WmsLogTag::DMS, "screen session state is not changed, return");
4172         return;
4173     }
4174     TLOGI(WmsLogTag::DMS, "PrivateSession status : %{public}u", hasPrivate);
4175     screenPrivacyStates = hasPrivate;
4176     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::PRIVATE_WINDOW_LISTENER);
4177     if (agents.empty()) {
4178         return;
4179     }
4180     for (auto& agent : agents) {
4181         agent->NotifyPrivateWindowStateChanged(hasPrivate);
4182     }
4183 }
4184 
SetScreenPrivacyState(bool hasPrivate)4185 void ScreenSessionManager::SetScreenPrivacyState(bool hasPrivate)
4186 {
4187     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4188         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4189             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4190         return;
4191     }
4192     TLOGI(WmsLogTag::DMS, "SetScreenPrivacyState enter, hasPrivate: %{public}d", hasPrivate);
4193     ScreenId id = GetDefaultScreenId();
4194     auto screenSession = GetScreenSession(id);
4195     if (screenSession == nullptr) {
4196         TLOGE(WmsLogTag::DMS, "can not get default screen now");
4197         return;
4198     }
4199     screenSession->SetPrivateSessionForeground(hasPrivate);
4200     NotifyPrivateSessionStateChanged(hasPrivate);
4201 }
4202 
SetPrivacyStateByDisplayId(DisplayId id,bool hasPrivate)4203 void ScreenSessionManager::SetPrivacyStateByDisplayId(DisplayId id, bool hasPrivate)
4204 {
4205     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4206         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4207             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4208         return;
4209     }
4210     TLOGI(WmsLogTag::DMS, "SetPrivacyStateByDisplayId enter, hasPrivate: %{public}d", hasPrivate);
4211     std::vector<ScreenId> screenIds = GetAllScreenIds();
4212     auto iter = std::find(screenIds.begin(), screenIds.end(), id);
4213     if (iter == screenIds.end()) {
4214         TLOGE(WmsLogTag::DMS, "SetPrivacyStateByDisplayId invalid displayId");
4215         return;
4216     }
4217     auto screenSession = GetScreenSession(id);
4218     if (screenSession == nullptr) {
4219         TLOGE(WmsLogTag::DMS, "can not get id: %{public}" PRIu64" screen now", id);
4220         return;
4221     }
4222     screenSession->SetPrivateSessionForeground(hasPrivate);
4223     NotifyPrivateSessionStateChanged(hasPrivate);
4224 }
4225 
SetScreenPrivacyWindowList(DisplayId id,std::vector<std::string> privacyWindowList)4226 void ScreenSessionManager::SetScreenPrivacyWindowList(DisplayId id, std::vector<std::string> privacyWindowList)
4227 {
4228     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4229         TLOGE(WmsLogTag::DMS, "Permmission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4230             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4231         return;
4232     }
4233     TLOGI(WmsLogTag::DMS, "SetScreenPrivacyWindowList enter");
4234     std::vector<ScreenId> screenIds = GetAllScreenIds();
4235     auto iter = std::find(screenIds.begin(), screenIds.end(), id);
4236     if (iter == screenIds.end()) {
4237         TLOGE(WmsLogTag::DMS, "SetScreenPrivacyWindowList invalid displayId");
4238         return;
4239     }
4240     auto screenSession = GetScreenSession(id);
4241     if (screenSession == nullptr) {
4242         TLOGE(WmsLogTag::DMS, "can not get id: %{public}" PRIu64" screen now", id);
4243         return;
4244     }
4245     NotifyPrivateWindowListChanged(id, privacyWindowList);
4246 }
4247 
NotifyPrivateWindowListChanged(DisplayId id,std::vector<std::string> privacyWindowList)4248 void ScreenSessionManager::NotifyPrivateWindowListChanged(DisplayId id, std::vector<std::string> privacyWindowList)
4249 {
4250     TLOGI(WmsLogTag::DMS, "Notify displayid: %{public}" PRIu64" PrivateWindowListChanged", id);
4251     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::PRIVATE_WINDOW_LIST_LISTENER);
4252     if (agents.empty()) {
4253         return;
4254     }
4255     for (auto& agent : agents) {
4256         agent->NotifyPrivateStateWindowListChanged(id, privacyWindowList);
4257     }
4258 }
4259 
HasPrivateWindow(DisplayId id,bool & hasPrivateWindow)4260 DMError ScreenSessionManager::HasPrivateWindow(DisplayId id, bool& hasPrivateWindow)
4261 {
4262     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4263         TLOGE(WmsLogTag::DMS, "Permmision Denied! calling clientName: %{public}s, calling pid: %{public}d",
4264             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4265         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4266     }
4267     std::vector<ScreenId> screenIds = GetAllScreenIds();
4268     auto iter = std::find(screenIds.begin(), screenIds.end(), id);
4269     if (iter == screenIds.end()) {
4270         TLOGE(WmsLogTag::DMS, "HasPrivateWindow invalid displayId");
4271         return DMError::DM_ERROR_INVALID_PARAM;
4272     }
4273     auto screenSession = GetScreenSession(id);
4274     if (screenSession == nullptr) {
4275         return DMError::DM_ERROR_NULLPTR;
4276     }
4277     hasPrivateWindow = screenSession->HasPrivateSessionForeground();
4278     TLOGI(WmsLogTag::DMS, "id: %{public}" PRIu64" has private window: %{public}u",
4279         id, static_cast<uint32_t>(hasPrivateWindow));
4280     return DMError::DM_OK;
4281 }
4282 
OnScreenGroupChange(const std::string & trigger,const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent groupEvent)4283 void ScreenSessionManager::OnScreenGroupChange(const std::string& trigger,
4284     const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent groupEvent)
4285 {
4286     if (screenInfo == nullptr) {
4287         return;
4288     }
4289     std::vector<sptr<ScreenInfo>> screenInfos;
4290     screenInfos.push_back(screenInfo);
4291     OnScreenGroupChange(trigger, screenInfos, groupEvent);
4292 }
4293 
OnScreenGroupChange(const std::string & trigger,const std::vector<sptr<ScreenInfo>> & screenInfos,ScreenGroupChangeEvent groupEvent)4294 void ScreenSessionManager::OnScreenGroupChange(const std::string& trigger,
4295     const std::vector<sptr<ScreenInfo>>& screenInfos, ScreenGroupChangeEvent groupEvent)
4296 {
4297     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
4298     std::vector<sptr<ScreenInfo>> infos;
4299     for (auto& screenInfo : screenInfos) {
4300         if (screenInfo != nullptr) {
4301             infos.emplace_back(screenInfo);
4302         }
4303     }
4304     if (agents.empty() || infos.empty()) {
4305         return;
4306     }
4307     for (auto& agent : agents) {
4308         agent->OnScreenGroupChange(trigger, infos, groupEvent);
4309     }
4310 }
4311 
OnScreenConnect(const sptr<ScreenInfo> screenInfo)4312 void ScreenSessionManager::OnScreenConnect(const sptr<ScreenInfo> screenInfo)
4313 {
4314     if (screenInfo == nullptr) {
4315         TLOGE(WmsLogTag::DMS, "OnScreenConnect screenInfo nullptr");
4316         return;
4317     }
4318     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
4319     if (agents.empty()) {
4320         TLOGI(WmsLogTag::DMS, "OnScreenConnect agents empty");
4321         return;
4322     }
4323     TLOGI(WmsLogTag::DMS, "OnScreenConnect");
4324     for (auto& agent : agents) {
4325         agent->OnScreenConnect(screenInfo);
4326     }
4327     NotifyScreenModeChange();
4328 }
4329 
OnScreenDisconnect(ScreenId screenId)4330 void ScreenSessionManager::OnScreenDisconnect(ScreenId screenId)
4331 {
4332     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
4333     if (agents.empty()) {
4334         TLOGI(WmsLogTag::DMS, "OnScreenDisconnect agents empty");
4335         return;
4336     }
4337     TLOGI(WmsLogTag::DMS, "OnScreenDisconnect");
4338     for (auto& agent : agents) {
4339         agent->OnScreenDisconnect(screenId);
4340     }
4341     NotifyScreenModeChange();
4342 }
4343 
OnScreenshot(sptr<ScreenshotInfo> info)4344 void ScreenSessionManager::OnScreenshot(sptr<ScreenshotInfo> info)
4345 {
4346     if (info == nullptr) {
4347         TLOGE(WmsLogTag::DMS, "OnScreenshot info is null");
4348         return;
4349     }
4350     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREENSHOT_EVENT_LISTENER);
4351     if (agents.empty()) {
4352         TLOGD(WmsLogTag::DMS, "agents empty");
4353         return;
4354     }
4355     TLOGI(WmsLogTag::DMS, "onScreenshot");
4356     for (auto& agent : agents) {
4357         agent->OnScreenshot(info);
4358     }
4359 }
4360 
GetCutoutInfo(DisplayId displayId)4361 sptr<CutoutInfo> ScreenSessionManager::GetCutoutInfo(DisplayId displayId)
4362 {
4363     DmsXcollie dmsXcollie("DMS:GetCutoutInfo", XCOLLIE_TIMEOUT_10S);
4364     return screenCutoutController_ ? screenCutoutController_->GetScreenCutoutInfo(displayId) : nullptr;
4365 }
4366 
HasImmersiveWindow(bool & immersive)4367 DMError ScreenSessionManager::HasImmersiveWindow(bool& immersive)
4368 {
4369     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4370         TLOGE(WmsLogTag::DMS, "permission denied!");
4371         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4372     }
4373     if (!clientProxy_) {
4374         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
4375         return DMError::DM_ERROR_NULLPTR;
4376     }
4377     clientProxy_->OnImmersiveStateChanged(immersive);
4378     return DMError::DM_OK;
4379 }
4380 
SetDisplayBoundary(const sptr<ScreenSession> screenSession)4381 void ScreenSessionManager::SetDisplayBoundary(const sptr<ScreenSession> screenSession)
4382 {
4383     if (screenSession && screenCutoutController_) {
4384         RectF rect =
4385             screenCutoutController_->CalculateCurvedCompression(screenSession->GetScreenProperty());
4386         if (!rect.IsEmpty()) {
4387             screenSession->SetDisplayBoundary(rect, screenCutoutController_->GetOffsetY());
4388         }
4389     } else {
4390         TLOGW(WmsLogTag::DMS, "screenSession or screenCutoutController_ is null");
4391     }
4392 }
4393 
TransferTypeToString(ScreenType type) const4394 std::string ScreenSessionManager::TransferTypeToString(ScreenType type) const
4395 {
4396     std::string screenType;
4397     switch (type) {
4398         case ScreenType::REAL:
4399             screenType = "REAL";
4400             break;
4401         case ScreenType::VIRTUAL:
4402             screenType = "VIRTUAL";
4403             break;
4404         default:
4405             screenType = "UNDEFINED";
4406             break;
4407     }
4408     return screenType;
4409 }
4410 
TransferPropertyChangeTypeToString(ScreenPropertyChangeType type) const4411 std::string ScreenSessionManager::TransferPropertyChangeTypeToString(ScreenPropertyChangeType type) const
4412 {
4413     std::string screenType;
4414     switch (type) {
4415         case ScreenPropertyChangeType::UNSPECIFIED:
4416             screenType = "UNSPECIFIED";
4417             break;
4418         case ScreenPropertyChangeType::ROTATION_BEGIN:
4419             screenType = "ROTATION_BEGIN";
4420             break;
4421         case ScreenPropertyChangeType::ROTATION_END:
4422             screenType = "ROTATION_END";
4423             break;
4424         default:
4425             screenType = "ROTATION_UPDATE_PROPERTY_ONLY";
4426             break;
4427     }
4428     return screenType;
4429 }
4430 
DumpAllScreensInfo(std::string & dumpInfo)4431 void ScreenSessionManager::DumpAllScreensInfo(std::string& dumpInfo)
4432 {
4433     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
4434         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4435             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4436         return;
4437     }
4438     std::ostringstream oss;
4439     oss << "--------------------------------------Free Screen"
4440         << "--------------------------------------"
4441         << std::endl;
4442     oss << "ScreenName           Type     IsGroup DmsId RsId                 ActiveIdx VPR Rotation Orientation "
4443         << "RequestOrientation NodeId               "
4444         << std::endl;
4445     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4446     for (auto sessionIt : screenSessionMap_) {
4447         auto screenSession = sessionIt.second;
4448         if (screenSession == nullptr) {
4449             continue;
4450         }
4451         sptr<ScreenInfo> screenInfo = screenSession->ConvertToScreenInfo();
4452         if (screenInfo == nullptr) {
4453             continue;
4454         }
4455         std::string screenType = TransferTypeToString(screenInfo->GetType());
4456         NodeId nodeId = (screenSession->GetDisplayNode() == nullptr) ?
4457             SCREEN_ID_INVALID : screenSession->GetDisplayNode()->GetId();
4458         oss << std::left << std::setw(21) << screenInfo->GetName() // 21 is width
4459             << std::left << std::setw(9) << screenType // 9 is width
4460             << std::left << std::setw(8) << (screenSession->isScreenGroup_ ? "true" : "false") // 8 is width
4461             << std::left << std::setw(6) << screenSession->screenId_ // 6 is width
4462             << std::left << std::setw(21) << screenSession->rsId_ // 21 is width
4463             << std::left << std::setw(10) << screenSession->activeIdx_ // 10 is width
4464             << std::left << std::setw(4) << screenInfo->GetVirtualPixelRatio() // 4 is width
4465             << std::left << std::setw(9) << static_cast<uint32_t>(screenInfo->GetRotation()) // 9 is width
4466             << std::left << std::setw(12) << static_cast<uint32_t>(screenInfo->GetOrientation()) // 12 is width
4467             << std::left << std::setw(19) // 19 is width
4468                 << static_cast<uint32_t>(screenSession->GetScreenRequestedOrientation())
4469             << std::left << std::setw(21) << nodeId // 21 is width
4470             << std::endl;
4471     }
4472     oss << "total screen num: " << screenSessionMap_.size() << std::endl;
4473     dumpInfo.append(oss.str());
4474 }
4475 
DumpSpecialScreenInfo(ScreenId id,std::string & dumpInfo)4476 void ScreenSessionManager::DumpSpecialScreenInfo(ScreenId id, std::string& dumpInfo)
4477 {
4478     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
4479         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4480             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4481         return;
4482     }
4483     std::ostringstream oss;
4484     sptr<ScreenSession> session = GetScreenSession(id);
4485     if (!session) {
4486         TLOGE(WmsLogTag::DMS, "Get screen session failed.");
4487         oss << "This screen id is invalid.";
4488         dumpInfo.append(oss.str());
4489         return;
4490     }
4491     sptr<ScreenInfo> screenInfo = GetScreenInfoById(id);
4492     if (screenInfo == nullptr) {
4493         return;
4494     }
4495     std::string screenType = TransferTypeToString(screenInfo->GetType());
4496     NodeId nodeId = (session->GetDisplayNode() == nullptr) ?
4497         SCREEN_ID_INVALID : session->GetDisplayNode()->GetId();
4498     oss << "ScreenName: " << screenInfo->GetName() << std::endl;
4499     oss << "Type: " << screenType << std::endl;
4500     oss << "IsGroup: " << (session->isScreenGroup_ ? "true" : "false") << std::endl;
4501     oss << "DmsId: " << id << std::endl;
4502     oss << "RsId: " << session->rsId_ << std::endl;
4503     oss << "ActiveIdx: " << session->activeIdx_ << std::endl;
4504     oss << "VPR: " << screenInfo->GetVirtualPixelRatio() << std::endl;
4505     oss << "Rotation: " << static_cast<uint32_t>(screenInfo->GetRotation()) << std::endl;
4506     oss << "Orientation: " << static_cast<uint32_t>(screenInfo->GetOrientation()) << std::endl;
4507     oss << "RequestOrientation: " << static_cast<uint32_t>(session->GetScreenRequestedOrientation()) << std::endl;
4508     oss << "NodeId: " << nodeId << std::endl;
4509     dumpInfo.append(oss.str());
4510 }
4511 
4512 // --- Fold Screen ---
GetPhyScreenProperty(ScreenId screenId)4513 ScreenProperty ScreenSessionManager::GetPhyScreenProperty(ScreenId screenId)
4514 {
4515     std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
4516     ScreenProperty property;
4517     auto iter = phyScreenPropMap_.find(screenId);
4518     if (iter == phyScreenPropMap_.end()) {
4519         TLOGI(WmsLogTag::DMS, "Error found physic screen config with id: %{public}" PRIu64, screenId);
4520         return property;
4521     }
4522     return iter->second;
4523 }
4524 
SetFoldDisplayMode(const FoldDisplayMode displayMode)4525 void ScreenSessionManager::SetFoldDisplayMode(const FoldDisplayMode displayMode)
4526 {
4527     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4528         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4529             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4530         return;
4531     }
4532     if (!g_foldScreenFlag) {
4533         return;
4534     }
4535     if (foldScreenController_ == nullptr) {
4536         TLOGI(WmsLogTag::DMS, "SetFoldDisplayMode foldScreenController_ is null");
4537         return;
4538     }
4539     if (!SessionPermission::IsSystemCalling()) {
4540         TLOGE(WmsLogTag::DMS, "SetFoldDisplayMode permission denied!");
4541         return;
4542     }
4543     TLOGI(WmsLogTag::DMS, "calling clientName: %{public}s, calling pid: %{public}d, setmode: %{public}d",
4544         SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid(), displayMode);
4545     if (foldScreenController_->GetTentMode() &&
4546         (displayMode == FoldDisplayMode::FULL || displayMode == FoldDisplayMode::COORDINATION)) {
4547         TLOGW(WmsLogTag::DMS, "in TentMode, SetFoldDisplayMode to %{public}d failed", displayMode);
4548         return;
4549     }
4550     foldScreenController_->SetDisplayMode(displayMode);
4551     NotifyClientProxyUpdateFoldDisplayMode(displayMode);
4552 }
4553 
SetFoldDisplayModeFromJs(const FoldDisplayMode displayMode)4554 DMError ScreenSessionManager::SetFoldDisplayModeFromJs(const FoldDisplayMode displayMode)
4555 {
4556     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4557         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4558             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4559         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4560     }
4561     SetFoldDisplayMode(displayMode);
4562     return DMError::DM_OK;
4563 }
4564 
UpdateDisplayScaleState(ScreenId screenId)4565 void ScreenSessionManager::UpdateDisplayScaleState(ScreenId screenId)
4566 {
4567     auto session = GetScreenSession(screenId);
4568     if (session == nullptr) {
4569         TLOGE(WmsLogTag::DMS, "session is null");
4570         return;
4571     }
4572     const ScreenProperty& property = session->GetScreenProperty();
4573     if (std::fabs(property.GetScaleX() - DEFAULT_SCALE) < FLT_EPSILON &&
4574         std::fabs(property.GetScaleY() - DEFAULT_SCALE) < FLT_EPSILON &&
4575         std::fabs(property.GetPivotX() - DEFAULT_PIVOT) < FLT_EPSILON &&
4576         std::fabs(property.GetPivotY() - DEFAULT_PIVOT) < FLT_EPSILON) {
4577         TLOGD(WmsLogTag::DMS, "The scale and pivot is default value now. There is no need to update");
4578         return;
4579     }
4580     SetDisplayScaleInner(screenId, property.GetScaleX(), property.GetScaleY(), property.GetPivotX(),
4581                          property.GetPivotY());
4582 }
4583 
SetDisplayScaleInner(ScreenId screenId,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY)4584 void ScreenSessionManager::SetDisplayScaleInner(ScreenId screenId, const float& scaleX, const float& scaleY,
4585                                                 const float& pivotX, const float& pivotY)
4586 {
4587     auto session = GetScreenSession(screenId);
4588     if (session == nullptr) {
4589         TLOGE(WmsLogTag::DMS, "session is null");
4590         return;
4591     }
4592     if (pivotX > 1.0f || pivotX < 0.0f || pivotY > 1.0f || pivotY < 0.0f) {
4593         TLOGE(WmsLogTag::DMS, "pivotX [%{public}f] and pivotY [%{public}f] should be in [0.0~1.0f]", pivotX, pivotY);
4594         return;
4595     }
4596     float translateX = 0.0f;
4597     float translateY = 0.0f;
4598     if (ROTATE_POLICY == FOLDABLE_DEVICE && FoldDisplayMode::FULL == GetFoldDisplayMode()) {
4599         CalcDisplayNodeTranslateOnFoldableRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
4600     } else {
4601         CalcDisplayNodeTranslateOnRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
4602     }
4603     TLOGD(WmsLogTag::DMS,
4604           "screenId %{public}" PRIu64 ", scale [%{public}f, %{public}f], "
4605           "pivot [%{public}f, %{public}f], translate [%{public}f, %{public}f]",
4606           screenId, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
4607     session->SetScreenScale(scaleX, scaleY, pivotX, pivotY, translateX, translateY);
4608     NotifyDisplayStateChange(GetDefaultScreenId(), session->ConvertToDisplayInfo(), {},
4609                              DisplayStateChangeType::UPDATE_SCALE);
4610 }
4611 
CalcDisplayNodeTranslateOnFoldableRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)4612 void ScreenSessionManager::CalcDisplayNodeTranslateOnFoldableRotation(sptr<ScreenSession>& session, const float& scaleX,
4613                                                                       const float& scaleY, const float& pivotX,
4614                                                                       const float& pivotY, float& translateX,
4615                                                                       float& translateY)
4616 {
4617     if (session == nullptr) {
4618         TLOGE(WmsLogTag::DMS, "session is nullptr");
4619         return;
4620     }
4621     const ScreenProperty& screenProperty = session->GetScreenProperty();
4622     auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
4623     auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
4624     Rotation rotation = session->GetRotation();
4625     float rotatedPivotX = DEFAULT_PIVOT;
4626     float rotatedPivotY = DEFAULT_PIVOT;
4627     float width = 0.0f;
4628     float height = 0.0f;
4629     switch (rotation) {
4630         case Rotation::ROTATION_0:
4631             rotatedPivotX = pivotY;
4632             rotatedPivotY = 1.0f - pivotX;
4633             width = screenHeight;
4634             height = screenWidth;
4635             break;
4636         case Rotation::ROTATION_90:
4637             rotatedPivotX = 1.0f - pivotX;
4638             rotatedPivotY = 1.0f - pivotY;
4639             width = screenWidth;
4640             height = screenHeight;
4641             break;
4642         case Rotation::ROTATION_180:
4643             rotatedPivotX = 1.0f - pivotY;
4644             rotatedPivotY = pivotX;
4645             width = screenHeight;
4646             height = screenWidth;
4647             break;
4648         case Rotation::ROTATION_270:
4649             rotatedPivotX = pivotX;
4650             rotatedPivotY = pivotY;
4651             width = screenWidth;
4652             height = screenHeight;
4653             break;
4654         default:
4655             TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
4656             break;
4657     }
4658     translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
4659     translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
4660 }
4661 
CalcDisplayNodeTranslateOnRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)4662 void ScreenSessionManager::CalcDisplayNodeTranslateOnRotation(sptr<ScreenSession>& session, const float& scaleX,
4663                                                               const float& scaleY, const float& pivotX,
4664                                                               const float& pivotY, float& translateX, float& translateY)
4665 {
4666     if (session == nullptr) {
4667         TLOGE(WmsLogTag::DMS, "session is nullptr");
4668         return;
4669     }
4670     const ScreenProperty& screenProperty = session->GetScreenProperty();
4671     auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
4672     auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
4673     Rotation rotation = session->GetRotation();
4674     float rotatedPivotX = DEFAULT_PIVOT;
4675     float rotatedPivotY = DEFAULT_PIVOT;
4676     float width = 0.0f;
4677     float height = 0.0f;
4678     switch (rotation) {
4679         case Rotation::ROTATION_0:
4680             rotatedPivotX = pivotX;
4681             rotatedPivotY = pivotY;
4682             width = screenWidth;
4683             height = screenHeight;
4684             break;
4685         case Rotation::ROTATION_90:
4686             rotatedPivotX = pivotY;
4687             rotatedPivotY = 1.0f - pivotX;
4688             width = screenHeight;
4689             height = screenWidth;
4690             break;
4691         case Rotation::ROTATION_180:
4692             rotatedPivotX = 1.0f - pivotX;
4693             rotatedPivotY = 1.0f - pivotY;
4694             width = screenWidth;
4695             height = screenHeight;
4696             break;
4697         case Rotation::ROTATION_270:
4698             rotatedPivotX = 1.0f - pivotY;
4699             rotatedPivotY = pivotX;
4700             width = screenHeight;
4701             height = screenWidth;
4702             break;
4703         default:
4704             TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
4705             break;
4706     }
4707     translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
4708     translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
4709 }
4710 
SetDisplayScale(ScreenId screenId,float scaleX,float scaleY,float pivotX,float pivotY)4711 void ScreenSessionManager::SetDisplayScale(ScreenId screenId, float scaleX, float scaleY, float pivotX,
4712     float pivotY)
4713 {
4714     if (!SessionPermission::IsSACalling()) {
4715         TLOGE(WmsLogTag::DMS, "calling clientName: %{public}s, calling pid: %{public}d",
4716             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4717         return;
4718     }
4719     SetDisplayScaleInner(screenId, scaleX, scaleY, pivotX, pivotY);
4720 }
4721 
SetFoldStatusLocked(bool locked)4722 void ScreenSessionManager::SetFoldStatusLocked(bool locked)
4723 {
4724     if (!g_foldScreenFlag) {
4725         return;
4726     }
4727     if (foldScreenController_ == nullptr) {
4728         TLOGI(WmsLogTag::DMS, "SetFoldStatusLocked foldScreenController_ is null");
4729         return;
4730     }
4731     if (!SessionPermission::IsSystemCalling()) {
4732         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4733             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4734         return;
4735     }
4736     foldScreenController_->LockDisplayStatus(locked);
4737 }
4738 
SetFoldStatusLockedFromJs(bool locked)4739 DMError ScreenSessionManager::SetFoldStatusLockedFromJs(bool locked)
4740 {
4741     if (!SessionPermission::IsSystemCalling()) {
4742         TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4743             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4744         return DMError::DM_ERROR_NOT_SYSTEM_APP;
4745     }
4746     SetFoldStatusLocked(locked);
4747     return DMError::DM_OK;
4748 }
4749 
GetFoldDisplayMode()4750 FoldDisplayMode ScreenSessionManager::GetFoldDisplayMode()
4751 {
4752     DmsXcollie dmsXcollie("DMS:GetFoldDisplayMode", XCOLLIE_TIMEOUT_10S);
4753     if (!g_foldScreenFlag) {
4754         return FoldDisplayMode::UNKNOWN;
4755     }
4756     if (foldScreenController_ == nullptr) {
4757         TLOGD(WmsLogTag::DMS, "GetFoldDisplayMode foldScreenController_ is null");
4758         return FoldDisplayMode::UNKNOWN;
4759     }
4760     return foldScreenController_->GetDisplayMode();
4761 }
4762 
IsFoldable()4763 bool ScreenSessionManager::IsFoldable()
4764 {
4765     DmsXcollie dmsXcollie("DMS:IsFoldable", XCOLLIE_TIMEOUT_10S);
4766     // Most applications do not adapt to Lem rotation and are temporarily treated as non fold device
4767     if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
4768         return false;
4769     }
4770 
4771     if (!g_foldScreenFlag) {
4772         return false;
4773     }
4774     if (foldScreenController_ == nullptr) {
4775         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
4776         return false;
4777     }
4778     return foldScreenController_->IsFoldable();
4779 }
4780 
IsCaptured()4781 bool ScreenSessionManager::IsCaptured()
4782 {
4783     return isScreenShot_ || virtualScreenCount_ > 0 || hdmiScreenCount_ > 0;
4784 }
4785 
IsMultiScreenCollaboration()4786 bool ScreenSessionManager::IsMultiScreenCollaboration()
4787 {
4788     return isMultiScreenCollaboration_;
4789 }
4790 
GetFoldStatus()4791 FoldStatus ScreenSessionManager::GetFoldStatus()
4792 {
4793     DmsXcollie dmsXcollie("DMS:GetFoldStatus", XCOLLIE_TIMEOUT_10S);
4794     if (!g_foldScreenFlag) {
4795         return FoldStatus::UNKNOWN;
4796     }
4797     if (foldScreenController_ == nullptr) {
4798         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
4799         return FoldStatus::UNKNOWN;
4800     }
4801     return foldScreenController_->GetFoldStatus();
4802 }
4803 
GetTentMode()4804 bool ScreenSessionManager::GetTentMode()
4805 {
4806     if (!g_foldScreenFlag) {
4807         return false;
4808     }
4809     if (foldScreenController_ == nullptr) {
4810         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
4811         return false;
4812     }
4813     return foldScreenController_->GetTentMode();
4814 }
4815 
GetCurrentFoldCreaseRegion()4816 sptr<FoldCreaseRegion> ScreenSessionManager::GetCurrentFoldCreaseRegion()
4817 {
4818     if (!g_foldScreenFlag) {
4819         return nullptr;
4820     }
4821     if (foldScreenController_ == nullptr) {
4822         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
4823         return nullptr;
4824     }
4825     return foldScreenController_->GetCurrentFoldCreaseRegion();
4826 }
4827 
GetCurvedCompressionArea()4828 uint32_t ScreenSessionManager::GetCurvedCompressionArea()
4829 {
4830     return ScreenSceneConfig::GetCurvedCompressionAreaInLandscape();
4831 }
4832 
NotifyFoldStatusChanged(FoldStatus foldStatus)4833 void ScreenSessionManager::NotifyFoldStatusChanged(FoldStatus foldStatus)
4834 {
4835     TLOGI(WmsLogTag::DMS, "NotifyFoldStatusChanged foldStatus:%{public}d", foldStatus);
4836     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
4837     if (screenSession != nullptr) {
4838         if (foldStatus == FoldStatus::FOLDED) {
4839             screenSession->SetDefaultDeviceRotationOffset(0);
4840         } else {
4841             screenSession->SetDefaultDeviceRotationOffset(defaultDeviceRotationOffset_);
4842         }
4843     }
4844     if (screenSession != nullptr && FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
4845         // 维护外屏独立dpi
4846         if (foldStatus == FoldStatus::FOLDED) {
4847             auto property = screenSession->GetScreenProperty();
4848             densityDpi_ = property.GetDensity();
4849             SetVirtualPixelRatio(GetDefaultScreenId(), subDensityDpi_);
4850         } else {
4851             SetVirtualPixelRatio(GetDefaultScreenId(), densityDpi_);
4852         }
4853     }
4854     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER);
4855     if (agents.empty()) {
4856         TLOGI(WmsLogTag::DMS, "NotifyFoldStatusChanged agents is empty");
4857         return;
4858     }
4859     for (auto& agent : agents) {
4860         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
4861         if (!IsFreezed(agentPid, DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER)) {
4862             agent->NotifyFoldStatusChanged(foldStatus);
4863         }
4864     }
4865 }
4866 
NotifyFoldAngleChanged(std::vector<float> foldAngles)4867 void ScreenSessionManager::NotifyFoldAngleChanged(std::vector<float> foldAngles)
4868 {
4869     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER);
4870     if (agents.empty()) {
4871         TLOGI(WmsLogTag::DMS, "NotifyFoldAngleChanged agents is empty");
4872         return;
4873     }
4874     {
4875         std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
4876         lastFoldAngles_ = foldAngles;
4877     }
4878     for (auto& agent : agents) {
4879         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
4880         if (!IsFreezed(agentPid, DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER)) {
4881             agent->NotifyFoldAngleChanged(foldAngles);
4882         }
4883     }
4884 }
4885 
NotifyCaptureStatusChanged()4886 void ScreenSessionManager::NotifyCaptureStatusChanged()
4887 {
4888     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER);
4889     bool isCapture = IsCaptured();
4890     isScreenShot_ = false;
4891     if (agents.empty()) {
4892         TLOGI(WmsLogTag::DMS, "agents is empty");
4893         return;
4894     }
4895     for (auto& agent : agents) {
4896         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
4897         if (!IsFreezed(agentPid, DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER)) {
4898             agent->NotifyCaptureStatusChanged(isCapture);
4899         }
4900     }
4901 }
4902 
NotifyDisplayChangeInfoChanged(const sptr<DisplayChangeInfo> & info)4903 void ScreenSessionManager::NotifyDisplayChangeInfoChanged(const sptr<DisplayChangeInfo>& info)
4904 {
4905     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER);
4906     if (agents.empty()) {
4907         TLOGI(WmsLogTag::DMS, "Agents is empty");
4908         return;
4909     }
4910     {
4911         std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
4912         lastDisplayChangeInfo_ = info;
4913     }
4914     for (auto& agent : agents) {
4915         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
4916         if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER)) {
4917             agent->NotifyDisplayChangeInfoChanged(info);
4918         }
4919     }
4920 }
4921 
NotifyDisplayModeChanged(FoldDisplayMode displayMode)4922 void ScreenSessionManager::NotifyDisplayModeChanged(FoldDisplayMode displayMode)
4923 {
4924     TLOGI(WmsLogTag::DMS, "DisplayMode:%{public}d", displayMode);
4925     NotifyClientProxyUpdateFoldDisplayMode(displayMode);
4926     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER);
4927     if (agents.empty()) {
4928         TLOGI(WmsLogTag::DMS, "Agents is empty");
4929         return;
4930     }
4931     for (auto& agent : agents) {
4932         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
4933         if (!IsFreezed(agentPid,
4934             DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER)) {
4935             agent->NotifyDisplayModeChanged(displayMode);
4936         }
4937     }
4938 }
4939 
SetDisplayNodeScreenId(ScreenId screenId,ScreenId displayNodeScreenId)4940 void ScreenSessionManager::SetDisplayNodeScreenId(ScreenId screenId, ScreenId displayNodeScreenId)
4941 {
4942     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " displayNodeScreenId: %{public}" PRIu64,
4943         screenId, displayNodeScreenId);
4944     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetDisplayNodeScreenId");
4945     if (!clientProxy_) {
4946         TLOGI(WmsLogTag::DMS, "SetDisplayNodeScreenId clientProxy_ is null");
4947         return;
4948     }
4949     clientProxy_->SetDisplayNodeScreenId(screenId, displayNodeScreenId);
4950 #ifdef DEVICE_STATUS_ENABLE
4951     SetDragWindowScreenId(screenId, displayNodeScreenId);
4952 #endif // DEVICE_STATUS_ENABLE
4953 }
4954 
4955 #ifdef DEVICE_STATUS_ENABLE
SetDragWindowScreenId(ScreenId screenId,ScreenId displayNodeScreenId)4956 void ScreenSessionManager::SetDragWindowScreenId(ScreenId screenId, ScreenId displayNodeScreenId)
4957 {
4958     auto interactionManager = Msdp::DeviceStatus::InteractionManager::GetInstance();
4959     if (interactionManager != nullptr) {
4960         interactionManager->SetDragWindowScreenId(screenId, displayNodeScreenId);
4961     }
4962 }
4963 #endif // DEVICE_STATUS_ENABLE
4964 
OnPropertyChange(const ScreenProperty & newProperty,ScreenPropertyChangeReason reason,ScreenId screenId)4965 void ScreenSessionManager::OnPropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason,
4966     ScreenId screenId)
4967 {
4968     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " reason: %{public}d", screenId, static_cast<int>(reason));
4969     if (!clientProxy_) {
4970         TLOGI(WmsLogTag::DMS, "OnPropertyChange clientProxy_ is null");
4971         return;
4972     }
4973     clientProxy_->OnPropertyChanged(screenId, newProperty, reason);
4974 }
4975 
OnPowerStatusChange(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)4976 void ScreenSessionManager::OnPowerStatusChange(DisplayPowerEvent event, EventStatus status,
4977     PowerStateChangeReason reason)
4978 {
4979     TLOGI(WmsLogTag::DMS, "[UL_POWER]event: %{public}d, status: %{public}d, reason: %{public}d",
4980         static_cast<int>(event),
4981         static_cast<int>(status), static_cast<int>(reason));
4982     if (!clientProxy_) {
4983         TLOGI(WmsLogTag::DMS, "[UL_POWER]OnPowerStatusChange clientProxy_ is null");
4984         return;
4985     }
4986     clientProxy_->OnPowerStatusChanged(event, status, reason);
4987 }
4988 
OnSensorRotationChange(float sensorRotation,ScreenId screenId)4989 void ScreenSessionManager::OnSensorRotationChange(float sensorRotation, ScreenId screenId)
4990 {
4991     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " sensorRotation: %{public}f", screenId, sensorRotation);
4992     if (!clientProxy_) {
4993         TLOGI(WmsLogTag::DMS, "OnSensorRotationChange clientProxy_ is null");
4994         return;
4995     }
4996     clientProxy_->OnSensorRotationChanged(screenId, sensorRotation);
4997 }
4998 
OnHoverStatusChange(int32_t hoverStatus,ScreenId screenId)4999 void ScreenSessionManager::OnHoverStatusChange(int32_t hoverStatus, ScreenId screenId)
5000 {
5001     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " hoverStatus: %{public}d", screenId, hoverStatus);
5002     if (!clientProxy_) {
5003         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
5004         return;
5005     }
5006     clientProxy_->OnHoverStatusChanged(screenId, hoverStatus);
5007 }
5008 
OnScreenOrientationChange(float screenOrientation,ScreenId screenId)5009 void ScreenSessionManager::OnScreenOrientationChange(float screenOrientation, ScreenId screenId)
5010 {
5011     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " screenOrientation: %{public}f", screenId, screenOrientation);
5012     if (!clientProxy_) {
5013         TLOGI(WmsLogTag::DMS, "OnScreenOrientationChange clientProxy_ is null");
5014         return;
5015     }
5016     clientProxy_->OnScreenOrientationChanged(screenId, screenOrientation);
5017 }
5018 
OnScreenRotationLockedChange(bool isLocked,ScreenId screenId)5019 void ScreenSessionManager::OnScreenRotationLockedChange(bool isLocked, ScreenId screenId)
5020 {
5021     TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " isLocked: %{public}d", screenId, isLocked);
5022     if (!clientProxy_) {
5023         TLOGI(WmsLogTag::DMS, "OnScreenRotationLockedChange clientProxy_ is null");
5024         return;
5025     }
5026     clientProxy_->OnScreenRotationLockedChanged(screenId, isLocked);
5027 }
5028 
NotifyClientProxyUpdateFoldDisplayMode(FoldDisplayMode displayMode)5029 void ScreenSessionManager::NotifyClientProxyUpdateFoldDisplayMode(FoldDisplayMode displayMode)
5030 {
5031     if (clientProxy_) {
5032         TLOGI(WmsLogTag::DMS, "NotifyClientProxyUpdateFoldDisplayMode displayMode = %{public}d",
5033             static_cast<int>(displayMode));
5034         clientProxy_->OnUpdateFoldDisplayMode(displayMode);
5035     }
5036 }
5037 
BlockScbByAvailabelBuffer()5038 void ScreenSessionManager::BlockScbByAvailabelBuffer()
5039 {
5040     std::unique_lock<std::mutex> lock(scbBufferAvailableMutex_);
5041     if (scbBufferAvailableCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_BUFFER_AVAILABLE_MS))
5042         == std::cv_status::timeout) {
5043         TLOGI(WmsLogTag::DMS, "available wait scbBufferAvailableCV_ timeout");
5044     }
5045 }
5046 
ScbClientDeathCallback(int32_t deathScbPid)5047 void ScreenSessionManager::ScbClientDeathCallback(int32_t deathScbPid)
5048 {
5049     std::unique_lock<std::mutex> lock(oldScbPidsMutex_);
5050     if (deathScbPid == currentScbPId_ || currentScbPId_ == INVALID_SCB_PID) {
5051         clientProxy_ = nullptr;
5052         TLOGE(WmsLogTag::DMS, "death callback, clientProxy is set null");
5053     }
5054     if (scbSwitchCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_SCBSWITCH_MS))
5055         == std::cv_status::timeout) {
5056         TLOGE(WmsLogTag::DMS, "set client task deathScbPid:%{public}d, timeout: %{public}d",
5057             deathScbPid, CV_WAIT_SCBSWITCH_MS);
5058     }
5059     std::ostringstream oss;
5060     oss << "Scb client death: " << deathScbPid;
5061     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
5062     screenEventTracker_.RecordEvent(oss.str());
5063     oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), deathScbPid), oldScbPids_.end());
5064 }
5065 
AddScbClientDeathRecipient(const sptr<IScreenSessionManagerClient> & scbClient,int32_t scbPid)5066 void ScreenSessionManager::AddScbClientDeathRecipient(const sptr<IScreenSessionManagerClient>& scbClient,
5067     int32_t scbPid)
5068 {
5069     sptr<ScbClientListenerDeathRecipient> scbClientDeathListener =
5070         new (std::nothrow) ScbClientListenerDeathRecipient(scbPid);
5071     if (scbClientDeathListener == nullptr) {
5072         TLOGE(WmsLogTag::DMS, "add scb: %{public}d death listener failed", scbPid);
5073         return;
5074     }
5075     if (scbClient != nullptr && scbClient->AsObject() != nullptr) {
5076         TLOGI(WmsLogTag::DMS, "add scb: %{public}d death listener", scbPid);
5077         scbClient->AsObject()->AddDeathRecipient(scbClientDeathListener);
5078     }
5079 }
5080 
SwitchUser()5081 void ScreenSessionManager::SwitchUser()
5082 {
5083     if (!SessionPermission::IsSystemCalling()) {
5084         TLOGE(WmsLogTag::DMS, "permission denied, calling clientName: %{public}s, calling pid: %{public}d",
5085             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5086         return;
5087     }
5088     auto userId = GetUserIdByCallingUid();
5089     auto newScbPid = IPCSkeleton::GetCallingPid();
5090     if (userId == currentUserId_) {
5091         TLOGE(WmsLogTag::DMS, "switch user not change");
5092         return;
5093     }
5094     SwitchScbNodeHandle(userId, newScbPid, false);
5095     MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, GetDefaultScreenId(), false);
5096 }
5097 
ScbStatusRecoveryWhenSwitchUser(std::vector<int32_t> oldScbPids,int32_t newScbPid)5098 void ScreenSessionManager::ScbStatusRecoveryWhenSwitchUser(std::vector<int32_t> oldScbPids, int32_t newScbPid)
5099 {
5100     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
5101     if (screenSession == nullptr) {
5102         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
5103         return;
5104     }
5105     if (g_foldScreenFlag) {
5106         NotifyFoldStatusChanged(GetFoldStatus());
5107         NotifyDisplayModeChanged(GetFoldDisplayMode());
5108     }
5109     int64_t delayTime = 0;
5110     if (g_foldScreenFlag && oldScbDisplayMode_ != GetFoldDisplayMode() &&
5111         !FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
5112         delayTime = SWITCH_USER_DISPLAYMODE_CHANGE_DELAY;
5113         auto foldStatus = GetFoldStatus();
5114         TLOGE(WmsLogTag::DMS, "old mode: %{public}u, cur mode: %{public}u", oldScbDisplayMode_, GetFoldDisplayMode());
5115         if (foldStatus == FoldStatus::EXPAND || foldStatus == FoldStatus::HALF_FOLD) {
5116             screenSession->UpdatePropertyByFoldControl(GetPhyScreenProperty(SCREEN_ID_FULL));
5117             screenSession->PropertyChange(screenSession->GetScreenProperty(),
5118                 ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
5119         } else if (foldStatus == FoldStatus::FOLDED) {
5120             screenSession->UpdatePropertyByFoldControl(GetPhyScreenProperty(SCREEN_ID_MAIN));
5121             screenSession->PropertyChange(screenSession->GetScreenProperty(),
5122                 ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING);
5123         } else {
5124             TLOGE(WmsLogTag::DMS, "unsupport foldStatus: %{public}u", foldStatus);
5125         }
5126     } else {
5127         screenSession->UpdateValidRotationToScb();
5128     }
5129     auto task = [=] {
5130         if (!clientProxy_) {
5131             TLOGE(WmsLogTag::DMS, "ScbStatusRecoveryWhenSwitchUser clientProxy_ is null");
5132             return;
5133         }
5134         clientProxy_->SwitchUserCallback(oldScbPids, newScbPid);
5135     };
5136     taskScheduler_->PostAsyncTask(task, "clientProxy_ SwitchUserCallback task", delayTime);
5137 }
5138 
SetClient(const sptr<IScreenSessionManagerClient> & client)5139 void ScreenSessionManager::SetClient(const sptr<IScreenSessionManagerClient>& client)
5140 {
5141     if (!SessionPermission::IsSystemCalling()) {
5142         TLOGE(WmsLogTag::DMS, "permission denied, calling clientName: %{public}s, calling pid: %{public}d",
5143             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5144         return;
5145     }
5146     if (!client) {
5147         TLOGE(WmsLogTag::DMS, "SetClient client is null");
5148         return;
5149     }
5150     clientProxy_ = client;
5151     auto userId = GetUserIdByCallingUid();
5152     auto newScbPid = IPCSkeleton::GetCallingPid();
5153 
5154     std::ostringstream oss;
5155     oss << "set client userId: " << userId
5156         << " newScbPid: " << newScbPid
5157         << " clientName: " << SysCapUtil::GetClientName();
5158     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
5159     screenEventTracker_.RecordEvent(oss.str());
5160 
5161     MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, GetDefaultScreenId(), true);
5162     NotifyClientProxyUpdateFoldDisplayMode(GetFoldDisplayMode());
5163     SetClientInner();
5164     SwitchScbNodeHandle(userId, newScbPid, true);
5165     AddScbClientDeathRecipient(client, newScbPid);
5166 }
5167 
SwitchScbNodeHandle(int32_t newUserId,int32_t newScbPid,bool coldBoot)5168 void ScreenSessionManager::SwitchScbNodeHandle(int32_t newUserId, int32_t newScbPid, bool coldBoot)
5169 {
5170     std::ostringstream oss;
5171     oss << "currentUserId: " << currentUserId_
5172         << "  currentScbPId: " << currentScbPId_
5173         << "  newUserId: " << newUserId
5174         << "  newScbPid: " << newScbPid
5175         << "  coldBoot: " << static_cast<int32_t>(coldBoot);
5176     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
5177     screenEventTracker_.RecordEvent(oss.str());
5178 
5179     std::unique_lock<std::mutex> lock(oldScbPidsMutex_);
5180     if (currentScbPId_ != INVALID_SCB_PID) {
5181         auto pidIter = std::find(oldScbPids_.begin(), oldScbPids_.end(), currentScbPId_);
5182         if (pidIter == oldScbPids_.end() && currentScbPId_ > 0) {
5183             oldScbPids_.emplace_back(currentScbPId_);
5184         }
5185         oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), newScbPid), oldScbPids_.end());
5186         if (oldScbPids_.size() == 0) {
5187             TLOGE(WmsLogTag::DMS, "swicth user failed, oldScbPids is null");
5188             screenEventTracker_.RecordEvent("swicth user failed, oldScbPids is null");
5189         }
5190     }
5191     if (!clientProxy_) {
5192         TLOGE(WmsLogTag::DMS, "clientProxy is null");
5193         return;
5194     }
5195     if (coldBoot) {
5196         clientProxy_->SwitchUserCallback(oldScbPids_, newScbPid);
5197         clientProxyMap_[newUserId] = clientProxy_;
5198     } else {
5199         // hot switch
5200         if (clientProxyMap_.count(newUserId) == 0) {
5201             TLOGE(WmsLogTag::DMS, "not found client proxy. userId:%{public}d.", newUserId);
5202             return;
5203         }
5204         if (newUserId == currentUserId_) {
5205             TLOGI(WmsLogTag::DMS, "switch user not change");
5206             return;
5207         }
5208         clientProxy_ = clientProxyMap_[newUserId];
5209         ScbStatusRecoveryWhenSwitchUser(oldScbPids_, newScbPid);
5210     }
5211     UpdateDisplayScaleState(GetDefaultScreenId());
5212     currentUserId_ = newUserId;
5213     currentScbPId_ = newScbPid;
5214     scbSwitchCV_.notify_all();
5215     oldScbDisplayMode_ = GetFoldDisplayMode();
5216 }
5217 
SetClientInner()5218 void ScreenSessionManager::SetClientInner()
5219 {
5220     std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5221     for (const auto& iter : screenSessionMap_) {
5222         if (!iter.second) {
5223             continue;
5224         }
5225         // In the rotating state, after scb restarts, the screen information needs to be reset.
5226         float phyWidth = 0.0f;
5227         float phyHeight = 0.0f;
5228         bool isReset = true;
5229         GetCurrentScreenPhyBounds(phyWidth, phyHeight, isReset, iter.first);
5230         auto localRotation = iter.second->GetRotation();
5231         TLOGI(WmsLogTag::DMS, "phyWidth = :%{public}f, phyHeight = :%{public}f, localRotation = :%{public}u",
5232             phyWidth, phyHeight, localRotation);
5233         bool isModeChanged = localRotation != Rotation::ROTATION_0;
5234         if (isModeChanged && isReset) {
5235             TLOGI(WmsLogTag::DMS, "screen(id:%{public}" PRIu64 ") current is not default mode, reset it", iter.first);
5236             SetRotation(iter.first, Rotation::ROTATION_0, false);
5237             iter.second->SetDisplayBoundary(RectF(0, 0, phyWidth, phyHeight), 0);
5238         }
5239         if (!clientProxy_) {
5240             TLOGE(WmsLogTag::DMS, "clientProxy is null");
5241             return;
5242         }
5243         clientProxy_->OnScreenConnectionChanged(iter.first, ScreenEvent::CONNECTED,
5244             iter.second->GetRSScreenId(), iter.second->GetName());
5245     }
5246 }
5247 
GetCurrentScreenPhyBounds(float & phyWidth,float & phyHeight,bool & isReset,const ScreenId & screenid)5248 void ScreenSessionManager::GetCurrentScreenPhyBounds(float& phyWidth, float& phyHeight,
5249                                                      bool& isReset, const ScreenId& screenid)
5250 {
5251     if (foldScreenController_ != nullptr) {
5252         FoldDisplayMode displayMode = GetFoldDisplayMode();
5253         TLOGI(WmsLogTag::DMS, "fold screen with screenId = %{public}u", displayMode);
5254         if (displayMode == FoldDisplayMode::MAIN) {
5255             auto phyBounds = GetPhyScreenProperty(SCREEN_ID_MAIN).GetPhyBounds();
5256             phyWidth = phyBounds.rect_.width_;
5257             phyHeight = phyBounds.rect_.height_;
5258         } else if (displayMode == FoldDisplayMode::FULL) {
5259             auto phyBounds = GetPhyScreenProperty(SCREEN_ID_FULL).GetPhyBounds();
5260             phyWidth = phyBounds.rect_.width_;
5261             phyHeight = phyBounds.rect_.height_;
5262             if (g_screenRotationOffSet == ROTATION_90 || g_screenRotationOffSet == ROTATION_270) {
5263                 std::swap(phyWidth, phyHeight);
5264             }
5265         } else {
5266             isReset = false;
5267         }
5268     } else {
5269         int id = HiviewDFX::XCollie::GetInstance().SetTimer("GetCurrentScreenPhyBounds", XCOLLIE_TIMEOUT_10S, nullptr,
5270             nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
5271         auto remoteScreenMode = rsInterface_.GetScreenActiveMode(screenid);
5272         HiviewDFX::XCollie::GetInstance().CancelTimer(id);
5273         phyWidth = remoteScreenMode.GetScreenWidth();
5274         phyHeight = remoteScreenMode.GetScreenHeight();
5275     }
5276 }
5277 
GetScreenProperty(ScreenId screenId)5278 ScreenProperty ScreenSessionManager::GetScreenProperty(ScreenId screenId)
5279 {
5280     DmsXcollie dmsXcollie("DMS:GetScreenProperty", XCOLLIE_TIMEOUT_10S);
5281     auto screenSession = GetScreenSession(screenId);
5282     if (!screenSession) {
5283         TLOGI(WmsLogTag::DMS, "GetScreenProperty screenSession is null");
5284         return {};
5285     }
5286     return screenSession->GetScreenProperty();
5287 }
5288 
GetDisplayNode(ScreenId screenId)5289 std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetDisplayNode(ScreenId screenId)
5290 {
5291     DmsXcollie dmsXcollie("DMS:GetDisplayNode", XCOLLIE_TIMEOUT_10S);
5292     auto screenSession = GetScreenSession(screenId);
5293     if (!screenSession) {
5294         TLOGE(WmsLogTag::DMS, "GetDisplayNode screenSession is null");
5295         return nullptr;
5296     }
5297     return screenSession->GetDisplayNode();
5298 }
5299 
Dump(int fd,const std::vector<std::u16string> & args)5300 int ScreenSessionManager::Dump(int fd, const std::vector<std::u16string>& args)
5301 {
5302     TLOGI(WmsLogTag::DMS, "Dump begin");
5303     sptr<ScreenSessionDumper> dumper = new ScreenSessionDumper(fd, args);
5304     if (dumper == nullptr) {
5305         TLOGE(WmsLogTag::DMS, "dumper is nullptr");
5306         return -1;
5307     }
5308     dumper->DumpFreezedPidList(freezedPidList_);
5309     dumper->DumpEventTracker(screenEventTracker_);
5310     dumper->DumpMultiUserInfo(oldScbPids_, currentUserId_, currentScbPId_);
5311     dumper->ExcuteDumpCmd();
5312     TLOGI(WmsLogTag::DMS, "dump end");
5313     return 0;
5314 }
5315 
NotifyFoldStatusChanged(const std::string & statusParam)5316 int ScreenSessionManager::NotifyFoldStatusChanged(const std::string& statusParam)
5317 {
5318     TLOGI(WmsLogTag::DMS, "NotifyFoldStatusChanged is dump log");
5319     if (statusParam.empty()) {
5320         return -1;
5321     }
5322     FoldStatus foldStatus = FoldStatus::UNKNOWN;
5323     FoldDisplayMode displayMode = FoldDisplayMode::UNKNOWN;
5324     if (statusParam == STATUS_FOLD_HALF) {
5325         foldStatus = FoldStatus::HALF_FOLD;
5326         displayMode = FoldDisplayMode::FULL;
5327     } else if (statusParam == STATUS_EXPAND) {
5328         foldStatus = FoldStatus::EXPAND;
5329         displayMode = FoldDisplayMode::FULL;
5330     } else if (statusParam == STATUS_FOLD) {
5331         foldStatus = FoldStatus::FOLDED;
5332         displayMode = FoldDisplayMode::MAIN;
5333     } else {
5334         TLOGW(WmsLogTag::DMS, "NotifyFoldStatusChanged status not support");
5335         return -1;
5336     }
5337     SetFoldDisplayMode(displayMode);
5338     if (foldScreenController_ != nullptr) {
5339         foldScreenController_->SetFoldStatus(foldStatus);
5340     }
5341     NotifyFoldStatusChanged(foldStatus);
5342     return 0;
5343 }
5344 
NotifyAvailableAreaChanged(DMRect area)5345 void ScreenSessionManager::NotifyAvailableAreaChanged(DMRect area)
5346 {
5347     TLOGI(WmsLogTag::DMS, "NotifyAvailableAreaChanged call");
5348     auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER);
5349     if (agents.empty()) {
5350         TLOGI(WmsLogTag::DMS, "NotifyAvailableAreaChanged agents is empty");
5351         return;
5352     }
5353     for (auto& agent : agents) {
5354         int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
5355         if (!IsFreezed(agentPid,
5356             DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER)) {
5357             agent->NotifyAvailableAreaChanged(area);
5358         }
5359     }
5360 }
5361 
GetAvailableArea(DisplayId displayId,DMRect & area)5362 DMError ScreenSessionManager::GetAvailableArea(DisplayId displayId, DMRect& area)
5363 {
5364     auto displayInfo = GetDisplayInfoById(displayId);
5365     if (displayInfo == nullptr) {
5366         TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
5367         return DMError::DM_ERROR_NULLPTR;
5368     }
5369     auto screenSession = GetScreenSession(displayInfo->GetScreenId());
5370     if (screenSession == nullptr) {
5371         TLOGE(WmsLogTag::DMS, "can not get default screen now");
5372         return DMError::DM_ERROR_NULLPTR;
5373     }
5374     area = screenSession->GetAvailableArea();
5375     return DMError::DM_OK;
5376 }
5377 
UpdateAvailableArea(ScreenId screenId,DMRect area)5378 void ScreenSessionManager::UpdateAvailableArea(ScreenId screenId, DMRect area)
5379 {
5380     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5381         TLOGE(WmsLogTag::DMS, "update available area permission denied!");
5382         return;
5383     }
5384 
5385     auto screenSession = GetScreenSession(screenId);
5386     if (screenSession == nullptr) {
5387         TLOGE(WmsLogTag::DMS, "can not get default screen now");
5388         return;
5389     }
5390     if (!screenSession->UpdateAvailableArea(area)) {
5391         return;
5392     }
5393     NotifyAvailableAreaChanged(area);
5394 }
5395 
NotifyFoldToExpandCompletion(bool foldToExpand)5396 void ScreenSessionManager::NotifyFoldToExpandCompletion(bool foldToExpand)
5397 {
5398     TLOGI(WmsLogTag::DMS, "NotifyFoldToExpandCompletion ENTER");
5399     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5400         TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
5401             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5402         return;
5403     }
5404     if (!FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
5405         SetDisplayNodeScreenId(SCREEN_ID_FULL, foldToExpand ? SCREEN_ID_FULL : SCREEN_ID_MAIN);
5406     }
5407     /* Avoid fold to expand process queues */
5408     if (foldScreenController_ != nullptr) {
5409         foldScreenController_->SetdisplayModeChangeStatus(false);
5410     }
5411     sptr<ScreenSession> screenSession = GetDefaultScreenSession();
5412     if (screenSession == nullptr) {
5413         TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
5414         return;
5415     }
5416     screenSession->UpdateRotationAfterBoot(foldToExpand);
5417 }
5418 
CheckAndSendHiSysEvent(const std::string & eventName,const std::string & bundleName) const5419 void ScreenSessionManager::CheckAndSendHiSysEvent(const std::string& eventName, const std::string& bundleName) const
5420 {
5421     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CheckAndSendHiSysEvent");
5422     if (eventName != "CREATE_VIRTUAL_SCREEN") {
5423         if (!Permission::CheckIsCallingBundleName(bundleName)) {
5424             TLOGD(WmsLogTag::DMS, "BundleName not in whitelist!");
5425             return;
5426         }
5427     }
5428     int32_t eventRet = HiSysEventWrite(
5429         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
5430         eventName, // CREATE_VIRTUAL_SCREEN, GET_DISPLAY_SNAPSHOT
5431         OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,
5432         "PID", getpid(),
5433         "UID", getuid());
5434     TLOGI(WmsLogTag::DMS, "%{public}s: Write HiSysEvent ret:%{public}d", eventName.c_str(), eventRet);
5435 }
5436 
ProxyForFreeze(const std::set<int32_t> & pidList,bool isProxy)5437 DMError ScreenSessionManager::ProxyForFreeze(const std::set<int32_t>& pidList, bool isProxy)
5438 {
5439     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5440         TLOGE(WmsLogTag::DMS, "permission denied!");
5441         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5442     }
5443     {
5444         std::lock_guard<std::mutex> lock(freezedPidListMutex_);
5445         for (auto pid : pidList) {
5446             if (isProxy) {
5447                 freezedPidList_.insert(pid);
5448             } else {
5449                 freezedPidList_.erase(pid); // set删除不存在的元素不会引发异常
5450             }
5451         }
5452     }
5453     if (isProxy) {
5454         return DMError::DM_OK;
5455     }
5456 
5457     // 进程解冻时刷新一次displaychange
5458     sptr<ScreenSession> screenSession = GetScreenSession(GetDefaultScreenId());
5459     if (!screenSession) {
5460         return DMError::DM_ERROR_NULLPTR;
5461     }
5462     auto task = [=] {
5463         NotifyUnfreezed(pidList, screenSession);
5464     };
5465     taskScheduler_->PostAsyncTask(task, "ProxyForUnFreeze NotifyDisplayChanged");
5466     return DMError::DM_OK;
5467 }
5468 
NotifyUnfreezedAgents(const int32_t & pid,const std::set<int32_t> & unfreezedPidList,const std::set<DisplayManagerAgentType> & pidAgentTypes,const sptr<ScreenSession> & screenSession)5469 void ScreenSessionManager::NotifyUnfreezedAgents(const int32_t& pid, const std::set<int32_t>& unfreezedPidList,
5470     const std::set<DisplayManagerAgentType>& pidAgentTypes, const sptr<ScreenSession>& screenSession)
5471 {
5472     bool isAgentTypeNotify = false;
5473     for (auto agentType : pidAgentTypes) {
5474         auto agents = dmAgentContainer_.GetAgentsByType(agentType);
5475         for (auto agent : agents) {
5476             int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
5477             if (agentPid != pid || unfreezedPidList.count(pid) == 0) {
5478                 continue;
5479             }
5480             isAgentTypeNotify = true;
5481             if (agentType == DisplayManagerAgentType::DISPLAY_EVENT_LISTENER) {
5482                 agent->OnDisplayChange(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_UNFREEZED);
5483             } else if (agentType == DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER) {
5484                 FoldDisplayMode displayMode = GetFoldDisplayMode();
5485                 agent->NotifyDisplayModeChanged(displayMode);
5486             } else if (agentType == DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER) {
5487                 FoldStatus foldStatus = GetFoldStatus();
5488                 agent->NotifyFoldStatusChanged(foldStatus);
5489             } else if (agentType == DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER) {
5490                 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
5491                 agent->NotifyFoldAngleChanged(lastFoldAngles_);
5492             } else if (agentType == DisplayManagerAgentType::SCREEN_EVENT_LISTENER) {
5493                 auto displayInfo = screenSession->ConvertToDisplayInfo();
5494                 auto screenInfo = GetScreenInfoById(displayInfo->GetScreenId());
5495                 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
5496                 agent->OnScreenChange(screenInfo, lastScreenChangeEvent_);
5497             } else if (agentType ==  DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER) {
5498                 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
5499                 agent->NotifyDisplayChangeInfoChanged(lastDisplayChangeInfo_);
5500             } else {
5501                 isAgentTypeNotify = false;
5502                 TLOGI(WmsLogTag::DMS, "Unknown agentType.");
5503             }
5504         }
5505         if (isAgentTypeNotify) {
5506             pidAgentTypeMap_[pid].erase(agentType);
5507         }
5508     }
5509 }
5510 
NotifyUnfreezed(const std::set<int32_t> & unfreezedPidList,const sptr<ScreenSession> & screenSession)5511 void ScreenSessionManager::NotifyUnfreezed(const std::set<int32_t>& unfreezedPidList,
5512     const sptr<ScreenSession>& screenSession)
5513 {
5514     std::lock_guard<std::mutex> lock(freezedPidListMutex_);
5515     for (auto iter = pidAgentTypeMap_.begin(); iter != pidAgentTypeMap_.end();) {
5516         int32_t pid = iter->first;
5517         auto pidAgentTypes = iter->second;
5518         NotifyUnfreezedAgents(pid, unfreezedPidList, pidAgentTypes, screenSession);
5519         if (pidAgentTypeMap_[pid].empty()) {
5520             iter = pidAgentTypeMap_.erase(iter);
5521         } else {
5522             iter++;
5523         }
5524     }
5525 }
5526 
ResetAllFreezeStatus()5527 DMError ScreenSessionManager::ResetAllFreezeStatus()
5528 {
5529     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5530         TLOGE(WmsLogTag::DMS, "permission denied!");
5531         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5532     }
5533     std::lock_guard<std::mutex> lock(freezedPidListMutex_);
5534     freezedPidList_.clear();
5535     pidAgentTypeMap_.clear();
5536     TLOGI(WmsLogTag::DMS, "freezedPidList_ has been clear.");
5537     return DMError::DM_OK;
5538 }
5539 
RegisterApplicationStateObserver()5540 void ScreenSessionManager::RegisterApplicationStateObserver()
5541 {
5542 #ifdef SENSOR_ENABLE
5543     std::string identify = IPCSkeleton::ResetCallingIdentity();
5544     FoldScreenSensorManager::GetInstance().RegisterApplicationStateObserver();
5545     IPCSkeleton::SetCallingIdentity(identify);
5546 #endif
5547 }
5548 
GetDeviceScreenConfig()5549 DeviceScreenConfig ScreenSessionManager::GetDeviceScreenConfig()
5550 {
5551     return deviceScreenConfig_;
5552 }
5553 
SetVirtualScreenBlackList(ScreenId screenId,std::vector<uint64_t> & windowIdList)5554 void ScreenSessionManager::SetVirtualScreenBlackList(ScreenId screenId, std::vector<uint64_t>& windowIdList)
5555 {
5556     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5557         TLOGE(WmsLogTag::DMS, "permission denied!");
5558         return;
5559     }
5560     TLOGI(WmsLogTag::DMS, "Enter, screenId: %{public}" PRIu64, screenId);
5561     if (windowIdList.empty()) {
5562         TLOGE(WmsLogTag::DMS, "WindowIdList is empty");
5563         return;
5564     }
5565     ScreenId rsScreenId = SCREEN_ID_INVALID;
5566     if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
5567         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
5568         return;
5569     }
5570     if (!clientProxy_) {
5571         TLOGE(WmsLogTag::DMS, "clientProxy_ is nullptr");
5572         return;
5573     }
5574     std::vector<uint64_t> surfaceNodeIds;
5575     clientProxy_->OnGetSurfaceNodeIdsFromMissionIdsChanged(windowIdList, surfaceNodeIds, true);
5576     rsInterface_.SetVirtualScreenBlackList(rsScreenId, surfaceNodeIds);
5577 }
5578 
DisablePowerOffRenderControl(ScreenId screenId)5579 void ScreenSessionManager::DisablePowerOffRenderControl(ScreenId screenId)
5580 {
5581     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5582         TLOGE(WmsLogTag::DMS, "permission denied!");
5583         return;
5584     }
5585     TLOGI(WmsLogTag::DMS, "Enter, screenId: %{public}" PRIu64, screenId);
5586     ScreenId rsScreenId = SCREEN_ID_INVALID;
5587     if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
5588         TLOGE(WmsLogTag::DMS, "No corresponding rsId");
5589         return;
5590     }
5591     rsInterface_.DisablePowerOffRenderControl(rsScreenId);
5592 }
5593 
ReportFoldStatusToScb(std::vector<std::string> & screenFoldInfo)5594 void ScreenSessionManager::ReportFoldStatusToScb(std::vector<std::string>& screenFoldInfo)
5595 {
5596     if (clientProxy_) {
5597         auto screenInfo = GetDefaultScreenSession();
5598         int32_t rotation = -1;
5599         if (screenInfo != nullptr) {
5600             rotation = static_cast<int32_t>(screenInfo->GetRotation());
5601         }
5602         screenFoldInfo.emplace_back(std::to_string(rotation));
5603 
5604         clientProxy_->OnFoldStatusChangedReportUE(screenFoldInfo);
5605     }
5606 }
5607 
GetAllDisplayPhysicalResolution()5608 std::vector<DisplayPhysicalResolution> ScreenSessionManager::GetAllDisplayPhysicalResolution()
5609 {
5610     if (allDisplayPhysicalResolution_.empty()) {
5611         sptr<ScreenSession> defaultScreen = GetDefaultScreenSession();
5612         if (defaultScreen == nullptr) {
5613             TLOGE(WmsLogTag::DMS, "default screen null");
5614             return allDisplayPhysicalResolution_;
5615         }
5616         ScreenProperty defaultScreenProperty = defaultScreen->GetScreenProperty();
5617         DisplayPhysicalResolution defaultSize;
5618         defaultSize.foldDisplayMode_ = FoldDisplayMode::UNKNOWN;
5619         defaultSize.physicalWidth_ = defaultScreenProperty.GetPhyBounds().rect_.width_;
5620         defaultSize.physicalHeight_ = defaultScreenProperty.GetPhyBounds().rect_.height_;
5621         allDisplayPhysicalResolution_.emplace_back(defaultSize);
5622     }
5623     return allDisplayPhysicalResolution_;
5624 }
5625 
SetVirtualScreenSecurityExemption(ScreenId screenId,uint32_t pid,std::vector<uint64_t> & windowIdList)5626 DMError ScreenSessionManager::SetVirtualScreenSecurityExemption(ScreenId screenId, uint32_t pid,
5627     std::vector<uint64_t>& windowIdList)
5628 {
5629     if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
5630         !SessionPermission::IsShellCall()) {
5631         TLOGE(WmsLogTag::DMS, "permission denied!");
5632         return DMError::DM_ERROR_INVALID_CALLING;
5633     }
5634     std::vector<uint64_t> surfaceNodeIds;
5635     if (!windowIdList.empty()) {
5636         MockSessionManagerService::GetInstance().GetProcessSurfaceNodeIdByPersistentId(
5637             pid, windowIdList, surfaceNodeIds);
5638     }
5639     auto rsId = screenIdManager_.ConvertToRsScreenId(screenId);
5640     auto ret = rsInterface_.SetVirtualScreenSecurityExemptionList(rsId, surfaceNodeIds);
5641 
5642     std::ostringstream oss;
5643     oss << "screenId:" << screenId << ", rsID: " << rsId << ", pid: " << pid
5644         << ", winListSize:[ ";
5645     for (auto val : windowIdList) {
5646         oss << val << " ";
5647     }
5648     oss << "]" << ", surfaceListSize:[ ";
5649     for (auto val : surfaceNodeIds) {
5650         oss << val << " ";
5651     }
5652     oss << "]" << ", ret: " << ret;
5653     TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
5654     return ret == 0 ? DMError::DM_OK : DMError::DM_ERROR_UNKNOWN;
5655 }
5656 
OnTentModeChanged(bool isTentMode)5657 void ScreenSessionManager::OnTentModeChanged(bool isTentMode)
5658 {
5659     if (!foldScreenController_) {
5660         TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
5661         return;
5662     }
5663     foldScreenController_->OnTentModeChanged(isTentMode);
5664 }
5665 
SetCoordinationFlag(bool isCoordinationFlag)5666 void ScreenSessionManager::SetCoordinationFlag(bool isCoordinationFlag)
5667 {
5668     TLOGI(WmsLogTag::DMS, "set coordination flag %{public}d", isCoordinationFlag);
5669     isCoordinationFlag_ = isCoordinationFlag;
5670 }
5671 
SetVirtualScreenMaxRefreshRate(ScreenId id,uint32_t refreshRate,uint32_t & actualRefreshRate)5672 DMError ScreenSessionManager::SetVirtualScreenMaxRefreshRate(ScreenId id, uint32_t refreshRate,
5673     uint32_t& actualRefreshRate)
5674 {
5675     if (!SessionPermission::IsSystemCalling()) {
5676         TLOGE(WmsLogTag::DMS, "permission denied! calling clientName: %{public}s, calling pid: %{public}d",
5677             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5678         return DMError::DM_ERROR_NOT_SYSTEM_APP;
5679     }
5680     TLOGI(WmsLogTag::DMS, "ID:%{public}" PRIu64", refreshRate:%{public}u, actualRefreshRate:%{public}u",
5681         id, refreshRate, actualRefreshRate);
5682     if (id == GetDefaultScreenId()) {
5683         TLOGE(WmsLogTag::DMS,
5684         "cannot set refresh rate of main screen, main screen id: %{public}" PRIu64".", GetDefaultScreenId());
5685         return DMError::DM_ERROR_INVALID_PARAM;
5686     }
5687     auto screenSession = GetScreenSession(id);
5688     if (screenSession == nullptr) {
5689         TLOGE(WmsLogTag::DMS, "screenSession is null.");
5690         return DMError::DM_ERROR_INVALID_PARAM;
5691     }
5692     ScreenId rsScreenId;
5693     if (!screenIdManager_.ConvertToRsScreenId(id, rsScreenId)) {
5694         TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
5695         return DMError::DM_ERROR_INVALID_PARAM;
5696     }
5697     int32_t res = rsInterface_.SetVirtualScreenRefreshRate(rsScreenId, refreshRate, actualRefreshRate);
5698     TLOGI(WmsLogTag::DMS, "refreshRate:%{public}u, actualRefreshRate:%{public}u", refreshRate, actualRefreshRate);
5699     if (res != StatusCode::SUCCESS) {
5700         TLOGE(WmsLogTag::DMS, "rsInterface error: %{public}d", res);
5701         return DMError::DM_ERROR_INVALID_PARAM;
5702     }
5703     screenSession->UpdateRefreshRate(actualRefreshRate);
5704     return DMError::DM_OK;
5705 }
5706 
OnScreenCaptureNotify(ScreenId mainScreenId,int32_t uid,const std::string & clientName)5707 void ScreenSessionManager::OnScreenCaptureNotify(ScreenId mainScreenId, int32_t uid, const std::string& clientName)
5708 {
5709     if (!clientProxy_) {
5710         TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
5711         return;
5712     }
5713     clientProxy_->ScreenCaptureNotify(mainScreenId, uid, clientName);
5714 }
5715 
AddPermissionUsedRecord(const std::string & permission,int32_t successCount,int32_t failCount)5716 void ScreenSessionManager::AddPermissionUsedRecord(const std::string& permission, int32_t successCount,
5717     int32_t failCount)
5718 {
5719     int32_t ret = Security::AccessToken::PrivacyKit::AddPermissionUsedRecord(IPCSkeleton::GetCallingTokenID(),
5720         permission, successCount, failCount);
5721     if (ret != 0) {
5722         TLOGW(WmsLogTag::DMS, "permission:%{public}s, successCount %{public}d, failedCount %{public}d",
5723             permission.c_str(), successCount, failCount);
5724     }
5725 }
5726 
GetScreenCapture(const CaptureOption & captureOption,DmErrorCode * errorCode)5727 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetScreenCapture(const CaptureOption& captureOption,
5728     DmErrorCode* errorCode)
5729 {
5730     TLOGI(WmsLogTag::DMS, "enter!");
5731     if (errorCode == nullptr) {
5732         TLOGE(WmsLogTag::DMS, "param is null.");
5733         return nullptr;
5734     }
5735     if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
5736         TLOGW(WmsLogTag::DMS, "capture disabled by edm!");
5737         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
5738         return nullptr;
5739     }
5740     if (!ScreenSceneConfig::IsSupportCapture()) {
5741         TLOGW(WmsLogTag::DMS, "device not support capture.");
5742         *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
5743         return nullptr;
5744     }
5745     if (!Permission::CheckCallingPermission(CUSTOM_SCREEN_CAPTURE_PERMISSION) && !SessionPermission::IsShellCall()) {
5746         TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d.",
5747             SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingRealPid());
5748         *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
5749         return nullptr;
5750     }
5751     if (captureOption.displayId_ == DISPLAY_ID_INVALID) {
5752         TLOGE(WmsLogTag::DMS, "display id invalid.");
5753         *errorCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
5754         return nullptr;
5755     }
5756     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetScreenCapture(%" PRIu64")", captureOption.displayId_);
5757     auto res = GetScreenSnapshot(captureOption.displayId_, false);
5758     AddPermissionUsedRecord(CUSTOM_SCREEN_CAPTURE_PERMISSION,
5759         static_cast<int32_t>(res != nullptr), static_cast<int32_t>(res == nullptr));
5760     if (res == nullptr) {
5761         TLOGE(WmsLogTag::DMS, "get capture null.");
5762         *errorCode = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
5763         return nullptr;
5764     }
5765     NotifyScreenshot(captureOption.displayId_);
5766     if (SessionPermission::IsBetaVersion()) {
5767         CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
5768     }
5769     *errorCode = DmErrorCode::DM_OK;
5770     isScreenShot_ = true;
5771     /* notify scb to do toast */
5772     OnScreenCaptureNotify(GetDefaultScreenId(), IPCSkeleton::GetCallingUid(), SysCapUtil::GetClientName());
5773     /* notify application capture happend */
5774     NotifyCaptureStatusChanged();
5775     return res;
5776 }
5777 
GetPrimaryDisplayInfo()5778 sptr<DisplayInfo> ScreenSessionManager::GetPrimaryDisplayInfo()
5779 {
5780     DmsXcollie dmsXcollie("DMS:GetPrimaryDisplayInfo", XCOLLIE_TIMEOUT_10S);
5781     sptr<ScreenSession> screenSession = nullptr;
5782     {
5783         std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5784         for (auto sessionIt : screenSessionMap_) {
5785             screenSession = sessionIt.second;
5786             if (screenSession == nullptr) {
5787                 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
5788                 continue;
5789             }
5790             if (!screenSession->GetIsExtend()) {
5791                 TLOGE(WmsLogTag::DMS, "find primary %{public}" PRIu64, screenSession->screenId_);
5792                 break;
5793             }
5794         }
5795     }
5796     if (screenSession == nullptr) {
5797         TLOGW(WmsLogTag::DMS, "get extend screen faild use default!");
5798         screenSession = GetScreenSession(GetDefaultScreenId());
5799     }
5800     if (screenSession) {
5801         std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
5802         sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
5803         if (displayInfo == nullptr) {
5804             TLOGI(WmsLogTag::DMS, "convert display error.");
5805             return nullptr;
5806         }
5807         displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
5808         return displayInfo;
5809     } else {
5810         TLOGE(WmsLogTag::DMS, "failed");
5811         return nullptr;
5812     }
5813 }
5814 
GetCameraStatus()5815 int32_t ScreenSessionManager::GetCameraStatus()
5816 {
5817     return cameraStatus_;
5818 }
5819 
GetCameraPosition()5820 int32_t ScreenSessionManager::GetCameraPosition()
5821 {
5822     return cameraPosition_;
5823 }
5824 } // namespace OHOS::Rosen