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