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