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