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