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 "screen_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 #include "input_manager.h"
25
26 #include <hitrace_meter.h>
27 #ifdef DEVICE_STATUS_ENABLE
28 #include <interaction_manager.h>
29 #endif // DEVICE_STATUS_ENABLE
30 #include <ipc_skeleton.h>
31 #include <parameter.h>
32 #include <parameters.h>
33 #include <privacy_kit.h>
34 #include <system_ability_definition.h>
35 #include <transaction/rs_interfaces.h>
36 #include <xcollie/watchdog.h>
37 #include <hisysevent.h>
38 #include <power_mgr_client.h>
39 #include <screen_power_utils.h>
40
41 #include "dm_common.h"
42 #include "fold_screen_state_internel.h"
43 #ifdef WM_MULTI_SCREEN_ENABLE
44 #include "multi_screen_manager.h"
45 #endif
46 #include "pipeline/rs_node_map.h"
47 #include "scene_board_judgement.h"
48 #include "session_permission.h"
49 #include "screen_scene_config.h"
50 #include "surface_capture_future.h"
51 #include "sys_cap_util.h"
52 #include "permission.h"
53 #include "window_manager_hilog.h"
54 #include "screen_rotation_property.h"
55 #include "screen_sensor_connector.h"
56 #include "screen_setting_helper.h"
57 #include "screen_session_dumper.h"
58 #include "mock_session_manager_service.h"
59 #include "connection/screen_snapshot_picker_connection.h"
60 #include "connection/screen_cast_connection.h"
61 #include "publish/screen_session_publish.h"
62 #include "dms_xcollie.h"
63 #include "screen_sensor_plugin.h"
64 #ifdef FOLD_ABILITY_ENABLE
65 #include "fold_screen_controller/super_fold_sensor_manager.h"
66 #include "fold_screen_controller/super_fold_state_manager.h"
67 #include "fold_screen_controller/secondary_fold_sensor_manager.h"
68 #include "fold_screen_controller/super_fold_policy.h"
69 #endif
70
71 namespace OHOS::Rosen {
72 namespace {
73 const std::string SCREEN_SESSION_MANAGER_THREAD = "OS_ScreenSessionManager";
74 const std::string SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD = "OS_ScreenSessionManager_ScreenPower";
75 const std::string SCREEN_CAPTURE_PERMISSION = "ohos.permission.CAPTURE_SCREEN";
76 const std::string CUSTOM_SCREEN_CAPTURE_PERMISSION = "ohos.permission.CUSTOM_SCREEN_CAPTURE";
77 const std::string BOOTEVENT_BOOT_COMPLETED = "bootevent.boot.completed";
78 const std::string ACCESS_VIRTUAL_SCREEN_PERMISSION = "ohos.permission.ACCESS_VIRTUAL_SCREEN";
79 const int32_t CV_WAIT_SCREENON_MS = 300;
80 const int32_t CV_WAIT_SCREENOFF_MS = 1500;
81 const int32_t CV_WAIT_SCREENOFF_MS_MAX = 3000;
82 const int32_t CV_WAIT_SCBSWITCH_MS = 3000;
83 #ifdef WM_MULTI_USR_ABILITY_ENABLE
84 const int64_t SWITCH_USER_DISPLAYMODE_CHANGE_DELAY = 500;
85 #endif
86 const int32_t SCREEN_OFF_MIN_DELAY_TIME = 300;
87 const int32_t SCREEN_WAIT_PICTURE_FRAME_TIME = 1500;
88 const std::string STATUS_FOLD_HALF = "-z";
89 const std::string STATUS_EXPAND = "-y";
90 const std::string STATUS_FOLD = "-p";
91 const std::string SETTING_LOCKED_KEY = "settings.general.accelerometer_rotation_status";
92 const ScreenId SCREEN_ID_DEFAULT = 0;
93 const ScreenId SCREEN_ID_FULL = 0;
94 const ScreenId SCREEN_ID_MAIN = 5;
95 const ScreenId SCREEN_ID_PC_MAIN = 9;
96 const ScreenId MINIMUM_VIRTUAL_SCREEN_ID = 1000;
97 constexpr int32_t INVALID_UID = -1;
98 constexpr int32_t INVALID_USER_ID = -1;
99 constexpr int32_t INVALID_SCB_PID = -1;
100 constexpr int32_t BASE_USER_RANGE = 200000;
101 static bool g_foldScreenFlag = system::GetParameter("const.window.foldscreen.type", "") != "";
102 static const int32_t SCREEN_ROTATION_OFFSET = system::GetIntParameter<int32_t>("const.fold.screen_rotation.offset", 0);
103 static const int32_t g_outerOnly = system::GetIntParameter<int32_t>("persist.display.outeronly", 0);
104 static const int32_t ROTATION_90 = 1;
105 static const int32_t ONLY_OUTER_SCREEN_VALUE = 1;
106 #ifdef FOLD_ABILITY_ENABLE
107 static const int32_t ROTATION_270 = 3;
108 constexpr int32_t REMOVE_DISPLAY_MODE = 0;
109 #endif
110 static const int32_t AUTO_ROTATE_OFF = 0;
111 static const int NOTIFY_EVENT_FOR_DUAL_FAILED = 0;
112 static const int NOTIFY_EVENT_FOR_DUAL_SUCESS = 1;
113 static const int NO_NEED_NOTIFY_EVENT_FOR_DUAL = 2;
114 static bool g_isPcDevice = false;
115 static uint32_t g_internalWidth = 3120;
116 const unsigned int XCOLLIE_TIMEOUT_10S = 10;
117 constexpr int32_t CAST_WIRED_PROJECTION_START = 1005;
118 constexpr int32_t CAST_WIRED_PROJECTION_STOP = 1007;
119 constexpr int32_t RES_FAILURE_FOR_PRIVACY_WINDOW = -2;
120 constexpr int32_t IRREGULAR_REFRESH_RATE_SKIP_THRETHOLD = 10;
121 #ifdef WM_MULTI_SCREEN_CTL_ABILITY_ENABLE
122 constexpr uint32_t NUMBER_OF_PHYSICAL_SCREEN = 2;
123 constexpr bool ADD_VOTE = true;
124 constexpr bool REMOVE_VOTE = false;
125 constexpr uint32_t OLED_60_HZ = 60;
126 #endif
127 constexpr uint32_t FOUR_K_WIDTH = 3840;
128 constexpr uint32_t THREE_K_WIDTH = 3000;
129 constexpr uint32_t DISPLAY_B_HEIGHT = 1608;
130
131 const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
132 constexpr int32_t FOLDABLE_DEVICE { 2 };
133 constexpr float DEFAULT_PIVOT = 0.5f;
134 constexpr float DEFAULT_SCALE = 1.0f;
135 constexpr float EXTEND_SCREEN_DPI_PARAMETER = 0.85f;
136 static const constexpr char* SET_SETTING_DPI_KEY {"default_display_dpi"};
137 const std::vector<std::string> ROTATION_DEFAULT = {"0", "1", "2", "3"};
138 const std::vector<std::string> ORIENTATION_DEFAULT = {"0", "1", "2", "3"};
139
140 const std::string SCREEN_UNKNOWN = "unknown";
141 #ifdef WM_MULTI_SCREEN_ENABLE
142 const std::string SCREEN_EXTEND = "extend";
143 const std::string SCREEN_MIRROR = "mirror";
144 const std::string MULTI_SCREEN_EXIT_STR = "exit";
145 const std::string MULTI_SCREEN_ENTER_STR = "enter";
146 #endif
147 const bool IS_COORDINATION_SUPPORT =
148 OHOS::system::GetBoolParameter("const.window.foldabledevice.is_coordination_support", false);
149
150 const std::string FAULT_DESCRIPTION = "842003014";
151 const std::string FAULT_SUGGESTION = "542003014";
152 constexpr uint32_t COMMON_EVENT_SERVICE_ID = 3299;
153
154 // based on the bundle_util
GetUserIdByCallingUid()155 inline int32_t GetUserIdByCallingUid()
156 {
157 int32_t uid = IPCSkeleton::GetCallingUid();
158 TLOGD(WmsLogTag::WMS_MULTI_USER, "get calling uid(%{public}d)", uid);
159 if (uid <= INVALID_UID) {
160 TLOGE(WmsLogTag::WMS_MULTI_USER, "uid is illegal: %{public}d", uid);
161 return INVALID_USER_ID;
162 }
163 return uid / BASE_USER_RANGE;
164 }
165 } // namespace
166
167 WM_IMPLEMENT_SINGLE_INSTANCE(ScreenSessionManager)
168
169 const bool REGISTER_RESULT = !SceneBoardJudgement::IsSceneBoardEnabled() ? false :
170 SystemAbility::MakeAndRegisterAbility(&ScreenSessionManager::GetInstance());
171
ScreenSessionManager()172 ScreenSessionManager::ScreenSessionManager()
173 : SystemAbility(DISPLAY_MANAGER_SERVICE_SA_ID, true), rsInterface_(RSInterfaces::GetInstance())
174 {
175 screenEventTracker_.RecordEvent("Dms construct.");
176 LoadScreenSceneXml();
177 screenOffDelay_ = CV_WAIT_SCREENOFF_MS;
178 screenOnDelay_ = CV_WAIT_SCREENON_MS;
179 taskScheduler_ = std::make_shared<TaskScheduler>(SCREEN_SESSION_MANAGER_THREAD);
180 screenPowerTaskScheduler_ = std::make_shared<TaskScheduler>(SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD);
181 screenCutoutController_ = new (std::nothrow) ScreenCutoutController();
182 if (!screenCutoutController_) {
183 TLOGE(WmsLogTag::DMS, "screenCutoutController_ is nullptr");
184 return;
185 }
186 sessionDisplayPowerController_ = new SessionDisplayPowerController(
187 std::bind(&ScreenSessionManager::NotifyDisplayStateChange, this,
188 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
189 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
190 g_foldScreenFlag = false;
191 }
192 if (g_foldScreenFlag) {
193 HandleFoldScreenPowerInit();
194 }
195 WatchParameter(BOOTEVENT_BOOT_COMPLETED.c_str(), BootFinishedCallback, this);
196 }
197
ConvertOffsetToCorrectRotation(int32_t phyOffset)198 ScreenRotation ScreenSessionManager::ConvertOffsetToCorrectRotation(int32_t phyOffset)
199 {
200 ScreenRotation offsetRotation = ScreenRotation::ROTATION_0;
201 switch (phyOffset) {
202 case 90: // Rotation 90 degree
203 offsetRotation = ScreenRotation::ROTATION_270;
204 break;
205 case 180: // Rotation 180 degree
206 offsetRotation = ScreenRotation::ROTATION_180;
207 break;
208 case 270: // Rotation 270 degree
209 offsetRotation = ScreenRotation::ROTATION_90;
210 break;
211 default:
212 offsetRotation = ScreenRotation::ROTATION_0;
213 break;
214 }
215 return offsetRotation;
216 }
217
HandleFoldScreenPowerInit()218 void ScreenSessionManager::HandleFoldScreenPowerInit()
219 {
220 #ifdef FOLD_ABILITY_ENABLE
221 TLOGI(WmsLogTag::DMS, "Enter");
222 foldScreenController_ = new (std::nothrow) FoldScreenController(displayInfoMutex_, screenPowerTaskScheduler_);
223 if (!foldScreenController_) {
224 TLOGE(WmsLogTag::DMS, "foldScreenController_ is nullptr");
225 return;
226 }
227 foldScreenController_->SetOnBootAnimation(true);
228 if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
229 SetFoldScreenPowerInit([&]() {
230 foldScreenController_->BootAnimationFinishPowerInit();
231 FixPowerStatus();
232 foldScreenController_->SetOnBootAnimation(false);
233 RegisterApplicationStateObserver();
234 });
235 } else {
236 // 后续其他设备rs上电规格将陆续迁移到BootAnimationFinishPowerInit中
237 FoldScreenPowerInit();
238 }
239 #endif
240 }
241
IsSupportCoordination()242 bool ScreenSessionManager::IsSupportCoordination()
243 {
244 return !FoldScreenStateInternel::IsDualDisplayFoldDevice() || IS_COORDINATION_SUPPORT;
245 }
246
FoldScreenPowerInit()247 void ScreenSessionManager::FoldScreenPowerInit()
248 {
249 #ifdef FOLD_ABILITY_ENABLE
250 SetFoldScreenPowerInit([&]() {
251 int64_t timeStamp = 50;
252 #ifdef TP_FEATURE_ENABLE
253 int32_t tpType = 12;
254 std::string fullTpChange = "0";
255 std::string mainTpChange = "1";
256 #endif
257 if (!foldScreenController_) {
258 TLOGE(WmsLogTag::DMS, "foldScreenController_ is nullptr");
259 return;
260 }
261 ScreenId currentScreenId = foldScreenController_->GetCurrentScreenId();
262 if (currentScreenId == SCREEN_ID_FULL) {
263 TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Full animation Init 1.");
264 rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF_FAKE);
265 if (IsSupportCoordination()) {
266 rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
267 }
268 std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
269 TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Full animation Init 2.");
270 #ifdef TP_FEATURE_ENABLE
271 rsInterface_.SetTpFeatureConfig(tpType, fullTpChange.c_str());
272 #endif
273 if (IsSupportCoordination()) {
274 rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
275 }
276 foldScreenController_->AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, REMOVE_DISPLAY_MODE);
277 rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
278 } else if (currentScreenId == SCREEN_ID_MAIN) {
279 TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Main animation Init 3.");
280 rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF_FAKE);
281 if (IsSupportCoordination()) {
282 rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
283 }
284 std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
285 TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Main animation Init 4.");
286 #ifdef TP_FEATURE_ENABLE
287 rsInterface_.SetTpFeatureConfig(tpType, mainTpChange.c_str());
288 #endif
289 if (IsSupportCoordination()) {
290 rsInterface_.SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
291 }
292 foldScreenController_->AddOrRemoveDisplayNodeToTree(SCREEN_ID_FULL, REMOVE_DISPLAY_MODE);
293 rsInterface_.SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
294 } else {
295 TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Init, invalid active screen id");
296 }
297 FixPowerStatus();
298 foldScreenController_->SetOnBootAnimation(false);
299 RegisterApplicationStateObserver();
300 });
301 #endif
302 }
303
FixPowerStatus()304 void ScreenSessionManager::FixPowerStatus()
305 {
306 if (!PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
307 PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
308 TLOGI(WmsLogTag::DMS, "Fix Screen Power State");
309 }
310 }
311
Init()312 void ScreenSessionManager::Init()
313 {
314 if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none") {
315 g_isPcDevice = true;
316 }
317 if (system::GetParameter("soc.boot.mode", "") != "rescue") {
318 uint64_t interval = g_isPcDevice ? 10 * 1000 : 5 * 1000; // 10 second for PC
319 if (HiviewDFX::Watchdog::GetInstance().AddThread(
320 SCREEN_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
321 TLOGW(WmsLogTag::DMS, "Add thread %{public}s to watchdog failed.", SCREEN_SESSION_MANAGER_THREAD.c_str());
322 }
323
324 if (HiviewDFX::Watchdog::GetInstance().AddThread(
325 SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD, screenPowerTaskScheduler_->GetEventHandler(), interval)) {
326 TLOGW(WmsLogTag::DMS, "Add thread %{public}s to watchdog failed.",
327 SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD.c_str());
328 }
329 } else {
330 TLOGI(WmsLogTag::DMS, "Dms in rescue mode, not need watchdog.");
331 screenEventTracker_.RecordEvent("Dms in rescue mode, not need watchdog.");
332 }
333
334 auto stringConfig = ScreenSceneConfig::GetStringConfig();
335 if (stringConfig.count("defaultDisplayCutoutPath") != 0) {
336 std::string defaultDisplayCutoutPath = static_cast<std::string>(stringConfig["defaultDisplayCutoutPath"]);
337 TLOGD(WmsLogTag::DMS, "defaultDisplayCutoutPath = %{public}s.", defaultDisplayCutoutPath.c_str());
338 ScreenSceneConfig::SetCutoutSvgPath(GetDefaultScreenId(), defaultDisplayCutoutPath);
339 }
340
341 if (!LoadMotionSensor()) {
342 screenEventTracker_.RecordEvent("Dms load motion plugin failed.");
343 TLOGW(WmsLogTag::DMS, "load motion plugin failed.");
344 }
345
346 RegisterScreenChangeListener();
347 if (!ScreenSceneConfig::IsSupportRotateWithSensor()) {
348 TLOGI(WmsLogTag::DMS, "Current type not support SetSensorSubscriptionEnabled.");
349 } else if (GetScreenPower(SCREEN_ID_FULL) == ScreenPowerState::POWER_ON) {
350 // 多屏设备只要有屏幕亮,GetScreenPower获取的任意一块屏幕状态均是ON
351 SetSensorSubscriptionEnabled();
352 screenEventTracker_.RecordEvent("Dms subscribed to sensor successfully.");
353 }
354
355 // publish init
356 ScreenSessionPublish::GetInstance().InitPublishEvents();
357 screenEventTracker_.RecordEvent("Dms init end.");
358 }
359
OnStart()360 void ScreenSessionManager::OnStart()
361 {
362 TLOGI(WmsLogTag::DMS, "start");
363 DmsXcollie dmsXcollie("DMS:OnStart", XCOLLIE_TIMEOUT_10S,
364 [this](void *) { screenEventTracker_.LogWarningAllInfos(); });
365 Init();
366 sptr<ScreenSessionManager> dms(this);
367 dms->IncStrongRef(nullptr);
368 if (!Publish(dms)) {
369 TLOGE(WmsLogTag::DMS, "Publish DMS failed");
370 return;
371 }
372 TLOGI(WmsLogTag::DMS, "DMS SA AddSystemAbilityListener");
373 (void)AddSystemAbilityListener(SENSOR_SERVICE_ABILITY_ID);
374 (void)AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
375 screenEventTracker_.RecordEvent("Dms AddSystemAbilityListener finished.");
376 TLOGI(WmsLogTag::DMS, "end");
377 screenEventTracker_.RecordEvent("Dms onstart end.");
378 }
379
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)380 void ScreenSessionManager::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
381 {
382 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "OnAddSystemAbility: %d", systemAbilityId);
383 TLOGI(WmsLogTag::DMS, "receive sa add:%{public}d", systemAbilityId);
384 if (systemAbilityId == SENSOR_SERVICE_ABILITY_ID) {
385 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
386 if (!g_foldScreenFlag) {
387 TLOGI(WmsLogTag::DMS, "current device is not fold phone.");
388 return;
389 }
390 if (!foldScreenController_ || isFoldScreenOuterScreenReady_) {
391 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null or outer screen is not ready.");
392 return;
393 }
394 if (GetDisplayState(foldScreenController_->GetCurrentScreenId()) == DisplayState::ON) {
395 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
396 SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
397 } else {
398 FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
399 }
400 TLOGI(WmsLogTag::DMS, "Recover Posture sensor finished");
401 }
402
403 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
404 SecondaryFoldSensorManager::GetInstance().RegisterHallCallback();
405 } else {
406 FoldScreenSensorManager::GetInstance().RegisterHallCallback();
407 }
408 TLOGI(WmsLogTag::DMS, "Recover Hall sensor finished");
409 screenEventTracker_.RecordEvent("Dms recover Posture and Hall sensor finished.");
410 #endif
411 } else if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
412 auto task = []() {
413 ScreenSessionPublish::GetInstance().RegisterLowTempSubscriber();
414 ScreenSessionPublish::GetInstance().RegisterUserSwitchedSubscriber();
415 };
416 taskScheduler_->PostAsyncTask(task, "RegisterCommonEventSubscriber");
417 }
418 }
419
CheckDisplayMangerAgentTypeAndPermission(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)420 DMError ScreenSessionManager::CheckDisplayMangerAgentTypeAndPermission(
421 const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
422 {
423 if ((type == DisplayManagerAgentType::SCREEN_EVENT_LISTENER ||
424 type == DisplayManagerAgentType::PRIVATE_WINDOW_LISTENER) &&
425 !SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
426 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
427 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
428 return DMError::DM_ERROR_NOT_SYSTEM_APP;
429 }
430
431 if ((displayManagerAgent == nullptr) || (displayManagerAgent->AsObject() == nullptr)) {
432 TLOGE(WmsLogTag::DMS, "displayManagerAgent invalid");
433 return DMError::DM_ERROR_NULLPTR;
434 }
435 return DMError::DM_OK;
436 }
437
RegisterDisplayManagerAgent(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)438 DMError ScreenSessionManager::RegisterDisplayManagerAgent(
439 const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
440 {
441 TLOGI(WmsLogTag::DMS, " called type: %{public}u", type);
442 DmsXcollie dmsXcollie("DMS:RegisterDisplayManagerAgent", XCOLLIE_TIMEOUT_10S);
443 DMError ret;
444
445 ret = CheckDisplayMangerAgentTypeAndPermission(displayManagerAgent, type);
446 if (ret != DMError::DM_OK) {
447 TLOGE(WmsLogTag::DMS, "call CheckDisplayMangerAgentTypeAndPermission fail!");
448 return ret;
449 }
450
451 if (type < DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER
452 || type >= DisplayManagerAgentType::DISPLAY_MANAGER_MAX_AGENT_TYPE) {
453 TLOGE(WmsLogTag::DMS, "DisplayManagerAgentType: %{public}u", static_cast<uint32_t>(type));
454 return DMError::DM_ERROR_INVALID_PARAM;
455 }
456 return dmAgentContainer_.RegisterAgent(displayManagerAgent, type) ? DMError::DM_OK :DMError::DM_ERROR_NULLPTR;
457 }
458
UnregisterDisplayManagerAgent(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)459 DMError ScreenSessionManager::UnregisterDisplayManagerAgent(
460 const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
461 {
462 TLOGI(WmsLogTag::DMS, " called type: %{public}u", type);
463 DMError ret;
464
465 ret = CheckDisplayMangerAgentTypeAndPermission(displayManagerAgent, type);
466 if (ret != DMError::DM_OK) {
467 TLOGE(WmsLogTag::DMS, "call CheckDisplayMangerAgentTypeAndPermission fail!");
468 return ret;
469 }
470 return dmAgentContainer_.UnregisterAgent(displayManagerAgent, type) ? DMError::DM_OK :DMError::DM_ERROR_NULLPTR;
471 }
472
LoadScreenSceneXml()473 void ScreenSessionManager::LoadScreenSceneXml()
474 {
475 if (ScreenSceneConfig::LoadConfigXml()) {
476 ScreenSceneConfig::DumpConfig();
477 ConfigureScreenScene();
478 }
479 }
480
ConfigureScreenScene()481 void ScreenSessionManager::ConfigureScreenScene()
482 {
483 auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
484 auto enableConfig = ScreenSceneConfig::GetEnableConfig();
485 auto stringConfig = ScreenSceneConfig::GetStringConfig();
486 ConfigureDpi();
487 if (numbersConfig.count("defaultDeviceRotationOffset") != 0) {
488 defaultDeviceRotationOffset_ = static_cast<uint32_t>(numbersConfig["defaultDeviceRotationOffset"][0]);
489 TLOGD(WmsLogTag::DMS, "defaultDeviceRotationOffset = %{public}u", defaultDeviceRotationOffset_);
490 }
491 if (enableConfig.count("isWaterfallDisplay") != 0) {
492 bool isWaterfallDisplay = static_cast<bool>(enableConfig["isWaterfallDisplay"]);
493 TLOGD(WmsLogTag::DMS, "isWaterfallDisplay = %{public}d", isWaterfallDisplay);
494 }
495 if (numbersConfig.count("curvedScreenBoundary") != 0) {
496 std::vector<int> vtBoundary = static_cast<std::vector<int>>(numbersConfig["curvedScreenBoundary"]);
497 TLOGD(WmsLogTag::DMS, "vtBoundary.size=%{public}u", static_cast<uint32_t>(vtBoundary.size()));
498 }
499 if (stringConfig.count("subDisplayCutoutPath") != 0) {
500 std::string subDisplayCutoutPath = stringConfig["subDisplayCutoutPath"];
501 TLOGD(WmsLogTag::DMS, "subDisplayCutoutPath = %{public}s.", subDisplayCutoutPath.c_str());
502 ScreenSceneConfig::SetSubCutoutSvgPath(subDisplayCutoutPath);
503 }
504 if (stringConfig.count("rotationPolicy") != 0) {
505 std::string rotationPolicy = stringConfig["rotationPolicy"];
506 TLOGD(WmsLogTag::DMS, "rotationPolicy = %{public}s.", rotationPolicy.c_str());
507 deviceScreenConfig_.rotationPolicy_ = rotationPolicy;
508 }
509 if (stringConfig.count("defaultRotationPolicy") != 0) {
510 std::string defaultRotationPolicy = stringConfig["defaultRotationPolicy"];
511 TLOGD(WmsLogTag::DMS, "defaultRotationPolicy = %{public}s.", defaultRotationPolicy.c_str());
512 deviceScreenConfig_.defaultRotationPolicy_ = defaultRotationPolicy;
513 }
514 if (enableConfig.count("isRightPowerButton") != 0) {
515 bool isRightPowerButton = static_cast<bool>(enableConfig["isRightPowerButton"]);
516 TLOGD(WmsLogTag::DMS, "isRightPowerButton = %{public}d", isRightPowerButton);
517 deviceScreenConfig_.isRightPowerButton_ = isRightPowerButton;
518 }
519 ConfigureWaterfallDisplayCompressionParams();
520 ConfigureCastParams();
521
522 if (numbersConfig.count("buildInDefaultOrientation") != 0) {
523 Orientation orientation = static_cast<Orientation>(numbersConfig["buildInDefaultOrientation"][0]);
524 TLOGD(WmsLogTag::DMS, "orientation = %{public}d", orientation);
525 }
526 allDisplayPhysicalResolution_ = ScreenSceneConfig::GetAllDisplayPhysicalConfig();
527 }
528
ConfigureDpi()529 void ScreenSessionManager::ConfigureDpi()
530 {
531 auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
532 if (numbersConfig.count("dpi") != 0) {
533 uint32_t densityDpi = static_cast<uint32_t>(numbersConfig["dpi"][0]);
534 TLOGI(WmsLogTag::DMS, "densityDpi = %{public}u", densityDpi);
535 if (densityDpi >= DOT_PER_INCH_MINIMUM_VALUE && densityDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
536 isDensityDpiLoad_ = true;
537 defaultDpi = densityDpi;
538 cachedSettingDpi_ = defaultDpi;
539 densityDpi_ = static_cast<float>(densityDpi) / BASELINE_DENSITY;
540 }
541 }
542 if (numbersConfig.count("subDpi") != 0) {
543 uint32_t subDensityDpi = static_cast<uint32_t>(numbersConfig["subDpi"][0]);
544 TLOGI(WmsLogTag::DMS, "subDensityDpi = %{public}u", subDensityDpi);
545 if (subDensityDpi >= DOT_PER_INCH_MINIMUM_VALUE && subDensityDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
546 isDensityDpiLoad_ = true;
547 subDensityDpi_ = static_cast<float>(subDensityDpi) / BASELINE_DENSITY;
548 }
549 }
550 }
551
ConfigureCastParams()552 void ScreenSessionManager::ConfigureCastParams()
553 {
554 auto stringConfig = ScreenSceneConfig::GetStringConfig();
555 if (stringConfig.count("castBundleName") == 0) {
556 TLOGE(WmsLogTag::DMS, "not find cast bundleName in config xml");
557 return;
558 }
559 std::string castBundleName = static_cast<std::string>(stringConfig["castBundleName"]);
560 TLOGD(WmsLogTag::DMS, "castBundleName = %{public}s", castBundleName.c_str());
561 ScreenCastConnection::GetInstance().SetBundleName(castBundleName);
562 if (stringConfig.count("castAbilityName") == 0) {
563 TLOGE(WmsLogTag::DMS, "not find cast ability in config xml");
564 return;
565 }
566 std::string castAbilityName = static_cast<std::string>(stringConfig["castAbilityName"]);
567 TLOGD(WmsLogTag::DMS, "castAbilityName = %{public}s", castAbilityName.c_str());
568 ScreenCastConnection::GetInstance().SetAbilityName(castAbilityName);
569 }
570
ConfigureWaterfallDisplayCompressionParams()571 void ScreenSessionManager::ConfigureWaterfallDisplayCompressionParams()
572 {
573 auto enableConfig = ScreenSceneConfig::GetEnableConfig();
574 if (enableConfig.count("isWaterfallAreaCompressionEnableWhenHorizontal") != 0) {
575 bool enable = static_cast<bool>(enableConfig["isWaterfallAreaCompressionEnableWhenHorizontal"]);
576 TLOGD(WmsLogTag::DMS, "isWaterfallAreaCompressionEnableWhenHorizontal=%{public}d.", enable);
577 }
578 ScreenSceneConfig::SetCurvedCompressionAreaInLandscape();
579 }
580
ConfigureScreenSnapshotParams()581 void ScreenSessionManager::ConfigureScreenSnapshotParams()
582 {
583 auto stringConfig = ScreenSceneConfig::GetStringConfig();
584 if (stringConfig.count("screenSnapshotBundleName") == 0) {
585 TLOGE(WmsLogTag::DMS, "not find screen snapshot bundleName in config xml");
586 return;
587 }
588 std::string screenSnapshotBundleName = static_cast<std::string>(stringConfig["screenSnapshotBundleName"]);
589 TLOGD(WmsLogTag::DMS, "screenSnapshotBundleName = %{public}s.", screenSnapshotBundleName.c_str());
590 ScreenSnapshotPickerConnection::GetInstance().SetBundleName(screenSnapshotBundleName);
591 if (stringConfig.count("screenSnapshotAbilityName") == 0) {
592 TLOGE(WmsLogTag::DMS, "not find screen snapshot ability in config xml");
593 return;
594 }
595 std::string screenSnapshotAbilityName = static_cast<std::string>(stringConfig["screenSnapshotAbilityName"]);
596 TLOGD(WmsLogTag::DMS, "screenSnapshotAbilityName = %{public}s.", screenSnapshotAbilityName.c_str());
597 ScreenSnapshotPickerConnection::GetInstance().SetAbilityName(screenSnapshotAbilityName);
598 }
599
RegisterScreenChangeListener()600 void ScreenSessionManager::RegisterScreenChangeListener()
601 {
602 TLOGI(WmsLogTag::DMS, "start");
603 auto res = rsInterface_.SetScreenChangeCallback(
604 [this](ScreenId screenId, ScreenEvent screenEvent, ScreenChangeReason reason) {
605 OnScreenChange(screenId, screenEvent, reason);
606 });
607 if (res != StatusCode::SUCCESS) {
608 auto task = [this]() { RegisterScreenChangeListener(); };
609 taskScheduler_->PostAsyncTask(task, "RegisterScreenChangeListener", 50); // Retry after 50 ms.
610 screenEventTracker_.RecordEvent("Dms OnScreenChange register failed.");
611 } else {
612 screenEventTracker_.RecordEvent("Dms OnScreenChange register success.");
613 }
614 }
615
RegisterRefreshRateChangeListener()616 void ScreenSessionManager::RegisterRefreshRateChangeListener()
617 {
618 static bool isRegisterRefreshRateListener = false;
619 if (!isRegisterRefreshRateListener) {
620 TLOGW(WmsLogTag::DMS, "call rsInterface_ RegisterHgmRefreshRateUpdateCallback");
621 auto res = rsInterface_.RegisterHgmRefreshRateUpdateCallback(
622 [this](uint32_t refreshRate) { OnHgmRefreshRateChange(refreshRate); });
623 TLOGW(WmsLogTag::DMS, "call rsInterface_ RegisterHgmRefreshRateUpdateCallback end");
624 if (res != StatusCode::SUCCESS) {
625 TLOGE(WmsLogTag::DMS, "failed");
626 screenEventTracker_.RecordEvent("Dms RefreshRateChange register failed.");
627 } else {
628 isRegisterRefreshRateListener = true;
629 screenEventTracker_.RecordEvent("Dms RefreshRateChange register success.");
630 }
631 }
632 }
633
OnVirtualScreenChange(ScreenId screenId,ScreenEvent screenEvent)634 void ScreenSessionManager::OnVirtualScreenChange(ScreenId screenId, ScreenEvent screenEvent)
635 {
636 TLOGI(WmsLogTag::DMS, "Notify scb virtual screen change, ScreenId: %{public}" PRIu64 ", ScreenEvent: %{public}d",
637 screenId, static_cast<int>(screenEvent));
638 auto screenSession = GetScreenSession(screenId);
639 if (!screenSession) {
640 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
641 return;
642 }
643 if (screenEvent == ScreenEvent::CONNECTED) {
644 if (clientProxy_) {
645 clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId),
646 ScreenEvent::CONNECTED);
647 }
648 return;
649 }
650 if (screenEvent == ScreenEvent::DISCONNECTED) {
651 if (clientProxy_) {
652 clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId),
653 ScreenEvent::DISCONNECTED);
654 }
655 }
656 }
657
IsDefaultMirrorMode(ScreenId screenId)658 bool ScreenSessionManager::IsDefaultMirrorMode(ScreenId screenId)
659 {
660 if (screenId != SCREEN_ID_MAIN && screenId != SCREEN_ID_FULL && screenId != SCREEN_ID_PC_MAIN) {
661 return true;
662 }
663 return false;
664 }
665
FreeDisplayMirrorNodeInner(const sptr<ScreenSession> mirrorSession)666 void ScreenSessionManager::FreeDisplayMirrorNodeInner(const sptr<ScreenSession> mirrorSession)
667 {
668 if (mirrorSession == nullptr) {
669 return;
670 }
671 {
672 std::shared_ptr<RSDisplayNode> displayNode = mirrorSession->GetDisplayNode();
673 if (displayNode == nullptr) {
674 return;
675 }
676 if (!g_isPcDevice) {
677 hdmiScreenCount_ = hdmiScreenCount_ > 0 ? hdmiScreenCount_ - 1 : 0;
678 NotifyCaptureStatusChanged();
679 }
680 displayNode->RemoveFromTree();
681 mirrorSession->ReleaseDisplayNode();
682 displayNode = nullptr;
683 }
684 auto transactionProxy = RSTransactionProxy::GetInstance();
685 if (transactionProxy != nullptr) {
686 TLOGI(WmsLogTag::DMS, "free displayNode");
687 transactionProxy->FlushImplicitTransaction();
688 }
689 }
690
SetScreenCorrection()691 void ScreenSessionManager::SetScreenCorrection()
692 {
693 std::ostringstream oss;
694 if (g_foldScreenFlag) {
695 if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
696 auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_MAIN,
697 static_cast<ScreenRotation>(ROTATION_90));
698 oss << "main screenRotationOffSet: " << SCREEN_ROTATION_OFFSET << " ret value: " << ret;
699 } else {
700 auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_FULL,
701 static_cast<ScreenRotation>(SCREEN_ROTATION_OFFSET));
702 oss << "full screenRotationOffSet: " << SCREEN_ROTATION_OFFSET << " ret value: " << ret;
703 }
704 } else {
705 std::vector<std::string> phyOffsets = FoldScreenStateInternel::GetPhyRotationOffset();
706 int32_t phyOffset = static_cast<int32_t>(std::stoi(phyOffsets[0]));
707 ScreenRotation correctRotation = ConvertOffsetToCorrectRotation(phyOffset);
708 auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_DEFAULT, correctRotation);
709 oss << "phyOffset: " << phyOffset << " correctRotation value: " <<
710 static_cast<int32_t>(correctRotation) << " ret value: " << ret;
711 }
712 TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
713 screenEventTracker_.RecordEvent(oss.str());
714 }
715
OnScreenChange(ScreenId screenId,ScreenEvent screenEvent,ScreenChangeReason reason)716 void ScreenSessionManager::OnScreenChange(ScreenId screenId, ScreenEvent screenEvent, ScreenChangeReason reason)
717 {
718 if (reason == ScreenChangeReason::HWCDEAD) {
719 NotifyAbnormalScreenConnectChange(screenId);
720 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " ScreenChangeReason: %{public}d",
721 screenId, static_cast<int>(reason));
722 return;
723 }
724 std::ostringstream oss;
725 oss << "OnScreenChange triggered. screenId: " << static_cast<int32_t>(screenId)
726 << " screenEvent: " << static_cast<int32_t>(screenEvent);
727 screenEventTracker_.RecordEvent(oss.str());
728 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " screenEvent: %{public}d",
729 screenId, static_cast<int>(screenEvent));
730 SetScreenCorrection();
731 auto screenSession = GetOrCreateScreenSession(screenId);
732 if (!screenSession) {
733 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
734 return;
735 }
736 #ifdef FOLD_ABILITY_ENABLE
737 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
738 SuperFoldSensorManager::GetInstance().RegisterPostureCallback();
739 SuperFoldSensorManager::GetInstance().RegisterHallCallback();
740 SetSensorSubscriptionEnabled();
741 screenEventTracker_.RecordEvent("Dms subscribed to sensor successfully.");
742 }
743
744 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
745 SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
746 SecondaryFoldSensorManager::GetInstance().RegisterHallCallback();
747 SetSensorSubscriptionEnabled();
748 screenEventTracker_.RecordEvent("secondary device: Dms subscribed to sensor successfully.");
749 }
750
751 if (foldScreenController_ != nullptr) {
752 screenSession->SetFoldScreen(true);
753 }
754 #endif
755 if (screenEvent == ScreenEvent::CONNECTED) {
756 connectScreenNumber_ ++;
757 HandleScreenConnectEvent(screenSession, screenId, screenEvent);
758 } else if (screenEvent == ScreenEvent::DISCONNECTED) {
759 connectScreenNumber_ --;
760 HandleScreenDisconnectEvent(screenSession, screenId, screenEvent);
761 } else {
762 TLOGE(WmsLogTag::DMS, "screenEvent error!");
763 }
764 NotifyScreenModeChange();
765 }
766
NotifyScreenModeChange(ScreenId disconnectedScreenId)767 void ScreenSessionManager::NotifyScreenModeChange(ScreenId disconnectedScreenId)
768 {
769 auto task = [=] {
770 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER);
771 if (agents.empty()) {
772 return;
773 }
774 std::vector<sptr<ScreenInfo>> screenInfos;
775 std::vector<ScreenId> screenIds = GetAllScreenIds();
776 for (auto screenId : screenIds) {
777 if (disconnectedScreenId == screenId) {
778 continue;
779 }
780 TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64, screenId);
781 auto screenSession = GetScreenSession(screenId);
782 screenInfos.emplace_back(screenSession->ConvertToScreenInfo());
783 }
784 for (auto& agent : agents) {
785 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
786 if (!IsFreezed(agentPid, DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER)) {
787 agent->NotifyScreenModeChange(screenInfos);
788 }
789 }
790 };
791 taskScheduler_->PostAsyncTask(task, "NotifyScreenModeChange");
792 }
793
NotifyAbnormalScreenConnectChange(ScreenId screenId)794 void ScreenSessionManager::NotifyAbnormalScreenConnectChange(ScreenId screenId)
795 {
796 auto agents = dmAgentContainer_.GetAgentsByType(
797 DisplayManagerAgentType::ABNORMAL_SCREEN_CONNECT_CHANGE_LISTENER);
798 if (agents.empty()) {
799 TLOGE(WmsLogTag::DMS, "agents is empty");
800 return;
801 }
802 for (auto& agent : agents) {
803 agent->NotifyAbnormalScreenConnectChange(screenId);
804 }
805 }
806
SendCastEvent(const bool & isPlugIn)807 void ScreenSessionManager::SendCastEvent(const bool &isPlugIn)
808 {
809 TLOGI(WmsLogTag::DMS, "isPlugIn:%{public}d", isPlugIn);
810 if (!ScreenCastConnection::GetInstance().CastConnectExtension(static_cast<int32_t>(isPlugIn))) {
811 TLOGE(WmsLogTag::DMS, "CastConnectionExtension failed");
812 return;
813 }
814 if (!ScreenCastConnection::GetInstance().IsConnectedSync()) {
815 TLOGE(WmsLogTag::DMS, "CastConnectionExtension connected failed");
816 ScreenCastConnection::GetInstance().CastDisconnectExtension();
817 return;
818 }
819 MessageParcel data;
820 MessageParcel reply;
821 if (isPlugIn) {
822 ScreenCastConnection::GetInstance().SendMessageToCastService(CAST_WIRED_PROJECTION_START, data, reply);
823 } else {
824 ScreenCastConnection::GetInstance().SendMessageToCastService(CAST_WIRED_PROJECTION_STOP, data, reply);
825 }
826 ScreenCastConnection::GetInstance().CastDisconnectExtension();
827 }
828
NotifyCastWhenScreenConnectChange(bool isConnected)829 void ScreenSessionManager::NotifyCastWhenScreenConnectChange(bool isConnected)
830 {
831 if (g_isPcDevice) {
832 TLOGI(WmsLogTag::DMS, "pc device");
833 return;
834 }
835 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
836 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
837 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
838 return;
839 }
840 if (isConnected) {
841 auto task = [this]() {
842 SendCastEvent(true);
843 ScreenSessionPublish::GetInstance().PublishCastPlugInEvent();
844 };
845 taskScheduler_->PostAsyncTask(task, "SendCastEventTrue");
846 TLOGI(WmsLogTag::DMS, "PostAsyncTask SendCastEventTrue");
847 } else {
848 auto task = [this]() {
849 SendCastEvent(false);
850 ScreenSessionPublish::GetInstance().PublishCastPlugOutEvent();
851 };
852 taskScheduler_->PostAsyncTask(task, "SendCastEventFalse");
853 TLOGI(WmsLogTag::DMS, "PostAsyncTask SendCastEventFalse");
854 }
855 }
856
PhyMirrorConnectWakeupScreen()857 void ScreenSessionManager::PhyMirrorConnectWakeupScreen()
858 {
859 #ifdef WM_MULTI_SCREEN_ENABLE
860 if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "mirror") {
861 TLOGI(WmsLogTag::DMS, "Connect to an external screen to wakeup the phone screen");
862 FixPowerStatus();
863 }
864 #endif
865 }
866
GetIsCurrentInUseById(ScreenId screenId)867 bool ScreenSessionManager::GetIsCurrentInUseById(ScreenId screenId)
868 {
869 auto session = GetScreenSession(screenId);
870 if (session == nullptr) {
871 TLOGE(WmsLogTag::DMS, "session not found");
872 return false;
873 }
874 if (!session->GetIsCurrentInUse()) {
875 TLOGE(WmsLogTag::DMS, "session not in use");
876 return false;
877 }
878 return true;
879 }
880
SetMultiScreenDefaultRelativePosition()881 void ScreenSessionManager::SetMultiScreenDefaultRelativePosition()
882 {
883 #ifdef WM_MULTI_SCREEN_ENABLE
884 MultiScreenPositionOptions mainOptions;
885 MultiScreenPositionOptions extendOptions;
886 sptr<ScreenSession> mainSession = nullptr;
887 sptr<ScreenSession> extendSession = nullptr;
888 for (auto sessionIt : screenSessionMap_) {
889 auto screenSession = sessionIt.second;
890 if (screenSession == nullptr) {
891 TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64,
892 sessionIt.first);
893 continue;
894 }
895 if (screenSession->GetIsRealScreen()) {
896 if (screenSession->GetIsExtend() && extendSession == nullptr) {
897 extendSession = screenSession;
898 } else {
899 mainSession = screenSession;
900 }
901 }
902 }
903 if (extendSession != nullptr && mainSession != nullptr) {
904 ScreenProperty mainProperty = mainSession->GetScreenProperty();
905 int32_t mainWidth = mainProperty.GetBounds().rect_.GetWidth();
906 int32_t mainHeight = mainProperty.GetBounds().rect_.GetHeight();
907 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && GetIsExtendScreenConnected() &&
908 mainHeight > mainWidth) {
909 mainWidth = mainHeight;
910 }
911 mainOptions = { mainSession->GetScreenId(), 0, 0 };
912 extendOptions = { extendSession->GetScreenId(), mainWidth, 0 };
913 auto ret = SetMultiScreenRelativePosition(mainOptions, extendOptions);
914 if (ret != DMError::DM_OK) {
915 TLOGE(WmsLogTag::DMS, "set Relative Position failed, DMError:%{public}d", static_cast<int32_t>(ret));
916 }
917 }
918 #endif
919 }
920
GetAndMergeEdidInfo(sptr<ScreenSession> screenSession)921 void ScreenSessionManager::GetAndMergeEdidInfo(sptr<ScreenSession> screenSession)
922 {
923 ScreenId screenId = screenSession->GetScreenId();
924 struct BaseEdid edid;
925 if (!GetEdid(screenId, edid)) {
926 TLOGE(WmsLogTag::DMS, "get EDID failed.");
927 return;
928 }
929 std::string serialNumber = ConvertEdidToString(edid);
930 screenSession->SetSerialNumber(serialNumber);
931 if (g_isPcDevice) {
932 screenSession->SetName(edid.manufacturerName_ + std::to_string(screenSession->GetScreenId()));
933 }
934 }
935
ConvertEdidToString(const struct BaseEdid edid)936 std::string ScreenSessionManager::ConvertEdidToString(const struct BaseEdid edid)
937 {
938 std::string edidInfo = "_";
939 edidInfo = edidInfo + std::to_string(edid.serialNumber_);
940 return edidInfo;
941 }
942
RecoverRestoredMultiScreenMode(sptr<ScreenSession> screenSession)943 bool ScreenSessionManager::RecoverRestoredMultiScreenMode(sptr<ScreenSession> screenSession)
944 {
945 #ifdef WM_MULTI_SCREEN_ENABLE
946 if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL) {
947 TLOGI(WmsLogTag::DMS, "not real screen, no need recover");
948 return true;
949 }
950 std::map<std::string, MultiScreenInfo> multiScreenInfoMap = ScreenSettingHelper::GetMultiScreenInfo();
951 if (multiScreenInfoMap.empty()) {
952 TLOGE(WmsLogTag::DMS, "no restored screen, use default mode!");
953 return false;
954 }
955 std::string serialNumber = screenSession->GetSerialNumber();
956 if (serialNumber.size() == 0) {
957 TLOGE(WmsLogTag::DMS, "serialNumber empty!");
958 return false;
959 }
960 if (multiScreenInfoMap.find(serialNumber) == multiScreenInfoMap.end()) {
961 TLOGE(WmsLogTag::DMS, "screen not found, use default mode!");
962 return false;
963 }
964
965 auto info = multiScreenInfoMap[serialNumber];
966 if (info.isExtendMain) {
967 info.mainScreenOption.screenId_ = screenSession->GetScreenId();
968 } else {
969 info.secondaryScreenOption.screenId_ = screenSession->GetScreenId();
970 }
971 if (info.multiScreenMode == MultiScreenMode::SCREEN_MIRROR) {
972 SetMultiScreenMode(info.mainScreenOption.screenId_, info.secondaryScreenOption.screenId_, info.multiScreenMode);
973 TLOGW(WmsLogTag::DMS, "mirror, return befor OnScreenConnectionChanged");
974 ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_MIRROR);
975 return true;
976 }
977 NotifyScreenModeChange();
978 if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
979 SetMultiScreenMode(info.mainScreenOption.screenId_, info.secondaryScreenOption.screenId_,
980 info.multiScreenMode);
981 } else {
982 clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenSession->GetScreenId()),
983 ScreenEvent::CONNECTED);
984 }
985 auto ret = SetMultiScreenRelativePosition(info.mainScreenOption, info.secondaryScreenOption);
986 if (ret != DMError::DM_OK) {
987 SetMultiScreenDefaultRelativePosition();
988 }
989 ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_EXTEND);
990 return true;
991 #else
992 return false;
993 #endif
994 }
995
ReportHandleScreenEvent(ScreenEvent screenEvent,ScreenCombination screenCombination)996 void ScreenSessionManager::ReportHandleScreenEvent(ScreenEvent screenEvent, ScreenCombination screenCombination)
997 {
998 MultiScreenMode multiScreenMode;
999 if (screenCombination == ScreenCombination::SCREEN_EXTEND) {
1000 multiScreenMode = MultiScreenMode::SCREEN_EXTEND;
1001 } else {
1002 multiScreenMode = MultiScreenMode::SCREEN_MIRROR;
1003 }
1004 int32_t ret = HiSysEventWrite(
1005 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
1006 "EXTEND_DISPLAY_PLUG_IN_AND_OUT",
1007 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
1008 "PLUG_IN_AND_OUT", static_cast<int32_t>(screenEvent),
1009 "DISPLAY_CONNECT_NUM", connectScreenNumber_,
1010 "DISPLAY_INUSED_NUM", GetCurrentInUseScreenNumber(),
1011 "EXTENSION_DISPLAY_MODE_STATUS", static_cast<int32_t>(multiScreenMode),
1012 "MAIN_DISPLAY_ID", GetInternalScreenId());
1013 if (ret != 0) {
1014 TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d", ret);
1015 }
1016 }
1017
GetCurrentInUseScreenNumber()1018 int32_t ScreenSessionManager::GetCurrentInUseScreenNumber()
1019 {
1020 int32_t inUseScreenNumber_ = 0;
1021 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1022 for (auto sessionIt : screenSessionMap_) {
1023 auto screenSession = sessionIt.second;
1024 if (screenSession == nullptr) {
1025 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
1026 continue;
1027 }
1028 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
1029 screenSession->GetIsCurrentInUse()) {
1030 TLOGI(WmsLogTag::DMS, "found screenId = %{public}" PRIu64, sessionIt.first);
1031 inUseScreenNumber_++;
1032 }
1033 }
1034 return inUseScreenNumber_;
1035 }
1036
SetCastPrivacyToRS(sptr<ScreenSession> screenSession,bool enable)1037 bool ScreenSessionManager::SetCastPrivacyToRS(sptr<ScreenSession> screenSession, bool enable)
1038 {
1039 bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId());
1040 if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL || !phyMirrorEnable) {
1041 TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"",
1042 screenSession->GetScreenId());
1043 return false;
1044 }
1045 ScreenId rsScreenId = INVALID_SCREEN_ID;
1046 if (!screenIdManager_.ConvertToRsScreenId(screenSession->GetScreenId(), rsScreenId) ||
1047 rsScreenId == INVALID_SCREEN_ID) {
1048 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
1049 return false;
1050 }
1051 rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, enable);
1052 return true;
1053 }
1054
SetCastPrivacyFromSettingData()1055 void ScreenSessionManager::SetCastPrivacyFromSettingData()
1056 {
1057 bool enable = true;
1058 bool isOK = ScreenSettingHelper::GetSettingCast(enable);
1059 TLOGI(WmsLogTag::DMS, "get setting cast done, isOK: %{public}u, enable: %{public}u", isOK, enable);
1060 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1061 for (const auto& sessionIt : screenSessionMap_) {
1062 auto screenSession = sessionIt.second;
1063 if (screenSession == nullptr) {
1064 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first);
1065 continue;
1066 }
1067 bool isSuc = SetCastPrivacyToRS(screenSession, enable);
1068 TLOGI(WmsLogTag::DMS, "set cast privacy done, isSuc:%{public}d, enable:%{public}d, screenId:%{public}" PRIu64"",
1069 isSuc, enable, sessionIt.first);
1070 }
1071 }
1072
RegisterSettingWireCastObserver(sptr<ScreenSession> & screenSession)1073 void ScreenSessionManager::RegisterSettingWireCastObserver(sptr<ScreenSession>& screenSession)
1074 {
1075 if (screenSession == nullptr) {
1076 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
1077 return;
1078 }
1079 bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId());
1080 if (!g_isPcDevice && phyMirrorEnable && screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL) {
1081 TLOGI(WmsLogTag::DMS, "Register Setting wire cast Observer");
1082 SettingObserver::UpdateFunc updateFunc = [this](const std::string& key) { SetCastPrivacyFromSettingData(); };
1083 ScreenSettingHelper::RegisterSettingWireCastObserver(updateFunc);
1084 }
1085 }
1086
UnregisterSettingWireCastObserver(ScreenId screenId)1087 void ScreenSessionManager::UnregisterSettingWireCastObserver(ScreenId screenId)
1088 {
1089 if (g_isPcDevice) {
1090 return;
1091 }
1092 for (const auto& sessionIt : screenSessionMap_) {
1093 auto screenSession = sessionIt.second;
1094 if (screenSession == nullptr) {
1095 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first);
1096 continue;
1097 }
1098 bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId());
1099 if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL || !phyMirrorEnable) {
1100 TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"", sessionIt.first);
1101 continue;
1102 }
1103 if (screenSession ->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR &&
1104 screenSession->GetScreenId() != screenId) {
1105 return;
1106 }
1107 }
1108 ScreenSettingHelper::UnregisterSettingWireCastObserver();
1109 TLOGI(WmsLogTag::DMS, "unregister Setting wire cast Observer");
1110 }
1111
HandleScreenConnectEvent(sptr<ScreenSession> screenSession,ScreenId screenId,ScreenEvent screenEvent)1112 void ScreenSessionManager::HandleScreenConnectEvent(sptr<ScreenSession> screenSession,
1113 ScreenId screenId, ScreenEvent screenEvent)
1114 {
1115 bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
1116 HandlePhysicalMirrorConnect(screenSession, phyMirrorEnable);
1117 #ifdef FOLD_ABILITY_ENABLE
1118 if (foldScreenController_ != nullptr) {
1119 if ((screenId == 0 || (screenId == SCREEN_ID_MAIN && isCoordinationFlag_ == true)) &&
1120 clientProxy_) {
1121 TLOGW(WmsLogTag::DMS, "event: connect %{public}" PRIu64 ", %{public}" PRIu64 ", "
1122 "name=%{public}s", screenId, screenSession->GetRSScreenId(), screenSession->GetName().c_str());
1123 clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1124 }
1125 return;
1126 }
1127 #endif
1128 if (clientProxy_ && g_isPcDevice) {
1129 SetExtendedScreenFallbackPlan(screenId);
1130 if (g_outerOnly == ONLY_OUTER_SCREEN_VALUE) {
1131 if (screenId != SCREEN_ID_FULL) {
1132 defaultScreenId_ = screenId;
1133 TLOGW(WmsLogTag::DMS, "event screen %{public}" PRIu64, screenId);
1134 clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1135 CallRsSetScreenPowerStatusSync(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
1136 }
1137 } else {
1138 if (!RecoverRestoredMultiScreenMode(screenSession)) {
1139 clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1140 SetMultiScreenDefaultRelativePosition();
1141 ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_EXTEND);
1142 }
1143 }
1144 }
1145 if (clientProxy_ && !g_isPcDevice && !phyMirrorEnable) {
1146 TLOGW(WmsLogTag::DMS, "screen connect and notify to scb.");
1147 clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1148 }
1149 if (phyMirrorEnable) {
1150 NotifyScreenConnected(screenSession->ConvertToScreenInfo());
1151 NotifyDisplayCreate(screenSession->ConvertToDisplayInfo());
1152 }
1153 TLOGW(WmsLogTag::DMS, "connect end. ScreenId: %{public}" PRIu64, screenId);
1154 }
1155
HandleScreenDisconnectEvent(sptr<ScreenSession> screenSession,ScreenId screenId,ScreenEvent screenEvent)1156 void ScreenSessionManager::HandleScreenDisconnectEvent(sptr<ScreenSession> screenSession,
1157 ScreenId screenId, ScreenEvent screenEvent)
1158 {
1159 bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
1160 if (phyMirrorEnable) {
1161 NotifyDisplayDestroy(screenSession->GetScreenId());
1162 NotifyCastWhenScreenConnectChange(false);
1163 FreeDisplayMirrorNodeInner(screenSession);
1164 if (!g_isPcDevice) {
1165 std::vector<ScreenId> screenIdsToExclude = { screenId };
1166 if (!HasCastEngineOrPhyMirror(screenIdsToExclude)) {
1167 ScreenPowerUtils::DisablePowerForceTimingOut();
1168 ScreenPowerUtils::LightAndLockScreen("light and lock screen");
1169 }
1170 }
1171 }
1172 HandlePCScreenDisconnect(screenSession);
1173 if (clientProxy_) {
1174 TLOGW(WmsLogTag::DMS, "screen disconnect and notify to scb.");
1175 clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), ScreenEvent::DISCONNECTED);
1176 }
1177 #ifdef WM_MULTI_SCREEN_ENABLE
1178 HandleExtendScreenDisconnect(screenId);
1179 #endif
1180 {
1181 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1182 screenSessionMap_.erase(screenId);
1183 }
1184 if (g_isPcDevice) {
1185 ScreenCombination screenCombination = screenSession->GetScreenCombination();
1186 ReportHandleScreenEvent(ScreenEvent::DISCONNECTED, screenCombination);
1187 SetMultiScreenFrameControl();
1188 }
1189 if (!(screenId == SCREEN_ID_MAIN && isCoordinationFlag_ == true)) {
1190 std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
1191 phyScreenPropMap_.erase(screenId);
1192 }
1193 if (phyMirrorEnable) {
1194 NotifyScreenDisconnected(screenSession->GetScreenId());
1195 isPhyScreenConnected_ = false;
1196 }
1197 if (!g_isPcDevice && phyMirrorEnable) {
1198 UnregisterSettingWireCastObserver(screenId);
1199 }
1200 TLOGW(WmsLogTag::DMS, "disconnect success. ScreenId: %{public}" PRIu64 "", screenId);
1201 }
1202
HandlePhysicalMirrorConnect(sptr<ScreenSession> screenSession,bool phyMirrorEnable)1203 void ScreenSessionManager::HandlePhysicalMirrorConnect(sptr<ScreenSession> screenSession, bool phyMirrorEnable)
1204 {
1205 if (phyMirrorEnable) {
1206 PhyMirrorConnectWakeupScreen();
1207 NotifyCastWhenScreenConnectChange(true);
1208 isPhyScreenConnected_ = true;
1209 RegisterSettingWireCastObserver(screenSession);
1210 if (!g_isPcDevice) {
1211 ScreenPowerUtils::EnablePowerForceTimingOut();
1212 DisablePowerOffRenderControl(0);
1213 }
1214 }
1215 }
1216
HandlePCScreenDisconnect(sptr<ScreenSession> screenSession)1217 void ScreenSessionManager::HandlePCScreenDisconnect(sptr<ScreenSession> screenSession)
1218 {
1219 ScreenCombination screenCombination = screenSession->GetScreenCombination();
1220 if (g_isPcDevice) {
1221 if (screenCombination == ScreenCombination::SCREEN_MAIN ||
1222 screenCombination == ScreenCombination::SCREEN_EXTEND) {
1223 TLOGW(WmsLogTag::DMS, "need to change screen");
1224 ScreenId internalScreenId = GetInternalScreenId();
1225 sptr<ScreenSession> internalSession = GetScreenSession(internalScreenId);
1226 if (screenCombination == ScreenCombination::SCREEN_EXTEND) {
1227 #ifdef WM_MULTI_SCREEN_ENABLE
1228 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_EXIT_STR);
1229 #endif
1230 }
1231 } else {
1232 #ifdef WM_MULTI_SCREEN_ENABLE
1233 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_MIRROR, MULTI_SCREEN_EXIT_STR);
1234 #endif
1235 NotifyCaptureStatusChanged(false);
1236 }
1237 MultiScreenPositionOptions defaultOptions = { GetDefaultScreenId(), 0, 0 };
1238 SetRelativePositionForDisconnect(defaultOptions);
1239 FreeDisplayMirrorNodeInner(screenSession);
1240 }
1241 }
1242
OnHgmRefreshRateChange(uint32_t refreshRate)1243 void ScreenSessionManager::OnHgmRefreshRateChange(uint32_t refreshRate)
1244 {
1245 GetDefaultScreenId();
1246 TLOGD(WmsLogTag::DMS, "Set refreshRate: %{public}u, defaultScreenId: %{public}" PRIu64"",
1247 refreshRate, defaultScreenId_);
1248 sptr<ScreenSession> screenSession = GetScreenSession(defaultScreenId_);
1249 if (screenSession) {
1250 screenSession->UpdateRefreshRate(refreshRate);
1251 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
1252 DisplayChangeEvent::UPDATE_REFRESHRATE);
1253 } else {
1254 TLOGE(WmsLogTag::DMS, "Get default screen session failed.");
1255 }
1256 return;
1257 }
1258
IsPhysicalScreenAndInUse(sptr<ScreenSession> screenSession) const1259 bool ScreenSessionManager::IsPhysicalScreenAndInUse(sptr<ScreenSession> screenSession) const
1260 {
1261 if (!screenSession) {
1262 return false;
1263 }
1264 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
1265 screenSession->GetIsCurrentInUse()) {
1266 return true;
1267 }
1268 return false;
1269 }
1270
SetMultiScreenFrameControl(void)1271 void ScreenSessionManager::SetMultiScreenFrameControl(void)
1272 {
1273 #ifdef WM_MULTI_SCREEN_CTL_ABILITY_ENABLE
1274 uint32_t count = 0;
1275 {
1276 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1277 for (auto sessionIt : screenSessionMap_) {
1278 if (IsPhysicalScreenAndInUse(sessionIt.second)) {
1279 count++;
1280 }
1281 }
1282 }
1283 if (count >= NUMBER_OF_PHYSICAL_SCREEN) {
1284 TLOGW(WmsLogTag::DMS, "MultiScreen control frame rate to 60");
1285 EventInfo event = { "VOTER_MUTIPHSICALSCREEN", ADD_VOTE, OLED_60_HZ, OLED_60_HZ };
1286 rsInterface_.NotifyRefreshRateEvent(event);
1287 } else {
1288 TLOGW(WmsLogTag::DMS, "Disabling frame rate control");
1289 EventInfo event = { "VOTER_MUTIPHSICALSCREEN", REMOVE_VOTE };
1290 rsInterface_.NotifyRefreshRateEvent(event);
1291 }
1292 #endif
1293 }
1294
GetScreenSession(ScreenId screenId) const1295 sptr<ScreenSession> ScreenSessionManager::GetScreenSession(ScreenId screenId) const
1296 {
1297 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1298 if (screenSessionMap_.empty()) {
1299 screenEventTracker_.LogWarningAllInfos();
1300 }
1301 auto iter = screenSessionMap_.find(screenId);
1302 if (iter == screenSessionMap_.end()) {
1303 TLOGW(WmsLogTag::DMS, "not found screen session id: %{public}" PRIu64" and create new.", screenId);
1304 return nullptr;
1305 }
1306 return iter->second;
1307 }
1308
GetDefaultScreenSession()1309 sptr<ScreenSession> ScreenSessionManager::GetDefaultScreenSession()
1310 {
1311 GetDefaultScreenId();
1312 return GetScreenSession(defaultScreenId_);
1313 }
1314
HookDisplayInfoByUid(sptr<DisplayInfo> displayInfo,const sptr<ScreenSession> & screenSession)1315 sptr<DisplayInfo> ScreenSessionManager::HookDisplayInfoByUid(sptr<DisplayInfo> displayInfo,
1316 const sptr<ScreenSession>& screenSession)
1317 {
1318 if (displayInfo == nullptr) {
1319 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1320 return nullptr;
1321 }
1322 auto uid = IPCSkeleton::GetCallingUid();
1323 std::shared_lock<std::shared_mutex> lock(hookInfoMutex_);
1324 if (displayHookMap_.find(uid) != displayHookMap_.end()) {
1325 auto info = displayHookMap_[uid];
1326 TLOGI(WmsLogTag::DMS, "hW: %{public}u, hH: %{public}u, hD: %{public}f, hR: %{public}u, hER: %{public}d, "
1327 "dW: %{public}u, dH: %{public}u, dR: %{public}u, dO: %{public}u", info.width_, info.height_, info.density_,
1328 info.rotation_, info.enableHookRotation_, displayInfo->GetWidth(), displayInfo->GetHeight(),
1329 displayInfo->GetRotation(), displayInfo->GetDisplayOrientation());
1330
1331 displayInfo->SetWidth(info.width_);
1332 displayInfo->SetHeight(info.height_);
1333 displayInfo->SetVirtualPixelRatio(info.density_);
1334 if (info.enableHookRotation_) {
1335 if (screenSession) {
1336 Rotation targetRotation = screenSession->ConvertIntToRotation(static_cast<int32_t>(info.rotation_));
1337 displayInfo->SetRotation(targetRotation);
1338 DisplayOrientation targetOrientation = screenSession->CalcDisplayOrientation(targetRotation,
1339 FoldDisplayMode::UNKNOWN, IsOrientationNeedChanged());
1340 TLOGI(WmsLogTag::DMS, "tR: %{public}u, tO: %{public}u", targetRotation, targetOrientation);
1341 displayInfo->SetDisplayOrientation(targetOrientation);
1342 } else {
1343 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, screenSession is nullptr.");
1344 return nullptr;
1345 }
1346 }
1347 }
1348 return displayInfo;
1349 }
1350
GetDefaultDisplayInfo()1351 sptr<DisplayInfo> ScreenSessionManager::GetDefaultDisplayInfo()
1352 {
1353 GetDefaultScreenId();
1354 sptr<ScreenSession> screenSession = GetScreenSession(defaultScreenId_);
1355 std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
1356 if (screenSession) {
1357 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1358 if (displayInfo == nullptr) {
1359 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1360 return nullptr;
1361 }
1362 // 在PC/PAD上安装的竖屏应用以及白名单中的应用在显示状态非全屏时需要hook displayinfo
1363 displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
1364 return displayInfo;
1365 } else {
1366 TLOGE(WmsLogTag::DMS, "failed");
1367 return nullptr;
1368 }
1369 }
1370
GetDisplayInfoById(DisplayId displayId)1371 sptr<DisplayInfo> ScreenSessionManager::GetDisplayInfoById(DisplayId displayId)
1372 {
1373 TLOGD(WmsLogTag::DMS, "enter, displayId: %{public}" PRIu64" ", displayId);
1374 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1375 for (auto sessionIt : screenSessionMap_) {
1376 auto screenSession = sessionIt.second;
1377 if (screenSession == nullptr) {
1378 TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64 "",
1379 sessionIt.first);
1380 continue;
1381 }
1382 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1383 if (displayInfo == nullptr) {
1384 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1385 continue;
1386 }
1387 if (displayId == displayInfo->GetDisplayId()) {
1388 TLOGD(WmsLogTag::DMS, "success");
1389 displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
1390 return displayInfo;
1391 }
1392 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1393 continue;
1394 }
1395 if (!screenSession->GetScreenProperty().GetIsFakeInUse()) {
1396 continue;
1397 }
1398 sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
1399 if (fakeScreenSession == nullptr) {
1400 TLOGE(WmsLogTag::DMS, "error, fakeScreenSession is nullptr.");
1401 continue;
1402 }
1403 sptr<DisplayInfo> fakeDisplayInfo = fakeScreenSession->ConvertToDisplayInfo();
1404 if (fakeDisplayInfo == nullptr) {
1405 TLOGE(WmsLogTag::DMS, "error, fakeDisplayInfo is nullptr.");
1406 continue;
1407 }
1408 fakeDisplayInfo = HookDisplayInfoByUid(fakeDisplayInfo, fakeScreenSession);
1409 DisplayId fakeDisplayId = fakeDisplayInfo->GetDisplayId();
1410 if (displayId == fakeDisplayId) {
1411 TLOGD(WmsLogTag::DMS, "find fake success");
1412 return fakeDisplayInfo;
1413 }
1414 }
1415 TLOGE(WmsLogTag::DMS, "GetDisplayInfoById failed. displayId: %{public}" PRIu64" ", displayId);
1416 return nullptr;
1417 }
1418
GetVisibleAreaDisplayInfoById(DisplayId displayId)1419 sptr<DisplayInfo> ScreenSessionManager::GetVisibleAreaDisplayInfoById(DisplayId displayId)
1420 {
1421 TLOGD(WmsLogTag::DMS, "enter, displayId: %{public}" PRIu64" ", displayId);
1422 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1423 for (auto sessionIt : screenSessionMap_) {
1424 auto screenSession = sessionIt.second;
1425 if (screenSession == nullptr) {
1426 TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64 "",
1427 sessionIt.first);
1428 continue;
1429 }
1430 sptr<DisplayInfo> displayInfo = screenSession->ConvertToRealDisplayInfo();
1431 if (displayInfo == nullptr) {
1432 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1433 continue;
1434 }
1435 if (displayId != displayInfo->GetDisplayId()) {
1436 continue;
1437 }
1438 TLOGD(WmsLogTag::DMS, "success");
1439 displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
1440 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1441 return displayInfo;
1442 }
1443 #ifdef FOLD_ABILITY_ENABLE
1444 SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
1445 RRect bounds = screenSession->GetScreenProperty().GetBounds();
1446 auto screenWdith = bounds.rect_.GetWidth();
1447 auto screenHeight = bounds.rect_.GetHeight();
1448 if (status == SuperFoldStatus::KEYBOARD) {
1449 if (screenWdith > screenHeight) {
1450 std::swap(screenWdith, screenHeight);
1451 }
1452 DMRect creaseRect = screenSession->GetScreenProperty().GetCreaseRect();
1453 if (creaseRect.posY_ > 0) {
1454 displayInfo->SetHeight(creaseRect.posY_);
1455 } else {
1456 displayInfo->SetHeight(screenHeight / HALF_SCREEN_PARAM);
1457 }
1458 displayInfo->SetWidth(screenWdith);
1459 } else {
1460 displayInfo->SetWidth(screenWdith);
1461 displayInfo->SetHeight(screenHeight);
1462 }
1463 return displayInfo;
1464 #endif
1465 }
1466 TLOGE(WmsLogTag::DMS, "GetVisibleAreaDisplayInfoById failed. displayId: %{public}" PRIu64" ", displayId);
1467 return nullptr;
1468 }
1469
GetDisplayInfoByScreen(ScreenId screenId)1470 sptr<DisplayInfo> ScreenSessionManager::GetDisplayInfoByScreen(ScreenId screenId)
1471 {
1472 TLOGD(WmsLogTag::DMS, "enter, screenId: %{public}" PRIu64"", screenId);
1473 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1474 for (auto sessionIt : screenSessionMap_) {
1475 auto screenSession = sessionIt.second;
1476 if (screenSession == nullptr) {
1477 TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId:%{public}" PRIu64"",
1478 sessionIt.first);
1479 continue;
1480 }
1481 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1482 if (displayInfo == nullptr) {
1483 TLOGI(WmsLogTag::DMS, "error, displayInfo is nullptr.");
1484 continue;
1485 }
1486 if (screenId == displayInfo->GetScreenId()) {
1487 return displayInfo;
1488 }
1489 }
1490 TLOGE(WmsLogTag::DMS, "failed. screenId: %{public}" PRIu64" ", screenId);
1491 return nullptr;
1492 }
1493
GetFakeDisplayId(sptr<ScreenSession> screenSession)1494 DisplayId ScreenSessionManager::GetFakeDisplayId(sptr<ScreenSession> screenSession)
1495 {
1496 sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
1497 if (fakeScreenSession == nullptr) {
1498 TLOGE(WmsLogTag::DMS, "error, fakeScreenSession is nullptr.");
1499 return DISPLAY_ID_INVALID;
1500 }
1501 sptr<DisplayInfo> fakeDisplayInfo = fakeScreenSession->ConvertToDisplayInfo();
1502 if (fakeDisplayInfo == nullptr) {
1503 TLOGE(WmsLogTag::DMS, "error, fakeDisplayInfo is nullptr.");
1504 return DISPLAY_ID_INVALID;
1505 }
1506 DisplayId fakeDisplayId = fakeDisplayInfo->GetDisplayId();
1507 return fakeDisplayId;
1508 }
1509
GetAllDisplayIds()1510 std::vector<DisplayId> ScreenSessionManager::GetAllDisplayIds()
1511 {
1512 TLOGI(WmsLogTag::DMS, "enter");
1513 std::vector<DisplayId> res;
1514 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1515 for (auto sessionIt : screenSessionMap_) {
1516 auto screenSession = sessionIt.second;
1517 if (screenSession == nullptr) {
1518 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, ScreenId:%{public}" PRIu64"",
1519 sessionIt.first);
1520 continue;
1521 }
1522 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1523 if (displayInfo == nullptr) {
1524 TLOGE(WmsLogTag::DMS, "error, displayInfo is nullptr.");
1525 continue;
1526 }
1527 DisplayId displayId = displayInfo->GetDisplayId();
1528 res.push_back(displayId);
1529 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1530 continue;
1531 }
1532 if (!screenSession->GetScreenProperty().GetIsFakeInUse()) {
1533 continue;
1534 }
1535 DisplayId fakeDisplayId = GetFakeDisplayId(screenSession);
1536 if (fakeDisplayId == DISPLAY_ID_FAKE) {
1537 res.push_back(fakeDisplayId);
1538 TLOGI(WmsLogTag::DMS, "add fakeDisplayId: %{public}" PRIu64 "", fakeDisplayId);
1539 }
1540 }
1541 return res;
1542 }
1543
CalculateXYPosition(sptr<ScreenSession> screenSession)1544 void ScreenSessionManager::CalculateXYPosition(sptr<ScreenSession> screenSession)
1545 {
1546 if (screenSession == nullptr) {
1547 TLOGI(WmsLogTag::DMS, "screenSession is nullptr");
1548 return;
1549 }
1550 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && screenSession->isInternal_) {
1551 screenSession->SetXYPosition(0, 0);
1552 } else {
1553 ScreenId internalScreenId = GetInternalScreenId();
1554 sptr<ScreenSession> internalSession = GetScreenSession(internalScreenId);
1555 if (internalSession == nullptr) {
1556 TLOGI(WmsLogTag::DMS, "internalSession is nullptr");
1557 return;
1558 }
1559 ScreenProperty internalScreenProperty = internalSession->GetScreenProperty();
1560 ScreenProperty secondaryScreenProperty = screenSession->GetScreenProperty();
1561 int32_t internalX = internalScreenProperty.GetStartX();
1562 int32_t internalY = internalScreenProperty.GetStartY();
1563 int32_t secondaryX = secondaryScreenProperty.GetStartX();
1564 int32_t secondaryY = secondaryScreenProperty.GetStartY();
1565 secondaryX = secondaryX + ~internalX + 1;
1566 secondaryY = secondaryY + ~internalY + 1;
1567 screenSession->SetXYPosition(secondaryX, secondaryY);
1568 }
1569 }
1570
GetScreenInfoById(ScreenId screenId)1571 sptr<ScreenInfo> ScreenSessionManager::GetScreenInfoById(ScreenId screenId)
1572 {
1573 if (!SessionPermission::IsSystemCalling() &&
1574 !Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION)) {
1575 TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
1576 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1577 return nullptr;
1578 }
1579 auto screenSession = GetScreenSession(screenId);
1580 if (screenSession == nullptr) {
1581 TLOGE(WmsLogTag::DMS, "cannot find screenInfo: %{public}" PRIu64"", screenId);
1582 return nullptr;
1583 }
1584 return screenSession->ConvertToScreenInfo();
1585 }
1586
SetScreenActiveMode(ScreenId screenId,uint32_t modeId)1587 DMError ScreenSessionManager::SetScreenActiveMode(ScreenId screenId, uint32_t modeId)
1588 {
1589 #ifdef WM_SCREEN_ACTIVE_MODE_ENABLE
1590 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", modeId: %{public}u", screenId, modeId);
1591 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1592 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, calling pid: %{public}d",
1593 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1594 return DMError::DM_ERROR_NOT_SYSTEM_APP;
1595 }
1596 if (screenId == SCREEN_ID_INVALID) {
1597 TLOGE(WmsLogTag::DMS, "invalid screenId");
1598 return DMError::DM_ERROR_NULLPTR;
1599 }
1600 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1601 if (screenSession == nullptr) {
1602 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1603 return DMError::DM_ERROR_NULLPTR;
1604 }
1605 ScreenId rsScreenId = SCREEN_ID_INVALID;
1606 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
1607 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
1608 return DMError::DM_ERROR_NULLPTR;
1609 }
1610 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetScreenActiveMode(%" PRIu64", %u)", screenId, modeId);
1611 rsInterface_.SetScreenActiveMode(rsScreenId, modeId);
1612 screenSession->activeIdx_ = static_cast<int32_t>(modeId);
1613 screenSession->UpdatePropertyByActiveMode();
1614 ScreenProperty property = screenSession->GetScreenProperty();
1615 property.SetPropertyChangeReason("active mode change");
1616 screenSession->PropertyChange(property, ScreenPropertyChangeReason::CHANGE_MODE);
1617 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
1618 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
1619 #endif
1620 return DMError::DM_OK;
1621 }
1622
ConvertScreenIdToRsScreenId(ScreenId screenId,ScreenId & rsScreenId)1623 bool ScreenSessionManager::ConvertScreenIdToRsScreenId(ScreenId screenId, ScreenId& rsScreenId)
1624 {
1625 return screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
1626 }
1627
UpdateDisplayHookInfo(int32_t uid,bool enable,const DMHookInfo & hookInfo)1628 void ScreenSessionManager::UpdateDisplayHookInfo(int32_t uid, bool enable, const DMHookInfo& hookInfo)
1629 {
1630 TLOGD(WmsLogTag::DMS, "DisplayHookInfo will update");
1631 if (!SessionPermission::IsSystemCalling()) {
1632 TLOGE(WmsLogTag::DMS, "permission denied!");
1633 return;
1634 }
1635
1636 std::unique_lock<std::shared_mutex> lock(hookInfoMutex_);
1637 if (enable) {
1638 if (uid != 0) {
1639 displayHookMap_[uid] = hookInfo;
1640 }
1641 } else {
1642 displayHookMap_.erase(uid);
1643 }
1644 }
1645
GetDisplayHookInfo(int32_t uid,DMHookInfo & hookInfo)1646 void ScreenSessionManager::GetDisplayHookInfo(int32_t uid, DMHookInfo& hookInfo)
1647 {
1648 std::shared_lock<std::shared_mutex> lock(hookInfoMutex_);
1649 if (displayHookMap_.find(uid) != displayHookMap_.end()) {
1650 hookInfo = displayHookMap_[uid];
1651 }
1652 }
1653
IsFreezed(const int32_t & agentPid,const DisplayManagerAgentType & agentType)1654 bool ScreenSessionManager::IsFreezed(const int32_t& agentPid, const DisplayManagerAgentType& agentType)
1655 {
1656 std::lock_guard<std::mutex> lock(freezedPidListMutex_);
1657 if (freezedPidList_.count(agentPid) == 0) {
1658 return false;
1659 }
1660 // 冻结的应用记录应用 pid 和注册的 agentType
1661 if (pidAgentTypeMap_.count(agentPid) == 0) {
1662 std::set agentTypes = { agentType };
1663 pidAgentTypeMap_[agentPid] = agentTypes;
1664 } else {
1665 pidAgentTypeMap_[agentPid].insert(agentType);
1666 }
1667 TLOGD(WmsLogTag::DMS, "Agent is freezed, no need notify. PID: %{public}d.", agentPid);
1668 return true;
1669 }
1670
NotifyScreenChanged(sptr<ScreenInfo> screenInfo,ScreenChangeEvent event)1671 void ScreenSessionManager::NotifyScreenChanged(sptr<ScreenInfo> screenInfo, ScreenChangeEvent event)
1672 {
1673 if (screenInfo == nullptr) {
1674 TLOGE(WmsLogTag::DMS, "error, screenInfo is nullptr.");
1675 return;
1676 }
1677 {
1678 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
1679 lastScreenChangeEvent_ = event;
1680 }
1681 auto task = [=] {
1682 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
1683 TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", agent size: %{public}u",
1684 screenInfo->GetScreenId(), static_cast<uint32_t>(agents.size()));
1685 if (agents.empty()) {
1686 return;
1687 }
1688 for (auto& agent : agents) {
1689 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
1690 if (!IsFreezed(agentPid, DisplayManagerAgentType::SCREEN_EVENT_LISTENER)) {
1691 agent->OnScreenChange(screenInfo, event);
1692 }
1693 }
1694 };
1695 taskScheduler_->PostAsyncTask(task, "NotifyScreenChanged:SID:" + std::to_string(screenInfo->GetScreenId()));
1696 }
1697
SetVirtualPixelRatio(ScreenId screenId,float virtualPixelRatio)1698 DMError ScreenSessionManager::SetVirtualPixelRatio(ScreenId screenId, float virtualPixelRatio)
1699 {
1700 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1701 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
1702 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1703 return DMError::DM_ERROR_NOT_SYSTEM_APP;
1704 }
1705
1706 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1707 if (!screenSession) {
1708 TLOGE(WmsLogTag::DMS, "screen session is nullptr");
1709 return DMError::DM_ERROR_UNKNOWN;
1710 }
1711 if (screenSession->isScreenGroup_) {
1712 TLOGE(WmsLogTag::DMS, "cannot set virtual pixel ratio to the combination. screen: %{public}" PRIu64"",
1713 screenId);
1714 return DMError::DM_ERROR_NULLPTR;
1715 }
1716 // less to 1e-6 mean equal
1717 if (fabs(screenSession->GetScreenProperty().GetVirtualPixelRatio() - virtualPixelRatio) < 1e-6) {
1718 TLOGE(WmsLogTag::DMS,
1719 "The density is equivalent to the original value, no update operation is required, aborted.");
1720 return DMError::DM_OK;
1721 }
1722 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetVirtualPixelRatio(%" PRIu64", %f)", screenId,
1723 virtualPixelRatio);
1724 screenSession->SetVirtualPixelRatio(virtualPixelRatio);
1725 std::map<DisplayId, sptr<DisplayInfo>> emptyMap;
1726 OnPropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::VIRTUAL_PIXEL_RATIO_CHANGE,
1727 screenId);
1728 NotifyDisplayStateChange(screenId, screenSession->ConvertToDisplayInfo(),
1729 emptyMap, DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE);
1730 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::VIRTUAL_PIXEL_RATIO_CHANGED);
1731 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
1732 DisplayChangeEvent::DISPLAY_VIRTUAL_PIXEL_RATIO_CHANGED);
1733 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && screenSession->GetScreenProperty().GetIsFakeInUse()) {
1734 sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
1735 if (fakeScreenSession == nullptr) {
1736 TLOGE(WmsLogTag::DMS, "error,fakeScreenSession is nullptr.");
1737 return DMError::DM_OK;
1738 }
1739 fakeScreenSession->SetVirtualPixelRatio(virtualPixelRatio);
1740 }
1741 return DMError::DM_OK;
1742 }
1743
SetVirtualPixelRatioSystem(ScreenId screenId,float virtualPixelRatio)1744 DMError ScreenSessionManager::SetVirtualPixelRatioSystem(ScreenId screenId, float virtualPixelRatio)
1745 {
1746 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1747 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
1748 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1749 return DMError::DM_ERROR_NOT_SYSTEM_APP;
1750 }
1751
1752 if (clientProxy_) {
1753 clientProxy_->SetVirtualPixelRatioSystem(screenId, virtualPixelRatio);
1754 }
1755 return DMError::DM_OK;
1756 }
1757
SetDefaultDensityDpi(ScreenId screenId,float virtualPixelRatio)1758 DMError ScreenSessionManager::SetDefaultDensityDpi(ScreenId screenId, float virtualPixelRatio)
1759 {
1760 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1761 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
1762 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1763 return DMError::DM_ERROR_NOT_SYSTEM_APP;
1764 }
1765
1766 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1767 if (!screenSession) {
1768 TLOGE(WmsLogTag::DMS, "screen session is nullptr");
1769 return DMError::DM_ERROR_UNKNOWN;
1770 }
1771 if (screenSession->isScreenGroup_) {
1772 TLOGE(WmsLogTag::DMS, "cannot set virtual pixel ratio to the combination. screen: %{public}" PRIu64"",
1773 screenId);
1774 return DMError::DM_ERROR_NULLPTR;
1775 }
1776 // less to 1e-6 mean equal
1777 if (fabs(screenSession->GetScreenProperty().GetDefaultDensity() - virtualPixelRatio) < 1e-6) {
1778 TLOGE(WmsLogTag::DMS,
1779 "The density is equivalent to the original value, no update operation is required, aborted.");
1780 return DMError::DM_OK;
1781 }
1782 screenSession->SetDefaultDensity(virtualPixelRatio);
1783 return DMError::DM_OK;
1784 }
1785
SetResolution(ScreenId screenId,uint32_t width,uint32_t height,float virtualPixelRatio)1786 DMError ScreenSessionManager::SetResolution(ScreenId screenId, uint32_t width, uint32_t height, float virtualPixelRatio)
1787 {
1788 TLOGI(WmsLogTag::DMS,
1789 "ScreenId: %{public}" PRIu64 ", w: %{public}u, h: %{public}u, virtualPixelRatio: %{public}f",
1790 screenId, width, height, virtualPixelRatio);
1791 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1792 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
1793 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1794 return DMError::DM_ERROR_NOT_SYSTEM_APP;
1795 }
1796 if (screenId == SCREEN_ID_INVALID) {
1797 TLOGE(WmsLogTag::DMS, "invalid screenId");
1798 return DMError::DM_ERROR_NULLPTR;
1799 }
1800 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1801 if (screenSession == nullptr) {
1802 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1803 return DMError::DM_ERROR_NULLPTR;
1804 }
1805 sptr<SupportedScreenModes> screenSessionModes = screenSession->GetActiveScreenMode();
1806 if (screenSessionModes == nullptr) {
1807 return DMError::DM_ERROR_NULLPTR;
1808 }
1809 if (width <= 0 || width > screenSessionModes->width_ ||
1810 height <= 0 || height > screenSessionModes->height_ ||
1811 virtualPixelRatio < (static_cast<float>(DOT_PER_INCH_MINIMUM_VALUE) / DOT_PER_INCH) ||
1812 virtualPixelRatio > (static_cast<float>(DOT_PER_INCH_MAXIMUM_VALUE) / DOT_PER_INCH)) {
1813 TLOGE(WmsLogTag::DMS, "invalid param! w:%{public}u h:%{public}u min:%{public}f max:%{public}f",
1814 screenSessionModes->width_, screenSessionModes->height_,
1815 static_cast<float>(DOT_PER_INCH_MINIMUM_VALUE) / DOT_PER_INCH,
1816 static_cast<float>(DOT_PER_INCH_MAXIMUM_VALUE) / DOT_PER_INCH);
1817 return DMError::DM_ERROR_INVALID_PARAM;
1818 }
1819 screenSession->SetDensityInCurResolution(virtualPixelRatio);
1820 DMError ret = SetVirtualPixelRatio(screenId, virtualPixelRatio);
1821 if (ret != DMError::DM_OK) {
1822 TLOGE(WmsLogTag::DMS, "Failed to setVirtualPixelRatio when settingResolution");
1823 screenSession->SetDensityInCurResolution(screenSession->GetScreenProperty().GetVirtualPixelRatio());
1824 return ret;
1825 }
1826 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetResolution(%" PRIu64", %u, %u, %f)",
1827 screenId, width, height, virtualPixelRatio);
1828 screenSession->UpdatePropertyByResolution(width, height);
1829 screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::CHANGE_MODE);
1830 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
1831 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
1832 return DMError::DM_OK;
1833 }
1834
GetDensityInCurResolution(ScreenId screenId,float & virtualPixelRatio)1835 DMError ScreenSessionManager::GetDensityInCurResolution(ScreenId screenId, float& virtualPixelRatio)
1836 {
1837 DmsXcollie dmsXcollie("DMS:GetDensityInCurResolution", XCOLLIE_TIMEOUT_10S);
1838 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1839 if (screenSession == nullptr) {
1840 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1841 return DMError::DM_ERROR_NULLPTR;
1842 }
1843
1844 virtualPixelRatio = screenSession->GetScreenProperty().GetDensityInCurResolution();
1845 return DMError::DM_OK;
1846 }
1847
GetScreenColorGamut(ScreenId screenId,ScreenColorGamut & colorGamut)1848 DMError ScreenSessionManager::GetScreenColorGamut(ScreenId screenId, ScreenColorGamut& colorGamut)
1849 {
1850 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
1851 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 "", screenId);
1852 if (screenId == SCREEN_ID_INVALID) {
1853 TLOGE(WmsLogTag::DMS, "screenId invalid");
1854 return DMError::DM_ERROR_INVALID_PARAM;
1855 }
1856 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1857 if (screenSession == nullptr) {
1858 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1859 return DMError::DM_ERROR_INVALID_PARAM;
1860 }
1861 return screenSession->GetScreenColorGamut(colorGamut);
1862 #else
1863 return DMError::DM_OK;
1864 #endif
1865 }
1866
SetScreenColorGamut(ScreenId screenId,int32_t colorGamutIdx)1867 DMError ScreenSessionManager::SetScreenColorGamut(ScreenId screenId, int32_t colorGamutIdx)
1868 {
1869 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
1870 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1871 TLOGE(WmsLogTag::DMS, "permission denied!");
1872 return DMError::DM_ERROR_NOT_SYSTEM_APP;
1873 }
1874
1875 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", colorGamutIdx %{public}d",
1876 screenId, colorGamutIdx);
1877 if (screenId == SCREEN_ID_INVALID) {
1878 TLOGE(WmsLogTag::DMS, "screenId invalid");
1879 return DMError::DM_ERROR_INVALID_PARAM;
1880 }
1881 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1882 if (screenSession == nullptr) {
1883 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1884 return DMError::DM_ERROR_INVALID_PARAM;
1885 }
1886 return screenSession->SetScreenColorGamut(colorGamutIdx);
1887 #else
1888 return DMError::DM_OK;
1889 #endif
1890 }
1891
GetScreenGamutMap(ScreenId screenId,ScreenGamutMap & gamutMap)1892 DMError ScreenSessionManager::GetScreenGamutMap(ScreenId screenId, ScreenGamutMap& gamutMap)
1893 {
1894 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
1895 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 "", screenId);
1896 if (screenId == SCREEN_ID_INVALID) {
1897 TLOGE(WmsLogTag::DMS, "screenId invalid");
1898 return DMError::DM_ERROR_INVALID_PARAM;
1899 }
1900 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1901 if (screenSession == nullptr) {
1902 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1903 return DMError::DM_ERROR_INVALID_PARAM;
1904 }
1905 return screenSession->GetScreenGamutMap(gamutMap);
1906 #else
1907 return DMError::DM_OK;
1908 #endif
1909 }
1910
SetScreenGamutMap(ScreenId screenId,ScreenGamutMap gamutMap)1911 DMError ScreenSessionManager::SetScreenGamutMap(ScreenId screenId, ScreenGamutMap gamutMap)
1912 {
1913 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
1914 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1915 TLOGE(WmsLogTag::DMS, "permission denied!");
1916 return DMError::DM_ERROR_NOT_SYSTEM_APP;
1917 }
1918
1919 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", ScreenGamutMap %{public}u",
1920 screenId, static_cast<uint32_t>(gamutMap));
1921 if (screenId == SCREEN_ID_INVALID) {
1922 TLOGE(WmsLogTag::DMS, "screenId invalid");
1923 return DMError::DM_ERROR_INVALID_PARAM;
1924 }
1925 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1926 if (screenSession == nullptr) {
1927 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1928 return DMError::DM_ERROR_INVALID_PARAM;
1929 }
1930 return screenSession->SetScreenGamutMap(gamutMap);
1931 #else
1932 return DMError::DM_OK;
1933 #endif
1934 }
1935
SetScreenColorTransform(ScreenId screenId)1936 DMError ScreenSessionManager::SetScreenColorTransform(ScreenId screenId)
1937 {
1938 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1939 TLOGE(WmsLogTag::DMS, "permission denied!");
1940 return DMError::DM_ERROR_NOT_SYSTEM_APP;
1941 }
1942
1943 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 "", screenId);
1944 if (screenId == SCREEN_ID_INVALID) {
1945 TLOGE(WmsLogTag::DMS, "screenId invalid");
1946 return DMError::DM_ERROR_INVALID_PARAM;
1947 }
1948 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
1949 if (screenSession == nullptr) {
1950 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
1951 return DMError::DM_ERROR_INVALID_PARAM;
1952 }
1953 return screenSession->SetScreenColorTransform();
1954 }
1955
GetPhysicalScreenSession(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)1956 sptr<ScreenSession> ScreenSessionManager::GetPhysicalScreenSession(ScreenId screenId, ScreenId defScreenId,
1957 ScreenProperty property)
1958 {
1959 sptr<ScreenSession> screenSession = nullptr;
1960 ScreenSessionConfig config;
1961 if (g_isPcDevice) {
1962 if (g_outerOnly == ONLY_OUTER_SCREEN_VALUE) {
1963 config = {
1964 .screenId = screenId,
1965 .rsId = screenId,
1966 .property = property,
1967 };
1968 } else {
1969 config = {
1970 .screenId = screenId,
1971 .rsId = screenId,
1972 .defaultScreenId = defScreenId,
1973 .property = property,
1974 };
1975 }
1976 screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_REAL);
1977 } else {
1978 sptr<ScreenSession> defaultScreen = GetDefaultScreenSession();
1979 if (defaultScreen == nullptr || defaultScreen->GetDisplayNode() == nullptr) {
1980 TLOGE(WmsLogTag::DMS, "default screen null");
1981 return screenSession;
1982 }
1983 NodeId nodeId = defaultScreen->GetDisplayNode()->GetId();
1984 TLOGI(WmsLogTag::DMS, "physical mirror screen nodeId: %{public}" PRIu64, nodeId);
1985 config = {
1986 .screenId = screenId,
1987 .defaultScreenId = defScreenId,
1988 .mirrorNodeId = nodeId,
1989 .property = property,
1990 };
1991 screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_MIRROR);
1992 screenSession->SetIsPhysicalMirrorSwitch(true);
1993 #ifdef FOLD_ABILITY_ENABLE
1994 if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
1995 DMRect mainScreenRegion = {0, 0, 0, 0};
1996 foldScreenController_->SetMainScreenRegion(mainScreenRegion);
1997 screenSession->SetMirrorScreenRegion(screenId, mainScreenRegion);
1998 screenSession->EnableMirrorScreenRegion();
1999 }
2000 #endif
2001 }
2002 return screenSession;
2003 }
2004
CreatePhysicalMirrorSessionInner(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)2005 sptr<ScreenSession> ScreenSessionManager::CreatePhysicalMirrorSessionInner(ScreenId screenId, ScreenId defScreenId,
2006 ScreenProperty property)
2007 {
2008 #ifdef WM_MULTI_SCREEN_ENABLE
2009 sptr<ScreenSession> screenSession = nullptr;
2010 if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
2011 TLOGW(WmsLogTag::DMS, "mirror disabled by edm!");
2012 return screenSession;
2013 }
2014 screenSession = GetPhysicalScreenSession(screenId, defScreenId, property);
2015 if (!screenSession) {
2016 TLOGE(WmsLogTag::DMS, "screenSession is null");
2017 return nullptr;
2018 }
2019 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_ENTER_STR);
2020 HandleExtendScreenConnect(screenId);
2021 if (g_isPcDevice) {
2022 // pc is none, pad&&phone is mirror
2023 InitExtendScreenProperty(screenId, screenSession, property);
2024 screenSession->SetName("ExtendedDisplay");
2025 if (g_outerOnly == ONLY_OUTER_SCREEN_VALUE) {
2026 screenSession->SetIsExtend(false);
2027 screenSession->SetScreenCombination(ScreenCombination::SCREEN_MAIN);
2028 } else {
2029 screenSession->SetIsExtend(true);
2030 screenSession->SetScreenCombination(ScreenCombination::SCREEN_EXTEND);
2031 }
2032 } else {
2033 screenSession->SetIsExtend(true);
2034 screenSession->SetName("CastEngine");
2035 screenSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
2036 }
2037 GetAndMergeEdidInfo(screenSession);
2038 screenSession->SetMirrorScreenType(MirrorScreenType::PHYSICAL_MIRROR);
2039 screenSession->SetIsPcUse(g_isPcDevice ? true : false);
2040 screenSession->SetIsInternal(false);
2041 screenSession->SetIsRealScreen(true);
2042 screenSession->SetIsCurrentInUse(true);
2043 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE);
2044 if (!g_isPcDevice) {
2045 hdmiScreenCount_ = hdmiScreenCount_ + 1;
2046 NotifyCaptureStatusChanged();
2047 }
2048 return screenSession;
2049 #else
2050 return nullptr;
2051 #endif
2052 }
2053
GetScreenSessionInner(ScreenId screenId,ScreenProperty property)2054 sptr<ScreenSession> ScreenSessionManager::GetScreenSessionInner(ScreenId screenId, ScreenProperty property)
2055 {
2056 ScreenId defScreenId = GetDefaultScreenId();
2057 TLOGW(WmsLogTag::DMS, "screenId:%{public}" PRIu64 "", screenId);
2058 if (IsDefaultMirrorMode(screenId)) {
2059 #ifdef WM_MULTI_SCREEN_ENABLE
2060 return CreatePhysicalMirrorSessionInner(screenId, defScreenId, property);
2061 #else
2062 return nullptr;
2063 #endif
2064 }
2065 std::string screenName = "UNKNOWN";
2066 if (screenId == SCREEN_ID_MAIN) {
2067 screenName = "SubScreen";
2068 }
2069 ScreenSessionConfig config = {
2070 .screenId = screenId,
2071 .defaultScreenId = defScreenId,
2072 .name = screenName,
2073 .property = property,
2074 };
2075 sptr<ScreenSession> screenSession = nullptr;
2076 if (g_isPcDevice && g_outerOnly == ONLY_OUTER_SCREEN_VALUE) {
2077 return screenSession;
2078 }
2079 screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_REAL);
2080 screenSession->SetIsExtend(false);
2081 screenSession->SetScreenCombination(ScreenCombination::SCREEN_MAIN);
2082 screenSession->SetIsInternal(true);
2083 screenSession->SetIsRealScreen(true);
2084 screenSession->SetIsCurrentInUse(true);
2085 screenSession->SetIsPcUse(g_isPcDevice ? true : false);
2086 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
2087 InitFakeScreenSession(screenSession);
2088 }
2089 return screenSession;
2090 }
2091
CreateScreenProperty(ScreenId screenId,ScreenProperty & property)2092 void ScreenSessionManager::CreateScreenProperty(ScreenId screenId, ScreenProperty& property)
2093 {
2094 int id = HiviewDFX::XCollie::GetInstance().SetTimer("CreateScreenPropertyCallRS", XCOLLIE_TIMEOUT_10S, nullptr,
2095 nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
2096 TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenActiveMode ScreenId: %{public}" PRIu64, screenId);
2097 auto screenMode = rsInterface_.GetScreenActiveMode(screenId);
2098 TLOGW(WmsLogTag::DMS, "get screenWidth: %{public}d, screenHeight: %{public}d",
2099 static_cast<uint32_t>(screenMode.GetScreenWidth()), static_cast<uint32_t>(screenMode.GetScreenHeight()));
2100 auto screenBounds = RRect({ 0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight() }, 0.0f, 0.0f);
2101 auto screenRefreshRate = screenMode.GetScreenRefreshRate();
2102 TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenCapability ScreenId: %{public}" PRIu64, screenId);
2103 auto screenCapability = rsInterface_.GetScreenCapability(screenId);
2104 HiviewDFX::XCollie::GetInstance().CancelTimer(id);
2105 TLOGW(WmsLogTag::DMS, "Call RS interface end, create ScreenProperty begin");
2106 InitScreenProperty(screenId, screenMode, screenCapability, property);
2107
2108 if (isDensityDpiLoad_) {
2109 if (screenId == SCREEN_ID_MAIN) {
2110 TLOGW(WmsLogTag::DMS, "subDensityDpi_ = %{public}f", subDensityDpi_);
2111 property.SetVirtualPixelRatio(subDensityDpi_);
2112 property.SetDefaultDensity(subDensityDpi_);
2113 property.SetDensityInCurResolution(subDensityDpi_);
2114 } else {
2115 TLOGW(WmsLogTag::DMS, "densityDpi_ = %{public}f", densityDpi_);
2116 property.SetVirtualPixelRatio(densityDpi_);
2117 property.SetDefaultDensity(densityDpi_);
2118 property.SetDensityInCurResolution(densityDpi_);
2119 }
2120 } else {
2121 property.UpdateVirtualPixelRatio(screenBounds);
2122 }
2123 property.SetRefreshRate(screenRefreshRate);
2124 property.SetDefaultDeviceRotationOffset(defaultDeviceRotationOffset_);
2125 #ifdef FOLD_ABILITY_ENABLE
2126 if (foldScreenController_ != nullptr && screenId == 0
2127 && (SCREEN_ROTATION_OFFSET == ROTATION_90 || SCREEN_ROTATION_OFFSET == ROTATION_270)) {
2128 screenBounds = RRect({ 0, 0, screenMode.GetScreenHeight(), screenMode.GetScreenWidth() }, 0.0f, 0.0f);
2129 property.SetBounds(screenBounds);
2130 }
2131 sptr<FoldCreaseRegion> creaseRegion = GetCurrentFoldCreaseRegion();
2132 if (creaseRegion != nullptr) {
2133 std::vector<DMRect> creaseRects = creaseRegion->GetCreaseRects();
2134 if (creaseRects.size() > 0) {
2135 property.SetCreaseRect(creaseRects[0]);
2136 }
2137 }
2138 #endif
2139 property.CalcDefaultDisplayOrientation();
2140 property.SetScreenShape(ScreenSettingHelper::GetScreenShape(screenId));
2141 }
2142
InitScreenProperty(ScreenId screenId,RSScreenModeInfo & screenMode,RSScreenCapability & screenCapability,ScreenProperty & property)2143 void ScreenSessionManager::InitScreenProperty(ScreenId screenId, RSScreenModeInfo& screenMode,
2144 RSScreenCapability& screenCapability, ScreenProperty& property)
2145 {
2146 auto screenBounds = RRect({ 0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight() }, 0.0f, 0.0f);
2147 property.SetRotation(0.0f);
2148 property.SetPhyWidth(screenCapability.GetPhyWidth());
2149 property.SetPhyHeight(screenCapability.GetPhyHeight());
2150 property.SetValidWidth(screenBounds.rect_.width_);
2151 property.SetValidHeight(screenBounds.rect_.height_);
2152 property.SetDpiPhyBounds(screenCapability.GetPhyWidth(), screenCapability.GetPhyHeight());
2153 property.SetPhyBounds(screenBounds);
2154 property.SetBounds(screenBounds);
2155 property.SetAvailableArea({0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight()});
2156 property.SetPhysicalTouchBounds();
2157 property.SetInputOffsetY();
2158 property.SetCurrentOffScreenRendering(false);
2159 property.SetScreenRealWidth(property.GetBounds().rect_.GetWidth());
2160 property.SetScreenRealHeight(property.GetBounds().rect_.GetHeight());
2161 property.SetScreenRealPPI();
2162 property.SetScreenRealDPI();
2163 }
2164
GetInternalWidth()2165 void ScreenSessionManager::GetInternalWidth()
2166 {
2167 ScreenId screenId = GetInternalScreenId();
2168 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2169 if (screenSession == nullptr) {
2170 TLOGE(WmsLogTag::DMS, "screen session is null");
2171 return;
2172 }
2173 ScreenProperty screenProperty = screenSession->GetScreenProperty();
2174 uint32_t screenWidth = screenProperty.GetScreenRealWidth();
2175 uint32_t screenHeight = screenProperty.GetScreenRealHeight();
2176 g_internalWidth = (screenWidth > screenHeight) ? screenWidth : screenHeight;
2177 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", g_internalWidth is:%{public}u",
2178 screenId, static_cast<uint32_t>(g_internalWidth));
2179 return;
2180 }
2181
InitExtendScreenProperty(ScreenId screenId,sptr<ScreenSession> session,ScreenProperty property)2182 void ScreenSessionManager::InitExtendScreenProperty(ScreenId screenId, sptr<ScreenSession> session,
2183 ScreenProperty property)
2184 {
2185 if (!g_isPcDevice) {
2186 TLOGW(WmsLogTag::DMS, "not PC device");
2187 return;
2188 }
2189 bool isSupportOffScreenRendering = ScreenSceneConfig::IsSupportOffScreenRendering();
2190 if (!isSupportOffScreenRendering) {
2191 TLOGW(WmsLogTag::DMS, "xml isSupportOffScreenRendering is fasle");
2192 return;
2193 }
2194 GetInternalWidth();
2195 TLOGD(WmsLogTag::DMS, "g_internalWidth: %{public}u", static_cast<uint32_t>(g_internalWidth));
2196 float offScreenPPIThreshold = static_cast<float>(ScreenSceneConfig::GetOffScreenPPIThreshold());
2197 uint32_t screenWidth = property.GetBounds().rect_.GetWidth();
2198 uint32_t screenHeight = property.GetBounds().rect_.GetHeight();
2199 float screenPPI = property.GetScreenRealPPI();
2200 if (screenWidth == 0) {
2201 TLOGE(WmsLogTag::DMS, "screenWidth is zero");
2202 return;
2203 }
2204 if (screenWidth > FOUR_K_WIDTH) {
2205 float scale = static_cast<float>(FOUR_K_WIDTH) / screenWidth;
2206 uint32_t screenAdjustHeight = static_cast<uint32_t>(std::round(screenHeight * scale));
2207 auto screenBounds = RRect({ 0, 0, FOUR_K_WIDTH, screenAdjustHeight }, 0.0f, 0.0f);
2208 session->SetExtendProperty(screenBounds, false);
2209 session->SetAvailableArea({0, 0, FOUR_K_WIDTH, screenAdjustHeight});
2210 TLOGD(WmsLogTag::DMS, "screenWidth > 4K, screenId:%{public}" PRIu64"", screenId);
2211 } else if (screenWidth < THREE_K_WIDTH && screenPPI < offScreenPPIThreshold) {
2212 float scale = static_cast<float>(g_internalWidth) / screenWidth;
2213 uint32_t screenAdjustHeight = static_cast<uint32_t>(std::round(screenHeight * scale));
2214 auto screenBounds = RRect({ 0, 0, g_internalWidth, screenAdjustHeight }, 0.0f, 0.0f);
2215 session->SetExtendProperty(screenBounds, true);
2216 session->SetAvailableArea({0, 0, g_internalWidth, screenAdjustHeight});
2217 TLOGD(WmsLogTag::DMS, "screenWidth < g_internalWidth, screenId:%{public}" PRIu64"", screenId);
2218 } else {
2219 TLOGW(WmsLogTag::DMS, "no need adjust, screenId:%{public}" PRIu64"", screenId);
2220 return;
2221 }
2222 std::ostringstream oss;
2223 oss << "screenId:" << screenId
2224 << ", screenWidth: " << session->GetScreenProperty().GetBounds().rect_.GetWidth()
2225 << ", screenHeight: " << session->GetScreenProperty().GetBounds().rect_.GetHeight()
2226 << ", propertyCurrentOffScreenRendering: " << session->GetScreenProperty().GetCurrentOffScreenRendering()
2227 << ", screenPPI: " << screenPPI;
2228 TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
2229 }
2230
SetExtendedScreenFallbackPlan(ScreenId screenId)2231 void ScreenSessionManager::SetExtendedScreenFallbackPlan(ScreenId screenId)
2232 {
2233 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2234 if (screenSession == nullptr) {
2235 TLOGE(WmsLogTag::DMS, "screen session is null");
2236 return;
2237 }
2238 if (screenSession->GetIsInternal()) {
2239 TLOGW(WmsLogTag::DMS, "screen is internal");
2240 return;
2241 }
2242 ScreenProperty screenProperty = screenSession->GetScreenProperty();
2243 if (!screenProperty.GetCurrentOffScreenRendering()) {
2244 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", propertyCurrentOffScreenRendering is false", screenId);
2245 return;
2246 }
2247 uint32_t screenAdjustWidth = 0;
2248 uint32_t screenAdjustHeight = 0;
2249 if (screenSession ->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
2250 TLOGD(WmsLogTag::DMS, "Screen is mirror");
2251 screenAdjustWidth = screenProperty.GetScreenRealWidth();
2252 screenAdjustHeight = screenProperty.GetScreenRealHeight();
2253 } else {
2254 TLOGD(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", setPhysicalScreenResolution", screenId);
2255 screenAdjustWidth = screenProperty.GetBounds().rect_.GetWidth();
2256 screenAdjustHeight = screenProperty.GetBounds().rect_.GetHeight();
2257 }
2258 ScreenId rsScreenId;
2259 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
2260 TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
2261 return;
2262 }
2263 int32_t res = -1;
2264 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetPhysicalScreenResolution(%" PRIu64")", screenId);
2265 res = rsInterface_.SetPhysicalScreenResolution(rsScreenId, screenAdjustWidth, screenAdjustHeight);
2266 screenSession->Resize(screenAdjustWidth, screenAdjustHeight, false);
2267 if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
2268 screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::UNDEFINED);
2269 }
2270 if (res != StatusCode::SUCCESS) {
2271 TLOGE(WmsLogTag::DMS, "RS SetPhysicalScreenResolution failed.");
2272 screenEventTracker_.RecordEvent("SetPhysicalScreenResolution failed.");
2273 } else {
2274 TLOGD(WmsLogTag::DMS, "RS SetPhysicalScreenResolution success.");
2275 screenEventTracker_.RecordEvent("SetPhysicalScreenResolution success.");
2276 }
2277 std::ostringstream oss;
2278 oss << "screenId:" << screenId << ", screenAdjustWidth: " << screenAdjustWidth
2279 << ", screenAdjustHeight: " << screenAdjustHeight;
2280 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
2281 }
2282
InitExtendScreenDensity(sptr<ScreenSession> session,ScreenProperty property)2283 void ScreenSessionManager::InitExtendScreenDensity(sptr<ScreenSession> session, ScreenProperty property)
2284 {
2285 if (session->GetScreenProperty().GetScreenType() != ScreenType::REAL || session->isInternal_) {
2286 // 表示非拓展屏
2287 TLOGW(WmsLogTag::DMS, "Not expandable screen, no need to set dpi");
2288 return;
2289 }
2290 ScreenId mainScreenId = GetDefaultScreenId();
2291 sptr<ScreenSession> screenSession = GetScreenSession(mainScreenId);
2292 if (screenSession == nullptr) {
2293 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
2294 return;
2295 }
2296 float extendDensity = screenSession->GetScreenProperty().GetDensity();
2297 float curResolution = screenSession->GetScreenProperty().GetDensityInCurResolution();
2298 TLOGW(WmsLogTag::DMS, "extendDensity = %{public}f", extendDensity);
2299 session->SetVirtualPixelRatio(extendDensity * EXTEND_SCREEN_DPI_PARAMETER);
2300 session->SetDefaultDensity(extendDensity * EXTEND_SCREEN_DPI_PARAMETER);
2301 session->SetDensityInCurResolution(curResolution);
2302 ScreenId screenId = session->GetScreenId();
2303 property.SetVirtualPixelRatio(extendDensity * EXTEND_SCREEN_DPI_PARAMETER);
2304 property.SetDefaultDensity(extendDensity* EXTEND_SCREEN_DPI_PARAMETER);
2305 property.SetDensityInCurResolution(curResolution);
2306 {
2307 std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
2308 phyScreenPropMap_[screenId] = property;
2309 }
2310 return;
2311 }
2312
GetOrCreateScreenSession(ScreenId screenId)2313 sptr<ScreenSession> ScreenSessionManager::GetOrCreateScreenSession(ScreenId screenId)
2314 {
2315 TLOGW(WmsLogTag::DMS, "ENTER. ScreenId: %{public}" PRIu64 "", screenId);
2316 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2317 if (screenSession) {
2318 TLOGW(WmsLogTag::DMS, "screenSession Exist ScreenId: %{public}" PRIu64, screenId);
2319 return screenSession;
2320 }
2321
2322 if (g_isPcDevice && phyScreenPropMap_.size() > 1) {
2323 // pc is none, pad&&phone is mirror
2324 TLOGW(WmsLogTag::DMS, "Only Support one External screen.");
2325 return nullptr;
2326 }
2327 screenIdManager_.UpdateScreenId(screenId, screenId);
2328
2329 ScreenProperty property;
2330 CreateScreenProperty(screenId, property);
2331 TLOGW(WmsLogTag::DMS, "call create screen property end");
2332 screenEventTracker_.RecordEvent("CreateScreenProperty by rsInterface success.");
2333 {
2334 std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
2335 phyScreenPropMap_[screenId] = property;
2336 }
2337
2338 if (HandleFoldScreenSessionCreate(screenId) == false) {
2339 return nullptr;
2340 }
2341
2342 sptr<ScreenSession> session = GetScreenSessionInner(screenId, property);
2343 if (session == nullptr) {
2344 TLOGE(WmsLogTag::DMS, "get screen session fail ScreenId: %{public}" PRIu64, screenId);
2345 return session;
2346 }
2347 session->RegisterScreenChangeListener(this);
2348 InitExtendScreenDensity(session, property);
2349 InitAbstractScreenModesInfo(session);
2350 session->groupSmsId_ = 1;
2351 {
2352 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2353 screenSessionMap_[screenId] = session;
2354 }
2355 if (g_isPcDevice) {
2356 SetMultiScreenFrameControl();
2357 }
2358 screenEventTracker_.RecordEvent("create screen session success.");
2359 SetHdrFormats(screenId, session);
2360 SetColorSpaces(screenId, session);
2361 RegisterRefreshRateChangeListener();
2362 TLOGW(WmsLogTag::DMS, "CreateScreenSession success. ScreenId: %{public}" PRIu64 "", screenId);
2363 return session;
2364 }
2365
HandleFoldScreenSessionCreate(ScreenId screenId)2366 bool ScreenSessionManager::HandleFoldScreenSessionCreate(ScreenId screenId)
2367 {
2368 #ifdef FOLD_ABILITY_ENABLE
2369 if (foldScreenController_ != nullptr) {
2370 // sensor may earlier than screen connect, when physical screen property changed, update
2371 foldScreenController_->UpdateForPhyScreenPropertyChange();
2372 /* folder screen outer screenId is 5 */
2373 if (screenId == SCREEN_ID_MAIN) {
2374 SetPostureAndHallSensorEnabled();
2375 ScreenSensorConnector::SubscribeTentSensor();
2376 isFoldScreenOuterScreenReady_ = true;
2377 if (!FoldScreenStateInternel::IsDualDisplayFoldDevice() && isCoordinationFlag_ == false) {
2378 return false;
2379 }
2380 }
2381 }
2382 #endif
2383 return true;
2384 }
2385
SetHdrFormats(ScreenId screenId,sptr<ScreenSession> & session)2386 void ScreenSessionManager::SetHdrFormats(ScreenId screenId, sptr<ScreenSession>& session)
2387 {
2388 TLOGI(WmsLogTag::DMS, "SetHdrFormats %{public}" PRIu64, screenId);
2389 std::vector<ScreenHDRFormat> rsHdrFormat;
2390 auto status = rsInterface_.GetScreenSupportedHDRFormats(screenId, rsHdrFormat);
2391 if (static_cast<StatusCode>(status) != StatusCode::SUCCESS) {
2392 TLOGE(WmsLogTag::DMS, "get hdr format failed! status code: %{public}d", status);
2393 } else {
2394 std::vector<uint32_t> hdrFormat(rsHdrFormat.size());
2395 std::transform(rsHdrFormat.begin(), rsHdrFormat.end(), hdrFormat.begin(), [](int val) {
2396 return static_cast<uint32_t>(val);
2397 });
2398 session->SetHdrFormats(std::move(hdrFormat));
2399 }
2400 }
2401
SetColorSpaces(ScreenId screenId,sptr<ScreenSession> & session)2402 void ScreenSessionManager::SetColorSpaces(ScreenId screenId, sptr<ScreenSession>& session)
2403 {
2404 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2405 TLOGE(WmsLogTag::DMS, "spaces permission denied!");
2406 return;
2407 }
2408
2409 TLOGI(WmsLogTag::DMS, "SetColorSpaces %{public}" PRIu64, screenId);
2410 std::vector<GraphicCM_ColorSpaceType> rsColorSpace;
2411 auto status = rsInterface_.GetScreenSupportedColorSpaces(screenId, rsColorSpace);
2412 if (static_cast<StatusCode>(status) != StatusCode::SUCCESS) {
2413 TLOGE(WmsLogTag::DMS, "get color space failed! status code: %{public}d", status);
2414 } else {
2415 std::vector<uint32_t> colorSpace(rsColorSpace.size());
2416 std::transform(rsColorSpace.begin(), rsColorSpace.end(), colorSpace.begin(), [](int val) {
2417 return static_cast<uint32_t>(val);
2418 });
2419 session->SetColorSpaces(std::move(colorSpace));
2420 }
2421 }
2422
GetDefaultScreenId()2423 ScreenId ScreenSessionManager::GetDefaultScreenId()
2424 {
2425 if (defaultScreenId_ == INVALID_SCREEN_ID) {
2426 defaultScreenId_ = rsInterface_.GetDefaultScreenId();
2427 std::ostringstream oss;
2428 oss << "Default screen id : " << defaultScreenId_;
2429 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
2430 screenEventTracker_.RecordEvent(oss.str());
2431 }
2432 return defaultScreenId_;
2433 }
2434
WakeUpBegin(PowerStateChangeReason reason)2435 bool ScreenSessionManager::WakeUpBegin(PowerStateChangeReason reason)
2436 {
2437 // 该接口当前只有Power调用
2438 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:WakeUpBegin(%u)", reason);
2439 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2440 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2441 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2442 return false;
2443 }
2444 TLOGI(WmsLogTag::DMS, "[UL_POWER]WakeUpBegin reason: %{public}u", reason);
2445 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_START_DREAM) {
2446 TLOGI(WmsLogTag::DMS, "[UL_POWER]wakeup cannot start dream");
2447 return false;
2448 }
2449 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_END_DREAM) {
2450 NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_END_DREAM, EventStatus::BEGIN, reason);
2451 return BlockScreenWaitPictureFrameByCV(false);
2452 }
2453 currentWakeUpReason_ = reason;
2454 // 多屏协作灭屏不通知锁屏
2455 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
2456 isMultiScreenCollaboration_ = true;
2457 return true;
2458 }
2459 lastWakeUpReason_ = reason;
2460 return NotifyDisplayPowerEvent(DisplayPowerEvent::WAKE_UP, EventStatus::BEGIN, reason);
2461 }
2462
WakeUpEnd()2463 bool ScreenSessionManager::WakeUpEnd()
2464 {
2465 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:WakeUpEnd");
2466 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2467 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2468 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2469 return false;
2470 }
2471 TLOGI(WmsLogTag::DMS, "[UL_POWER]WakeUpEnd enter");
2472 // 多屏协作灭屏不通知锁屏
2473 if (isMultiScreenCollaboration_) {
2474 isMultiScreenCollaboration_ = false;
2475 return true;
2476 }
2477 return NotifyDisplayPowerEvent(DisplayPowerEvent::WAKE_UP, EventStatus::END,
2478 PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
2479 }
2480
SuspendBegin(PowerStateChangeReason reason)2481 bool ScreenSessionManager::SuspendBegin(PowerStateChangeReason reason)
2482 {
2483 // only power use
2484 powerStateChangeReason_ = reason;
2485 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:SuspendBegin(%u)", reason);
2486 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2487 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2488 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2489 return false;
2490 }
2491 TLOGI(WmsLogTag::DMS, "[UL_POWER]Reason: %{public}u", static_cast<uint32_t>(reason));
2492 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_END_DREAM) {
2493 TLOGI(WmsLogTag::DMS, "[UL_POWER]suspend cannot end dream");
2494 return false;
2495 }
2496 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_START_DREAM) {
2497 NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_START_DREAM, EventStatus::BEGIN, reason);
2498 return BlockScreenWaitPictureFrameByCV(true);
2499 }
2500 gotScreenlockFingerprint_ = false;
2501 lastWakeUpReason_ = PowerStateChangeReason::STATE_CHANGE_REASON_INIT;
2502 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
2503 lastWakeUpReason_ = PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF;
2504 }
2505 // 多屏协作灭屏不通知锁屏
2506 gotScreenOffNotify_ = false;
2507 if (!g_isPcDevice && reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT &&
2508 reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_SUCCESS &&
2509 reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_ON &&
2510 reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
2511 sessionDisplayPowerController_->canCancelSuspendNotify_ = true;
2512 }
2513 sessionDisplayPowerController_->isSuspendBegin_ = true;
2514 sessionDisplayPowerController_->SuspendBegin(reason);
2515 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
2516 isMultiScreenCollaboration_ = true;
2517 return true;
2518 }
2519 return NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::BEGIN, reason);
2520 }
2521
SuspendEnd()2522 bool ScreenSessionManager::SuspendEnd()
2523 {
2524 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2525 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2526 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2527 return false;
2528 }
2529 TLOGI(WmsLogTag::DMS, "[UL_POWER] enter");
2530 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:SuspendEnd");
2531 // 多屏协作灭屏不通知锁屏
2532 if (isMultiScreenCollaboration_) {
2533 isMultiScreenCollaboration_ = false;
2534 return true;
2535 }
2536 return NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::END,
2537 PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
2538 }
2539
GetInternalScreenId()2540 ScreenId ScreenSessionManager::GetInternalScreenId()
2541 {
2542 ScreenId screenId = SCREEN_ID_INVALID;
2543 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2544 for (auto sessionIt : screenSessionMap_) {
2545 auto screenSession = sessionIt.second;
2546 if (screenSession == nullptr) {
2547 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
2548 continue;
2549 }
2550 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && screenSession->isInternal_) {
2551 TLOGI(WmsLogTag::DMS, "found screenId = %{public}" PRIu64, sessionIt.first);
2552 screenId = sessionIt.first;
2553 break;
2554 }
2555 }
2556 return screenId;
2557 }
2558
GetInternalAndExternalSession(sptr<ScreenSession> & internalSession,sptr<ScreenSession> & externalSession)2559 void ScreenSessionManager::GetInternalAndExternalSession(sptr<ScreenSession>& internalSession,
2560 sptr<ScreenSession>& externalSession)
2561 {
2562 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2563 for (auto sessionIt : screenSessionMap_) {
2564 auto screenSession = sessionIt.second;
2565 if (screenSession == nullptr) {
2566 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
2567 continue;
2568 }
2569 if (!screenSession->GetIsCurrentInUse()) {
2570 TLOGE(WmsLogTag::DMS, "screenSession not in use!");
2571 continue;
2572 }
2573 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && screenSession->isInternal_) {
2574 TLOGI(WmsLogTag::DMS, "found internalSession, screenId = %{public}" PRIu64, sessionIt.first);
2575 internalSession = screenSession;
2576 } else {
2577 TLOGI(WmsLogTag::DMS, "found externalSession, screenId = %{public}" PRIu64, sessionIt.first);
2578 externalSession = screenSession;
2579 }
2580 }
2581 }
2582
SetScreenPowerById(ScreenId screenId,ScreenPowerState state,PowerStateChangeReason reason)2583 bool ScreenSessionManager::SetScreenPowerById(ScreenId screenId, ScreenPowerState state,
2584 PowerStateChangeReason reason)
2585 {
2586 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2587 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2588 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2589 return false;
2590 }
2591
2592 TLOGI(WmsLogTag::DMS, "screen id:%{public}" PRIu64
2593 ", state:%{public}u, reason:%{public}u", screenId, state, static_cast<uint32_t>(reason));
2594
2595 sptr<ScreenSession> internalSession;
2596 sptr<ScreenSession> externalSession;
2597 GetInternalAndExternalSession(internalSession, externalSession);
2598 ScreenPowerStatus status;
2599 switch (state) {
2600 case ScreenPowerState::POWER_ON: {
2601 status = ScreenPowerStatus::POWER_STATUS_ON;
2602 MultiScreenManager::GetInstance().InternalScreenOnChange(internalSession, externalSession);
2603 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_ON");
2604 break;
2605 }
2606 case ScreenPowerState::POWER_OFF: {
2607 status = ScreenPowerStatus::POWER_STATUS_OFF;
2608 MultiScreenManager::GetInstance().InternalScreenOffChange(internalSession, externalSession);
2609 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_OFF");
2610 break;
2611 }
2612 default: {
2613 TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerById state not support");
2614 return false;
2615 }
2616 }
2617
2618 CallRsSetScreenPowerStatusSync(screenId, status);
2619 return true;
2620 }
2621
SetLastScreenMode(sptr<ScreenSession> firstSession,sptr<ScreenSession> secondarySession)2622 void ScreenSessionManager::SetLastScreenMode(sptr<ScreenSession> firstSession, sptr<ScreenSession> secondarySession)
2623 {
2624 #ifdef WM_MULTI_SCREEN_ENABLE
2625 if (firstSession == nullptr || secondarySession == nullptr) {
2626 TLOGE(WmsLogTag::DMS, "first or second screen is null");
2627 return;
2628 }
2629
2630 ScreenId mainScreenId = SCREEN_ID_INVALID;
2631 MultiScreenMode secondaryScreenMode = MultiScreenMode::SCREEN_MIRROR;
2632 {
2633 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2634 for (auto sessionIt : screenSessionMap_) {
2635 auto screenSession = sessionIt.second;
2636 if (screenSession == nullptr) {
2637 TLOGW(WmsLogTag::DMS, "screenSession is nullptr!");
2638 continue;
2639 }
2640 if (screenSession != firstSession && screenSession != secondarySession) {
2641 continue;
2642 }
2643 if (!screenSession->GetIsCurrentInUse()) {
2644 TLOGE(WmsLogTag::DMS, "screenSession not in use!");
2645 continue;
2646 }
2647 ScreenCombination screenCombination = screenSession->GetScreenCombination();
2648 if (screenCombination == ScreenCombination::SCREEN_MAIN) {
2649 mainScreenId = sessionIt.first;
2650 TLOGI(WmsLogTag::DMS, "found main screen");
2651 } else if (screenCombination == ScreenCombination::SCREEN_MIRROR) {
2652 secondaryScreenMode = MultiScreenMode::SCREEN_MIRROR;
2653 TLOGI(WmsLogTag::DMS, "found mirror screen");
2654 } else if (screenCombination == ScreenCombination::SCREEN_EXTEND) {
2655 secondaryScreenMode = MultiScreenMode::SCREEN_EXTEND;
2656 TLOGI(WmsLogTag::DMS, "found extend screen");
2657 } else {
2658 TLOGE(WmsLogTag::DMS, "screen id or screen mode error");
2659 }
2660 }
2661 }
2662
2663 if (mainScreenId == SCREEN_ID_INVALID) {
2664 TLOGE(WmsLogTag::DMS, "param error!");
2665 return;
2666 }
2667 MultiScreenManager::GetInstance().SetLastScreenMode(mainScreenId, secondaryScreenMode);
2668 #endif
2669 }
2670
IsPreBrightAuthFail(void)2671 bool ScreenSessionManager::IsPreBrightAuthFail(void)
2672 {
2673 return lastWakeUpReason_ == PowerStateChangeReason::
2674 STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF;
2675 }
2676
BlockSetDisplayState(void)2677 bool ScreenSessionManager::BlockSetDisplayState(void)
2678 {
2679 return prePowerStateChangeReason_ == PowerStateChangeReason::POWER_BUTTON;
2680 }
2681
SetDisplayState(DisplayState state)2682 bool ScreenSessionManager::SetDisplayState(DisplayState state)
2683 {
2684 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2685 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2686 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2687 return false;
2688 }
2689 if (!sessionDisplayPowerController_) {
2690 TLOGE(WmsLogTag::DMS, "[UL_POWER]sessionDisplayPowerController_ is null");
2691 return false;
2692 }
2693 TLOGI(WmsLogTag::DMS, "[UL_POWER] enter");
2694 auto screenIds = GetAllScreenIds();
2695 if (screenIds.empty()) {
2696 TLOGI(WmsLogTag::DMS, "[UL_POWER]no screen info");
2697 return sessionDisplayPowerController_->SetDisplayState(state);
2698 }
2699
2700 UpdateDisplayState(screenIds, state);
2701 bool ret = sessionDisplayPowerController_->SetDisplayState(state);
2702 if (!ret && state == DisplayState::OFF) {
2703 state = lastDisplayState_;
2704 UpdateDisplayState(screenIds, state);
2705 }
2706 lastDisplayState_ = state;
2707 return ret;
2708 }
2709
UpdateDisplayState(std::vector<ScreenId> screenIds,DisplayState state)2710 void ScreenSessionManager::UpdateDisplayState(std::vector<ScreenId> screenIds, DisplayState state)
2711 {
2712 for (auto screenId : screenIds) {
2713 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2714 if (screenSession == nullptr) {
2715 TLOGW(WmsLogTag::DMS, "[UL_POWER] cannot get ScreenSession, screenId: %{public}" PRIu64"",
2716 screenId);
2717 continue;
2718 }
2719 screenSession->UpdateDisplayState(state);
2720 TLOGI(WmsLogTag::DMS, "[UL_POWER]set screenSession displayState property: %{public}u",
2721 screenSession->GetScreenProperty().GetDisplayState());
2722 }
2723 }
2724
BlockScreenOnByCV(void)2725 void ScreenSessionManager::BlockScreenOnByCV(void)
2726 {
2727 if (keyguardDrawnDone_ == false) {
2728 TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOnCV_ set");
2729 needScreenOnWhenKeyguardNotify_ = true;
2730 std::unique_lock<std::mutex> lock(screenOnMutex_);
2731 if (screenOnCV_.wait_for(lock, std::chrono::milliseconds(screenOnDelay_)) == std::cv_status::timeout) {
2732 TLOGI(WmsLogTag::DMS, "[UL_POWER]wait ScreenOnCV_ timeout");
2733 }
2734 }
2735 }
2736
BlockScreenOffByCV(void)2737 void ScreenSessionManager::BlockScreenOffByCV(void)
2738 {
2739 if (gotScreenOffNotify_ == false) {
2740 TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOffCV_ set, delay:%{public}d", screenOffDelay_);
2741 needScreenOffNotify_ = true;
2742 std::unique_lock<std::mutex> lock(screenOffMutex_);
2743 if (screenOffCV_.wait_for(lock, std::chrono::milliseconds(screenOffDelay_)) == std::cv_status::timeout) {
2744 isScreenLockSuspend_ = false;
2745 needScreenOffNotify_ = false;
2746 TLOGI(WmsLogTag::DMS, "[UL_POWER]wait ScreenOffCV_ timeout, isScreenLockSuspend_ is false");
2747 }
2748 }
2749 }
2750
TryToCancelScreenOff()2751 bool ScreenSessionManager::TryToCancelScreenOff()
2752 {
2753 std::lock_guard<std::mutex> notifyLock(sessionDisplayPowerController_->notifyMutex_);
2754 TLOGI(WmsLogTag::DMS, "[UL_POWER]about to cancel suspend, can:%{public}d, got:%{public}d, need:%{public}d",
2755 sessionDisplayPowerController_->canCancelSuspendNotify_, gotScreenOffNotify_, needScreenOffNotify_);
2756 if (sessionDisplayPowerController_->canCancelSuspendNotify_) {
2757 sessionDisplayPowerController_->needCancelNotify_ = true;
2758 TLOGI(WmsLogTag::DMS, "[UL_POWER]notify cancel screenoff");
2759 ScreenSessionManager::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_OFF_CANCELED,
2760 EventStatus::BEGIN, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
2761 return true;
2762 }
2763 if (gotScreenOffNotify_ == false && needScreenOffNotify_ == true) {
2764 std::unique_lock <std::mutex> lock(screenOffMutex_);
2765 sessionDisplayPowerController_->canceledSuspend_ = true;
2766 screenOffCV_.notify_all();
2767 needScreenOffNotify_ = false;
2768 TLOGI(WmsLogTag::DMS, "[UL_POWER]cancel wait and notify cancel screenoff");
2769 ScreenSessionManager::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_OFF_CANCELED,
2770 EventStatus::BEGIN, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
2771 return true;
2772 }
2773 TLOGW(WmsLogTag::DMS, "[UL_POWER]failed to cancel suspend");
2774 return false;
2775 }
2776
ForceSkipScreenOffAnimation()2777 void ScreenSessionManager::ForceSkipScreenOffAnimation()
2778 {
2779 std::lock_guard<std::mutex> notifyLock(sessionDisplayPowerController_->notifyMutex_);
2780 TLOGI(WmsLogTag::DMS, "[UL_POWER]about to skip animation, can:%{public}d, got:%{public}d, need:%{public}d",
2781 sessionDisplayPowerController_->canCancelSuspendNotify_, gotScreenOffNotify_, needScreenOffNotify_);
2782 if (sessionDisplayPowerController_->canCancelSuspendNotify_) {
2783 sessionDisplayPowerController_->skipScreenOffBlock_ = true;
2784 TLOGI(WmsLogTag::DMS, "[UL_POWER]skip screenoff animation");
2785 return;
2786 }
2787 if (gotScreenOffNotify_ == false && needScreenOffNotify_ == true) {
2788 std::unique_lock <std::mutex> lock(screenOffMutex_);
2789 screenOffCV_.notify_all();
2790 needScreenOffNotify_ = false;
2791 TLOGI(WmsLogTag::DMS, "[UL_POWER]skip wait");
2792 return;
2793 }
2794 }
2795
SetScreenBrightness(uint64_t screenId,uint32_t level)2796 bool ScreenSessionManager::SetScreenBrightness(uint64_t screenId, uint32_t level)
2797 {
2798 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2799 TLOGE(WmsLogTag::DMS, "set screen brightness permission denied!");
2800 return false;
2801 }
2802 TLOGD(WmsLogTag::DMS, "screenId:%{public}" PRIu64", level:%{public}u,", screenId, level);
2803 RSInterfaces::GetInstance().SetScreenBacklight(screenId, level);
2804 return true;
2805 }
2806
GetScreenBrightness(uint64_t screenId)2807 uint32_t ScreenSessionManager::GetScreenBrightness(uint64_t screenId)
2808 {
2809 uint32_t level = static_cast<uint32_t>(RSInterfaces::GetInstance().GetScreenBacklight(screenId));
2810 TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", level:%{public}u,", screenId, level);
2811 return level;
2812 }
2813
SetScreenOffDelayTime(int32_t delay)2814 int32_t ScreenSessionManager::SetScreenOffDelayTime(int32_t delay)
2815 {
2816 DmsXcollie dmsXcollie("DMS:SetScreenOffDelayTime", XCOLLIE_TIMEOUT_10S);
2817 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2818 TLOGE(WmsLogTag::DMS, "set screen off delay time permission denied!");
2819 return 0;
2820 }
2821
2822 if (delay > SCREEN_OFF_MIN_DELAY_TIME && delay < CV_WAIT_SCREENOFF_MS) {
2823 screenOffDelay_ = CV_WAIT_SCREENOFF_MS;
2824 } else if (delay > CV_WAIT_SCREENOFF_MS_MAX) {
2825 screenOffDelay_ = CV_WAIT_SCREENOFF_MS_MAX;
2826 } else {
2827 screenOffDelay_ = delay;
2828 }
2829 TLOGI(WmsLogTag::DMS, "delay:%{public}d, screenOffDelay_:%{public}d",
2830 delay, screenOffDelay_);
2831 return screenOffDelay_;
2832 }
2833
SetScreenOnDelayTime(int32_t delay)2834 int32_t ScreenSessionManager::SetScreenOnDelayTime(int32_t delay)
2835 {
2836 DmsXcollie dmsXcollie("DMS:SetScreenOnDelayTime", XCOLLIE_TIMEOUT_10S);
2837 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2838 TLOGE(WmsLogTag::DMS, "set screen on delay time permission denied!");
2839 return 0;
2840 }
2841
2842 if (delay > CV_WAIT_SCREENON_MS) {
2843 screenOnDelay_ = CV_WAIT_SCREENON_MS;
2844 } else {
2845 screenOnDelay_ = delay;
2846 }
2847 TLOGI(WmsLogTag::DMS, "delay:%{public}d, screenOnDelay_:%{public}d",
2848 delay, screenOnDelay_);
2849 return screenOnDelay_;
2850 }
2851
SetCameraStatus(int32_t cameraStatus,int32_t cameraPosition)2852 void ScreenSessionManager::SetCameraStatus(int32_t cameraStatus, int32_t cameraPosition)
2853 {
2854 #ifdef WM_CAM_MODE_ABILITY_ENABLE
2855 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2856 TLOGE(WmsLogTag::DMS, "set camera status permission denied!");
2857 return;
2858 }
2859
2860 if ((cameraStatus_ == cameraStatus) && (cameraPosition_ == cameraPosition)) {
2861 return; // no need to update
2862 }
2863 cameraStatus_ = cameraStatus;
2864 cameraPosition_ = cameraPosition;
2865 TLOGI(WmsLogTag::DMS, "SetCameraStatus, cameraStatus:%{public}d, cameraPosition:%{public}d",
2866 cameraStatus, cameraPosition);
2867 #endif
2868 }
2869
IsScreenLockSuspend(void)2870 bool ScreenSessionManager::IsScreenLockSuspend(void)
2871 {
2872 return isScreenLockSuspend_;
2873 }
2874
NotifyDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)2875 void ScreenSessionManager::NotifyDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
2876 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
2877 {
2878 if (clientProxy_) {
2879 clientProxy_->OnDisplayStateChanged(defaultDisplayId, displayInfo, displayInfoMap, type);
2880 }
2881 }
2882
NotifyScreenshot(DisplayId displayId)2883 void ScreenSessionManager::NotifyScreenshot(DisplayId displayId)
2884 {
2885 if (clientProxy_) {
2886 clientProxy_->OnScreenshot(displayId);
2887 }
2888 }
2889
SetSpecifiedScreenPower(ScreenId screenId,ScreenPowerState state,PowerStateChangeReason reason)2890 bool ScreenSessionManager::SetSpecifiedScreenPower(ScreenId screenId, ScreenPowerState state,
2891 PowerStateChangeReason reason)
2892 {
2893 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2894 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
2895 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2896 return false;
2897 }
2898 TLOGI(WmsLogTag::DMS, "screen id:%{public}" PRIu64 ", state:%{public}u",
2899 screenId, state);
2900
2901 ScreenPowerStatus status;
2902 switch (state) {
2903 case ScreenPowerState::POWER_ON: {
2904 status = ScreenPowerStatus::POWER_STATUS_ON;
2905 break;
2906 }
2907 case ScreenPowerState::POWER_OFF: {
2908 status = ScreenPowerStatus::POWER_STATUS_OFF;
2909 break;
2910 }
2911 default: {
2912 TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerStatus state not support");
2913 return false;
2914 }
2915 }
2916
2917 CallRsSetScreenPowerStatusSync(screenId, status);
2918 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
2919 return true;
2920 }
2921 return NotifyDisplayPowerEvent(state == ScreenPowerState::POWER_ON ? DisplayPowerEvent::DISPLAY_ON :
2922 DisplayPowerEvent::DISPLAY_OFF, EventStatus::END, reason);
2923 }
2924
SetScreenPowerForAll(ScreenPowerState state,PowerStateChangeReason reason)2925 bool ScreenSessionManager::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)
2926 {
2927 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2928 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2929 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2930 return false;
2931 }
2932 TLOGI(WmsLogTag::DMS, "[UL_POWER]state: %{public}u, reason: %{public}u",
2933 static_cast<uint32_t>(state), static_cast<uint32_t>(reason));
2934 ScreenPowerStatus status;
2935
2936 if (!GetPowerStatus(state, reason, status)) {
2937 return false;
2938 }
2939 gotScreenOffNotify_ = false;
2940 keyguardDrawnDone_ = false;
2941 TLOGI(WmsLogTag::DMS, "keyguardDrawnDone_ is false");
2942 prePowerStateChangeReason_ = reason;
2943 return SetScreenPower(status, reason);
2944 }
2945
GetPowerStatus(ScreenPowerState state,PowerStateChangeReason reason,ScreenPowerStatus & status)2946 bool ScreenSessionManager::GetPowerStatus(ScreenPowerState state, PowerStateChangeReason reason,
2947 ScreenPowerStatus& status)
2948 {
2949 switch (state) {
2950 case ScreenPowerState::POWER_ON: {
2951 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT) {
2952 // 预亮屏
2953 status = ScreenPowerStatus::POWER_STATUS_ON_ADVANCED;
2954 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_ON_ADVANCED");
2955 } else {
2956 status = ScreenPowerStatus::POWER_STATUS_ON;
2957 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_ON");
2958 }
2959 break;
2960 }
2961 case ScreenPowerState::POWER_OFF: {
2962 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
2963 // 预亮屏时指纹认证失败
2964 status = ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED;
2965 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_OFF_ADVANCED");
2966 } else {
2967 status = ScreenPowerStatus::POWER_STATUS_OFF;
2968 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_OFF");
2969 }
2970 rsInterface_.MarkPowerOffNeedProcessOneFrame();
2971 break;
2972 }
2973 case ScreenPowerState::POWER_SUSPEND: {
2974 status = ScreenPowerStatus::POWER_STATUS_SUSPEND;
2975 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_SUSPEND");
2976 rsInterface_.MarkPowerOffNeedProcessOneFrame();
2977 break;
2978 }
2979 case ScreenPowerState::POWER_DOZE: {
2980 status = ScreenPowerStatus::POWER_STATUS_DOZE;
2981 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_DOZE");
2982 break;
2983 }
2984 case ScreenPowerState::POWER_DOZE_SUSPEND: {
2985 status = ScreenPowerStatus::POWER_STATUS_DOZE_SUSPEND;
2986 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_DOZE_SUSPEND");
2987 break;
2988 }
2989 default: {
2990 TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerStatus state not support");
2991 return false;
2992 }
2993 }
2994 return true;
2995 }
2996
ExitCoordination(const std::string & reason)2997 void ScreenSessionManager::ExitCoordination(const std::string& reason)
2998 {
2999 #ifdef FOLD_ABILITY_ENABLE
3000 if (GetFoldDisplayMode() != FoldDisplayMode::COORDINATION) {
3001 return;
3002 }
3003 if (foldScreenController_ != nullptr) {
3004 TLOGI(WmsLogTag::DMS, "[UL_POWER] reason:%{public}s", reason.c_str());
3005 foldScreenController_->ExitCoordination();
3006 }
3007 #endif
3008 }
3009
TryToRecoverFoldDisplayMode(ScreenPowerStatus status)3010 void ScreenSessionManager::TryToRecoverFoldDisplayMode(ScreenPowerStatus status)
3011 {
3012 #ifdef FOLD_ABILITY_ENABLE
3013 if (foldScreenController_ == nullptr) {
3014 TLOGW(WmsLogTag::DMS, "foldScreenController_ is null");
3015 return;
3016 }
3017 if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED ||
3018 status == ScreenPowerStatus::POWER_STATUS_OFF_FAKE || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3019 status == ScreenPowerStatus::POWER_STATUS_DOZE) {
3020 foldScreenController_->RecoverDisplayMode();
3021 }
3022 #endif
3023 }
3024
SetScreenPower(ScreenPowerStatus status,PowerStateChangeReason reason)3025 bool ScreenSessionManager::SetScreenPower(ScreenPowerStatus status, PowerStateChangeReason reason)
3026 {
3027 TLOGI(WmsLogTag::DMS, "[UL_POWER] enter status:%{public}u", status);
3028 auto screenIds = GetAllScreenIds();
3029 if (screenIds.empty()) {
3030 TLOGI(WmsLogTag::DMS, "[UL_POWER] screenIds empty");
3031 return false;
3032 }
3033
3034 if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3035 status == ScreenPowerStatus::POWER_STATUS_DOZE) {
3036 ExitCoordination("Press PowerKey");
3037 }
3038 DisplayPowerEvent notifyEvent = DisplayPowerEvent::DISPLAY_OFF;
3039 auto iter = SCREEN_STATUS_POWER_EVENT_MAP.find(status);
3040 if (iter != SCREEN_STATUS_POWER_EVENT_MAP.end()) {
3041 notifyEvent = iter->second;
3042 }
3043 if (((status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3044 status == ScreenPowerStatus::POWER_STATUS_DOZE) &&
3045 gotScreenlockFingerprint_ == true) &&
3046 prePowerStateChangeReason_ != PowerStateChangeReason::STATE_CHANGE_REASON_SHUT_DOWN) {
3047 gotScreenlockFingerprint_ = false;
3048 TLOGI(WmsLogTag::DMS, "[UL_POWER] screenlockFingerprint or shutdown");
3049 return NotifyDisplayPowerEvent(notifyEvent, EventStatus::END, reason);
3050 }
3051 #ifdef FOLD_ABILITY_ENABLE
3052 if (foldScreenController_ != nullptr) {
3053 CallRsSetScreenPowerStatusSyncForFold(status);
3054 CallRsSetScreenPowerStatusSyncForExtend(screenIds, status);
3055 TryToRecoverFoldDisplayMode(status);
3056 } else {
3057 SetRsSetScreenPowerStatusSync(screenIds, status);
3058 }
3059 #else
3060 SetRsSetScreenPowerStatusSync(screenIds, status);
3061 #endif
3062 HandlerSensor(status, reason);
3063 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3064 return true;
3065 }
3066 if ((status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3067 status == ScreenPowerStatus::POWER_STATUS_DOZE) &&
3068 gotScreenlockFingerprint_ == true) {
3069 gotScreenlockFingerprint_ = false;
3070 }
3071
3072 return NotifyDisplayPowerEvent(notifyEvent, EventStatus::END, reason);
3073 }
3074
SetRsSetScreenPowerStatusSync(const std::vector<ScreenId> & screenIds,ScreenPowerStatus status)3075 void ScreenSessionManager::SetRsSetScreenPowerStatusSync(const std::vector<ScreenId>& screenIds,
3076 ScreenPowerStatus status)
3077 {
3078 if (!g_isPcDevice) {
3079 for (auto screenId : screenIds) {
3080 CallRsSetScreenPowerStatusSync(screenId, status);
3081 }
3082 } else {
3083 TLOGI(WmsLogTag::DMS, "[UL_POWER] isPcDevice");
3084 for (auto screenId : screenIds) {
3085 if (screenId == SCREEN_ID_DEFAULT) {
3086 TLOGI(WmsLogTag::DMS, "[UL_POWER] screen id is 0, pass");
3087 continue;
3088 }
3089 CallRsSetScreenPowerStatusSync(screenId, status);
3090 }
3091 TLOGI(WmsLogTag::DMS, "[UL_POWER] screen 0 power off");
3092 CallRsSetScreenPowerStatusSync(SCREEN_ID_DEFAULT, status);
3093 }
3094 }
3095
CallRsSetScreenPowerStatusSyncForExtend(const std::vector<ScreenId> & screenIds,ScreenPowerStatus status)3096 void ScreenSessionManager::CallRsSetScreenPowerStatusSyncForExtend(const std::vector<ScreenId>& screenIds,
3097 ScreenPowerStatus status)
3098 {
3099 for (auto screenId : screenIds) {
3100 auto session = GetScreenSession(screenId);
3101 if (session && session->GetScreenProperty().GetScreenType() == ScreenType::REAL && !session->isInternal_) {
3102 CallRsSetScreenPowerStatusSync(screenId, status);
3103 }
3104 }
3105 }
3106 #ifdef FOLD_ABILITY_ENABLE
SetScreenPowerForFold(ScreenPowerStatus status)3107 void ScreenSessionManager::SetScreenPowerForFold(ScreenPowerStatus status)
3108 {
3109 if (foldScreenController_ == nullptr) {
3110 TLOGW(WmsLogTag::DMS, "foldScreenController_ is null");
3111 return;
3112 }
3113 SetScreenPowerForFold(foldScreenController_->GetCurrentScreenId(), status);
3114 }
3115
SetScreenPowerForFold(ScreenId screenId,ScreenPowerStatus status)3116 void ScreenSessionManager::SetScreenPowerForFold(ScreenId screenId, ScreenPowerStatus status)
3117 {
3118 if (status != ScreenPowerStatus::POWER_STATUS_OFF) {
3119 rsInterface_.SetScreenPowerStatus(screenId, status);
3120 return;
3121 }
3122 ScreenPowerStatus preStatus = rsInterface_.GetScreenPowerStatus(screenId);
3123 if (preStatus != ScreenPowerStatus::POWER_STATUS_ON_ADVANCED) {
3124 rsInterface_.SetScreenPowerStatus(screenId, status);
3125 return;
3126 }
3127 TLOGW(WmsLogTag::DMS,
3128 "screenId = %{public}" PRIu64\
3129 ", prepare set power status %{public}u, set %{public}u instead because preStatus is %{public}u",
3130 screenId,
3131 ScreenPowerStatus::POWER_STATUS_OFF,
3132 ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED,
3133 preStatus
3134 );
3135 rsInterface_.SetScreenPowerStatus(screenId, ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED);
3136 }
3137
TriggerDisplayModeUpdate(FoldDisplayMode targetDisplayMode)3138 void ScreenSessionManager::TriggerDisplayModeUpdate(FoldDisplayMode targetDisplayMode)
3139 {
3140 auto updateDisplayModeTask = [=] {
3141 TLOGNI(WmsLogTag::DMS, "start change displaymode to lastest mode");
3142 foldScreenController_->SetDisplayMode(targetDisplayMode);
3143 };
3144 taskScheduler_->PostAsyncTask(updateDisplayModeTask, "updateDisplayModeTask");
3145 }
3146 #endif
CallRsSetScreenPowerStatusSync(ScreenId screenId,ScreenPowerStatus status)3147 void ScreenSessionManager::CallRsSetScreenPowerStatusSync(ScreenId screenId, ScreenPowerStatus status)
3148 {
3149 auto rsSetScreenPowerStatusTask = [=] {
3150 bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
3151 if (phyMirrorEnable && !g_isPcDevice) {
3152 auto screenSession = GetScreenSession(screenId);
3153 if (screenSession == nullptr) {
3154 return;
3155 }
3156 auto sourceMode = screenSession->GetSourceMode();
3157 if (sourceMode == ScreenSourceMode::SCREEN_MIRROR &&
3158 status != ScreenPowerStatus::POWER_STATUS_ON &&
3159 powerStateChangeReason_ == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3160 return;
3161 }
3162 if (sourceMode == ScreenSourceMode::SCREEN_UNIQUE &&
3163 status != ScreenPowerStatus::POWER_STATUS_ON &&
3164 powerStateChangeReason_ == PowerStateChangeReason::STATE_CHANGE_REASON_HARD_KEY) {
3165 return;
3166 }
3167 }
3168 rsInterface_.SetScreenPowerStatus(screenId, status);
3169 };
3170 screenPowerTaskScheduler_->PostVoidSyncTask(rsSetScreenPowerStatusTask, "rsInterface_.SetScreenPowerStatus task");
3171 }
3172
CallRsSetScreenPowerStatusSyncForFold(ScreenPowerStatus status)3173 void ScreenSessionManager::CallRsSetScreenPowerStatusSyncForFold(ScreenPowerStatus status)
3174 {
3175 #ifdef FOLD_ABILITY_ENABLE
3176 auto rsSetScreenPowerStatusTask = [=] {
3177 if (foldScreenController_ == nullptr) {
3178 TLOGNW(WmsLogTag::DMS, "foldScreenController_ is null");
3179 return;
3180 }
3181 rsInterface_.SetScreenPowerStatus(foldScreenController_->GetCurrentScreenId(), status);
3182 };
3183 screenPowerTaskScheduler_->PostVoidSyncTask(rsSetScreenPowerStatusTask, "rsInterface_.SetScreenPowerStatus task");
3184 #endif
3185 }
3186
SetKeyguardDrawnDoneFlag(bool flag)3187 void ScreenSessionManager::SetKeyguardDrawnDoneFlag(bool flag)
3188 {
3189 keyguardDrawnDone_ = flag;
3190 }
3191
HandlerSensor(ScreenPowerStatus status,PowerStateChangeReason reason)3192 void ScreenSessionManager::HandlerSensor(ScreenPowerStatus status, PowerStateChangeReason reason)
3193 {
3194 if (!ScreenSceneConfig::IsSupportRotateWithSensor()) {
3195 TLOGW(WmsLogTag::DMS, "not supportRotateWithSensor.");
3196 return;
3197 }
3198 if (status == ScreenPowerStatus::POWER_STATUS_ON) {
3199 DmsXcollie dmsXcollie("DMS:SubscribeRotationSensor", XCOLLIE_TIMEOUT_10S);
3200 TLOGI(WmsLogTag::DMS, "subscribe rotation and posture sensor when phone turn on");
3201 ScreenSensorConnector::SubscribeRotationSensor();
3202 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
3203 if (g_foldScreenFlag && reason != PowerStateChangeReason::STATE_CHANGE_REASON_DISPLAY_SWITCH) {
3204 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
3205 SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
3206 SecondaryFoldSensorManager::GetInstance().PowerKeySetScreenActiveRect();
3207 } else {
3208 FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
3209 }
3210 } else {
3211 TLOGI(WmsLogTag::DMS, "not fold product, switch screen reason, failed register posture.");
3212 }
3213 #endif
3214 } else if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3215 status == ScreenPowerStatus::POWER_STATUS_DOZE || status == ScreenPowerStatus::POWER_STATUS_DOZE_SUSPEND) {
3216 UnregisterInHandlerSensorWithPowerOff(reason);
3217 } else {
3218 TLOGI(WmsLogTag::DMS, "SetScreenPower state not support");
3219 screenEventTracker_.RecordEvent("HandlerSensor start!");
3220 }
3221 }
3222
UnregisterInHandlerSensorWithPowerOff(PowerStateChangeReason reason)3223 void ScreenSessionManager::UnregisterInHandlerSensorWithPowerOff(PowerStateChangeReason reason)
3224 {
3225 TLOGI(WmsLogTag::DMS, "unsubscribe rotation and posture sensor when phone turn off");
3226 if (isMultiScreenCollaboration_) {
3227 TLOGI(WmsLogTag::DMS, "[UL_POWER]MultiScreenCollaboration, not unsubscribe rotation sensor");
3228 } else {
3229 DmsXcollie dmsXcollie("DMS:UnsubscribeRotationSensor", XCOLLIE_TIMEOUT_10S);
3230 ScreenSensorConnector::UnsubscribeRotationSensor();
3231 }
3232 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
3233 if (g_foldScreenFlag && reason != PowerStateChangeReason::STATE_CHANGE_REASON_DISPLAY_SWITCH &&
3234 !FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
3235 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
3236 SecondaryFoldSensorManager::GetInstance().UnRegisterPostureCallback();
3237 SecondaryFoldSensorManager::GetInstance().isPowerRectExe_ = false;
3238 } else {
3239 FoldScreenSensorManager::GetInstance().UnRegisterPostureCallback();
3240 }
3241 } else {
3242 TLOGI(WmsLogTag::DMS, "not fold product, switch screen reason, failed unregister posture.");
3243 }
3244 #endif
3245 }
3246
BootFinishedCallback(const char * key,const char * value,void * context)3247 void ScreenSessionManager::BootFinishedCallback(const char *key, const char *value, void *context)
3248 {
3249 if (strcmp(key, BOOTEVENT_BOOT_COMPLETED.c_str()) == 0 && strcmp(value, "true") == 0) {
3250 TLOGI(WmsLogTag::DMS, "boot animation finished");
3251 auto &that = *reinterpret_cast<ScreenSessionManager *>(context);
3252 that.SetRotateLockedFromSettingData();
3253 that.SetDpiFromSettingData();
3254 that.SetDisplayState(DisplayState::ON);
3255 that.RegisterSettingDpiObserver();
3256 if (that.foldScreenPowerInit_ != nullptr) {
3257 that.foldScreenPowerInit_();
3258 }
3259 that.RegisterSettingRotationObserver();
3260 that.RegisterSettingscreenSkipProtectedWindowObserver();
3261 if (that.defaultDpi) {
3262 auto ret = ScreenSettingHelper::SetSettingDefaultDpi(that.defaultDpi, SET_SETTING_DPI_KEY);
3263 if (!ret) {
3264 TLOGE(WmsLogTag::DMS, "set setting defaultDpi failed");
3265 } else {
3266 TLOGI(WmsLogTag::DMS, "set setting defaultDpi:%{public}d", that.defaultDpi);
3267 }
3268 }
3269 #ifdef FOLD_ABILITY_ENABLE
3270 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
3271 auto screenSession = that.GetDefaultScreenSession();
3272 if (screenSession == nullptr) {
3273 TLOGE(WmsLogTag::DMS, "screen session is null!");
3274 return;
3275 }
3276 ScreenId screenId = screenSession->GetScreenId();
3277 SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
3278 that.OnSuperFoldStatusChange(screenId, status);
3279 float sensorRotation = screenSession->GetSensorRotation();
3280 if (sensorRotation >= 0.0f) {
3281 that.OnSensorRotationChange(sensorRotation, screenId);
3282 }
3283 screenSession->PropertyChange(screenSession->GetScreenProperty(),
3284 ScreenPropertyChangeReason::SUPER_FOLD_STATUS_CHANGE);
3285 }
3286 #endif
3287 }
3288 }
3289
SetFoldScreenPowerInit(std::function<void ()> foldScreenPowerInit)3290 void ScreenSessionManager::SetFoldScreenPowerInit(std::function<void()> foldScreenPowerInit)
3291 {
3292 foldScreenPowerInit_ = foldScreenPowerInit;
3293 }
3294
SetRotateLockedFromSettingData()3295 void ScreenSessionManager::SetRotateLockedFromSettingData()
3296 {
3297 uint32_t autoRotateStatus = AUTO_ROTATE_OFF; // 0代表自动旋转关闭,1代表自动旋转打开
3298 bool islocked = true;
3299 // ret为true表示从数据库读到了值,并赋给了autoRotateStatus
3300 bool ret = ScreenSettingHelper::GetSettingValue(autoRotateStatus, SETTING_LOCKED_KEY);
3301 TLOGI(WmsLogTag::DMS, "get autoRotateStatus from settingdata: %{public}u", autoRotateStatus);
3302 if (autoRotateStatus) {
3303 islocked =false;
3304 }
3305 if (ret) {
3306 TLOGI(WmsLogTag::DMS, "get islocked success");
3307 SetScreenRotationLockedFromJs(islocked);
3308 }
3309 }
3310
RegisterSettingDpiObserver()3311 void ScreenSessionManager::RegisterSettingDpiObserver()
3312 {
3313 TLOGI(WmsLogTag::DMS, "Register Setting Dpi Observer");
3314 SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetDpiFromSettingData(); };
3315 ScreenSettingHelper::RegisterSettingDpiObserver(updateFunc);
3316 }
3317
SetDpiFromSettingData()3318 void ScreenSessionManager::SetDpiFromSettingData()
3319 {
3320 uint32_t settingDpi;
3321 bool ret = ScreenSettingHelper::GetSettingDpi(settingDpi);
3322 if (!ret) {
3323 TLOGW(WmsLogTag::DMS, "get setting dpi failed,use default dpi");
3324 settingDpi = defaultDpi;
3325 } else {
3326 TLOGI(WmsLogTag::DMS, "get setting dpi success,settingDpi: %{public}u", settingDpi);
3327 }
3328 if (settingDpi >= DOT_PER_INCH_MINIMUM_VALUE && settingDpi <= DOT_PER_INCH_MAXIMUM_VALUE
3329 && cachedSettingDpi_ != settingDpi) {
3330 cachedSettingDpi_ = settingDpi;
3331 float dpi = static_cast<float>(settingDpi) / BASELINE_DENSITY;
3332 ScreenId defaultScreenId = GetDefaultScreenId();
3333 SetVirtualPixelRatio(defaultScreenId, dpi);
3334 if (g_isPcDevice) {
3335 SetExtendPixelRatio(dpi * EXTEND_SCREEN_DPI_PARAMETER);
3336 }
3337 } else {
3338 TLOGE(WmsLogTag::DMS, "setting dpi error, settingDpi: %{public}d", settingDpi);
3339 }
3340 }
3341
SetExtendPixelRatio(const float & dpi)3342 void ScreenSessionManager::SetExtendPixelRatio(const float& dpi)
3343 {
3344 auto screenIds = GetAllScreenIds();
3345 if (screenIds.empty()) {
3346 TLOGE(WmsLogTag::DMS, "no screenId");
3347 return;
3348 }
3349 for (auto screenId : screenIds) {
3350 auto screenSession = GetScreenSession(screenId);
3351 if (screenSession == nullptr) {
3352 TLOGE(WmsLogTag::DMS, "screensession is nullptr, screenId: %{public}" PRIu64"", screenId);
3353 continue;
3354 }
3355 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && !screenSession->isInternal_) {
3356 SetVirtualPixelRatio(screenId, dpi);
3357 }
3358 }
3359 }
3360
GetAllScreenIds()3361 std::vector<ScreenId> ScreenSessionManager::GetAllScreenIds()
3362 {
3363 std::vector<ScreenId> res;
3364 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3365 for (const auto& iter : screenSessionMap_) {
3366 res.emplace_back(iter.first);
3367 }
3368 return res;
3369 }
3370
GetDisplayState(DisplayId displayId)3371 DisplayState ScreenSessionManager::GetDisplayState(DisplayId displayId)
3372 {
3373 return sessionDisplayPowerController_->GetDisplayState(displayId);
3374 }
3375
NotifyDisplayEvent(DisplayEvent event)3376 void ScreenSessionManager::NotifyDisplayEvent(DisplayEvent event)
3377 {
3378 TLOGI(WmsLogTag::DMS, "[UL_POWER] receive keyguardDrawnDone");
3379 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3380 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3381 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3382 return;
3383 }
3384 sessionDisplayPowerController_->NotifyDisplayEvent(event);
3385 if (event == DisplayEvent::KEYGUARD_DRAWN) {
3386 keyguardDrawnDone_ = true;
3387 TLOGI(WmsLogTag::DMS, "[UL_POWER]keyguardDrawnDone_ is true");
3388 if (needScreenOnWhenKeyguardNotify_) {
3389 std::unique_lock <std::mutex> lock(screenOnMutex_);
3390 screenOnCV_.notify_all();
3391 TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOnCV_ notify one");
3392 needScreenOnWhenKeyguardNotify_ = false;
3393 }
3394 }
3395 if (event == DisplayEvent::SCREEN_LOCK_SUSPEND) {
3396 TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock suspend");
3397 if (isPhyScreenConnected_) {
3398 isScreenLockSuspend_ = false;
3399 TLOGI(WmsLogTag::DMS, "[UL_POWER]isScreenLockSuspend__ is false");
3400 } else {
3401 isScreenLockSuspend_ = true;
3402 }
3403 SetGotScreenOffAndWakeUpBlock();
3404 }
3405 if (event == DisplayEvent::SCREEN_LOCK_OFF) {
3406 TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock off");
3407 isScreenLockSuspend_ = false;
3408 TLOGI(WmsLogTag::DMS, "[UL_POWER]isScreenLockSuspend__ is false");
3409 SetGotScreenOffAndWakeUpBlock();
3410 }
3411 if (event == DisplayEvent::SCREEN_LOCK_FINGERPRINT) {
3412 TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock fingerprint");
3413 gotScreenlockFingerprint_ = true;
3414 SetGotScreenOffAndWakeUpBlock();
3415 }
3416 if (event == DisplayEvent::SCREEN_LOCK_DOZE_FINISH) {
3417 TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock doze finish");
3418 SetGotScreenOffAndWakeUpBlock();
3419 }
3420 WakeUpPictureFrameBlock(event);
3421 }
3422
SetGotScreenOffAndWakeUpBlock()3423 void ScreenSessionManager::SetGotScreenOffAndWakeUpBlock()
3424 {
3425 gotScreenOffNotify_ = true;
3426 if (needScreenOffNotify_) {
3427 ScreenOffCVNotify();
3428 }
3429 }
3430
ScreenOffCVNotify(void)3431 void ScreenSessionManager::ScreenOffCVNotify(void)
3432 {
3433 std::unique_lock <std::mutex> lock(screenOffMutex_);
3434 screenOffCV_.notify_all();
3435 needScreenOffNotify_ = false;
3436 TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOffCV_ notify one");
3437 }
3438
GetScreenPower(ScreenId screenId)3439 ScreenPowerState ScreenSessionManager::GetScreenPower(ScreenId screenId)
3440 {
3441 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3442 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3443 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3444 return ScreenPowerState::INVALID_STATE;
3445 }
3446 auto state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance().GetScreenPowerStatus(screenId));
3447 std::ostringstream oss;
3448 oss << "GetScreenPower state:" << static_cast<uint32_t>(state) << " screenId:" << static_cast<uint64_t>(screenId);
3449 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
3450 screenEventTracker_.RecordEvent(oss.str());
3451 return state;
3452 }
3453
GetScreenPower()3454 ScreenPowerState ScreenSessionManager::GetScreenPower()
3455 {
3456 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3457 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3458 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3459 return ScreenPowerState::INVALID_STATE;
3460 }
3461 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetScreenPower");
3462 ScreenPowerState state = ScreenPowerState::INVALID_STATE;
3463 #ifdef FOLD_ABILITY_ENABLE
3464 if (!g_foldScreenFlag || FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
3465 state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance()
3466 .GetScreenPowerStatus(GetDefaultScreenId()));
3467 } else {
3468 state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance()
3469 .GetScreenPowerStatus(foldScreenController_->GetCurrentScreenId()));
3470 }
3471 #else
3472 state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance()
3473 .GetScreenPowerStatus(foldScreenController_->GetCurrentScreenId()));
3474 #endif
3475 std::ostringstream oss;
3476 oss << "GetScreenPower state:" << static_cast<uint32_t>(state);
3477 TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
3478 screenEventTracker_.RecordEvent(oss.str());
3479 return state;
3480 }
3481
IsScreenRotationLocked(bool & isLocked)3482 DMError ScreenSessionManager::IsScreenRotationLocked(bool& isLocked)
3483 {
3484 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3485 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3486 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3487 return DMError::DM_ERROR_NOT_SYSTEM_APP;
3488 }
3489 sptr<ScreenSession> screenSession = GetDefaultScreenSession();
3490 if (screenSession == nullptr) {
3491 TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
3492 return DMError::DM_ERROR_INVALID_PARAM;
3493 }
3494 isLocked = screenSession->IsScreenRotationLocked();
3495 TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
3496 return DMError::DM_OK;
3497 }
3498
SetScreenRotationLocked(bool isLocked)3499 DMError ScreenSessionManager::SetScreenRotationLocked(bool isLocked)
3500 {
3501 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3502 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3503 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3504 return DMError::DM_ERROR_NOT_SYSTEM_APP;
3505 }
3506 sptr<ScreenSession> screenSession = GetDefaultScreenSession();
3507 if (screenSession == nullptr) {
3508 TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
3509 return DMError::DM_ERROR_INVALID_PARAM;
3510 }
3511 screenSession->SetScreenRotationLocked(isLocked);
3512 TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
3513 return DMError::DM_OK;
3514 }
3515
SetScreenRotationLockedFromJs(bool isLocked)3516 DMError ScreenSessionManager::SetScreenRotationLockedFromJs(bool isLocked)
3517 {
3518 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3519 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3520 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3521 return DMError::DM_ERROR_NOT_SYSTEM_APP;
3522 }
3523 sptr<ScreenSession> screenSession = GetDefaultScreenSession();
3524 if (screenSession == nullptr) {
3525 TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
3526 return DMError::DM_ERROR_INVALID_PARAM;
3527 }
3528 screenSession->SetScreenRotationLockedFromJs(isLocked);
3529 TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
3530 return DMError::DM_OK;
3531 }
3532
NotifyAndPublishEvent(sptr<DisplayInfo> displayInfo,ScreenId screenId,sptr<ScreenSession> screenSession)3533 void ScreenSessionManager::NotifyAndPublishEvent(sptr<DisplayInfo> displayInfo, ScreenId screenId,
3534 sptr<ScreenSession> screenSession)
3535 {
3536 if (displayInfo == nullptr || screenSession == nullptr) {
3537 TLOGE(WmsLogTag::DMS, "error, displayInfo or screenSession is nullptr");
3538 return;
3539 }
3540 NotifyDisplayChanged(displayInfo, DisplayChangeEvent::UPDATE_ROTATION);
3541 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
3542 UpdateDisplayScaleState(screenId);
3543 std::map<DisplayId, sptr<DisplayInfo>> emptyMap;
3544 NotifyDisplayStateChange(GetDefaultScreenId(), screenSession->ConvertToDisplayInfo(),
3545 emptyMap, DisplayStateChangeType::UPDATE_ROTATION);
3546 std::string identity = IPCSkeleton::ResetCallingIdentity();
3547 ScreenSessionPublish::GetInstance().PublishDisplayRotationEvent(
3548 displayInfo->GetScreenId(), displayInfo->GetRotation());
3549 IPCSkeleton::SetCallingIdentity(identity);
3550 }
3551
UpdateScreenDirectionInfo(ScreenId screenId,float screenComponentRotation,float rotation,float phyRotation,ScreenPropertyChangeType screenPropertyChangeType)3552 void ScreenSessionManager::UpdateScreenDirectionInfo(ScreenId screenId, float screenComponentRotation, float rotation,
3553 float phyRotation, ScreenPropertyChangeType screenPropertyChangeType)
3554 {
3555 if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_END) {
3556 TLOGI(WmsLogTag::DMS, "ROTATION_END");
3557 return;
3558 }
3559 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3560 if (screenSession == nullptr) {
3561 TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"",
3562 screenId);
3563 return;
3564 }
3565 screenSession->SetPhysicalRotation(phyRotation);
3566 screenSession->SetScreenComponentRotation(screenComponentRotation);
3567 screenSession->UpdateRotationOrientation(rotation, GetFoldDisplayMode(), IsOrientationNeedChanged());
3568 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", rotation: %{public}f, screenComponentRotation: %{public}f",
3569 screenId, rotation, screenComponentRotation);
3570 }
3571
UpdateScreenRotationProperty(ScreenId screenId,const RRect & bounds,float rotation,ScreenPropertyChangeType screenPropertyChangeType)3572 void ScreenSessionManager::UpdateScreenRotationProperty(ScreenId screenId, const RRect& bounds, float rotation,
3573 ScreenPropertyChangeType screenPropertyChangeType)
3574 {
3575 std::ostringstream oss;
3576 std::string changeType = TransferPropertyChangeTypeToString(screenPropertyChangeType);
3577 oss << "screenId: " << screenId << " rotation: " << rotation << " width: " << bounds.rect_.width_ \
3578 << " height: " << bounds.rect_.height_ << " type: " << changeType;
3579 screenEventTracker_.RecordBoundsEvent(oss.str());
3580 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3581 TLOGE(WmsLogTag::DMS, "permission denied!");
3582 return;
3583 }
3584 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3585 if (screenSession == nullptr) {
3586 TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"", screenId);
3587 return;
3588 }
3589 {
3590 DmsXcollie dmsXcollie("DMS:UpdateScreenRotationProperty:CacheForRotation", XCOLLIE_TIMEOUT_10S);
3591 if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_BEGIN) {
3592 // Rs is used to mark the start of the rotation animation
3593 TLOGI(WmsLogTag::DMS, "EnableCacheForRotation");
3594 RSInterfaces::GetInstance().EnableCacheForRotation();
3595 } else if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_END) {
3596 // Rs is used to mark the end of the rotation animation
3597 TLOGI(WmsLogTag::DMS, "DisableCacheForRotation");
3598 RSInterfaces::GetInstance().DisableCacheForRotation();
3599 return;
3600 } else if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY ||
3601 screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY) {
3602 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
3603 TLOGI(WmsLogTag::DMS, "Update Screen Rotation Property Only");
3604 {
3605 std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
3606 screenSession->UpdatePropertyOnly(bounds, rotation, GetFoldDisplayMode(), IsOrientationNeedChanged());
3607 }
3608 if (screenPropertyChangeType != ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY) {
3609 NotifyDisplayChanged(displayInfo, DisplayChangeEvent::UPDATE_ROTATION);
3610 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
3611 }
3612 return;
3613 }
3614 }
3615 {
3616 std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
3617 screenSession->UpdatePropertyAfterRotation(bounds, rotation, GetFoldDisplayMode(), IsOrientationNeedChanged());
3618 }
3619 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
3620 NotifyAndPublishEvent(displayInfo, screenId, screenSession);
3621 }
3622
NotifyDisplayChanged(sptr<DisplayInfo> displayInfo,DisplayChangeEvent event)3623 void ScreenSessionManager::NotifyDisplayChanged(sptr<DisplayInfo> displayInfo, DisplayChangeEvent event)
3624 {
3625 if (displayInfo == nullptr) {
3626 TLOGE(WmsLogTag::DMS, "error, displayInfo is nullptr.");
3627 return;
3628 }
3629 auto task = [=] {
3630 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
3631 if (event == DisplayChangeEvent::UPDATE_REFRESHRATE) {
3632 TLOGND(WmsLogTag::DMS, "evevt:%{public}d, displayId:%{public}" PRIu64", agent size: %{public}u",
3633 event, displayInfo->GetDisplayId(), static_cast<uint32_t>(agents.size()));
3634 } else {
3635 TLOGNI(WmsLogTag::DMS, "evevt:%{public}d, displayId:%{public}" PRIu64", agent size: %{public}u",
3636 event, displayInfo->GetDisplayId(), static_cast<uint32_t>(agents.size()));
3637 }
3638 if (agents.empty()) {
3639 return;
3640 }
3641 for (auto& agent : agents) {
3642 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
3643 if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
3644 agent->OnDisplayChange(displayInfo, event);
3645 }
3646 }
3647 };
3648 taskScheduler_->PostAsyncTask(task, "NotifyDisplayChanged");
3649 }
3650
SetOrientation(ScreenId screenId,Orientation orientation)3651 DMError ScreenSessionManager::SetOrientation(ScreenId screenId, Orientation orientation)
3652 {
3653 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3654 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3655 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3656 return DMError::DM_ERROR_NOT_SYSTEM_APP;
3657 }
3658 if (orientation < Orientation::UNSPECIFIED || orientation > Orientation::REVERSE_HORIZONTAL) {
3659 TLOGE(WmsLogTag::DMS, "set: %{public}u", static_cast<uint32_t>(orientation));
3660 return DMError::DM_ERROR_INVALID_PARAM;
3661 }
3662 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetOrientation");
3663 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3664 if (screenSession == nullptr) {
3665 TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"", screenId);
3666 return DMError::DM_ERROR_NULLPTR;
3667 }
3668 // just for get orientation test
3669 screenSession->SetOrientation(orientation);
3670 screenSession->ScreenOrientationChange(orientation, GetFoldDisplayMode());
3671 return DMError::DM_OK;
3672 }
3673
SetRotation(ScreenId screenId,Rotation rotationAfter,bool isFromWindow)3674 bool ScreenSessionManager::SetRotation(ScreenId screenId, Rotation rotationAfter, bool isFromWindow)
3675 {
3676 TLOGI(WmsLogTag::DMS,
3677 "Enter, screenId: %{public}" PRIu64 ", rotation: %{public}u, isFromWindow: %{public}u,",
3678 screenId, rotationAfter, isFromWindow);
3679 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3680 if (screenSession == nullptr) {
3681 TLOGE(WmsLogTag::DMS, "error, cannot get screen with screenId: %{public}" PRIu64, screenId);
3682 return false;
3683 }
3684 if (rotationAfter == screenSession->GetRotation()) {
3685 TLOGE(WmsLogTag::DMS, "rotation not changed. screen %{public}" PRIu64" rotation %{public}u",
3686 screenId, rotationAfter);
3687 return false;
3688 }
3689 TLOGI(WmsLogTag::DMS, "set orientation. rotation %{public}u", rotationAfter);
3690 SetDisplayBoundary(screenSession);
3691 screenSession->SetRotation(rotationAfter);
3692 screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::ROTATION);
3693 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
3694 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::UPDATE_ROTATION);
3695 return true;
3696 }
3697
SetSensorSubscriptionEnabled()3698 void ScreenSessionManager::SetSensorSubscriptionEnabled()
3699 {
3700 isAutoRotationOpen_ = system::GetParameter("persist.display.ar.enabled", "1") == "1";
3701 if (!isAutoRotationOpen_) {
3702 TLOGE(WmsLogTag::DMS, "autoRotation is not open");
3703 return;
3704 }
3705 ScreenSensorConnector::SubscribeRotationSensor();
3706 TLOGI(WmsLogTag::DMS, "subscribe rotation sensor successful");
3707 }
3708
SetPostureAndHallSensorEnabled()3709 void ScreenSessionManager::SetPostureAndHallSensorEnabled()
3710 {
3711 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
3712 if (!g_foldScreenFlag) {
3713 TLOGI(WmsLogTag::DMS, "current device is not fold phone.");
3714 return;
3715 }
3716 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
3717 SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
3718 SecondaryFoldSensorManager::GetInstance().RegisterHallCallback();
3719 } else {
3720 FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
3721 FoldScreenSensorManager::GetInstance().RegisterHallCallback();
3722 }
3723 TLOGI(WmsLogTag::DMS, "successful");
3724 screenEventTracker_.RecordEvent("Dms subscribe Posture and Hall sensor finished.");
3725 #endif
3726 }
3727
SetRotationFromWindow(Rotation targetRotation)3728 bool ScreenSessionManager::SetRotationFromWindow(Rotation targetRotation)
3729 {
3730 sptr<DisplayInfo> displayInfo = GetDefaultDisplayInfo();
3731 if (displayInfo == nullptr) {
3732 return false;
3733 }
3734 return SetRotation(displayInfo->GetScreenId(), targetRotation, true);
3735 }
3736
GetScreenModesByDisplayId(DisplayId displayId)3737 sptr<SupportedScreenModes> ScreenSessionManager::GetScreenModesByDisplayId(DisplayId displayId)
3738 {
3739 auto displayInfo = GetDisplayInfoById(displayId);
3740 if (displayInfo == nullptr) {
3741 TLOGE(WmsLogTag::DMS, "can not get display.");
3742 return nullptr;
3743 }
3744 auto screenInfo = GetScreenInfoById(displayInfo->GetScreenId());
3745 if (screenInfo == nullptr) {
3746 TLOGE(WmsLogTag::DMS, "can not get screen.");
3747 return nullptr;
3748 }
3749 auto modes = screenInfo->GetModes();
3750 auto id = screenInfo->GetModeId();
3751 if (id >= modes.size()) {
3752 TLOGE(WmsLogTag::DMS, "can not get screenMode.");
3753 return nullptr;
3754 }
3755 return modes[id];
3756 }
3757
GetScreenInfoByDisplayId(DisplayId displayId)3758 sptr<ScreenInfo> ScreenSessionManager::GetScreenInfoByDisplayId(DisplayId displayId)
3759 {
3760 auto displayInfo = GetDisplayInfoById(displayId);
3761 if (displayInfo == nullptr) {
3762 TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
3763 return nullptr;
3764 }
3765 return GetScreenInfoById(displayInfo->GetScreenId());
3766 }
3767
NotifyPowerEventForDualDisplay(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)3768 int ScreenSessionManager::NotifyPowerEventForDualDisplay(DisplayPowerEvent event, EventStatus status,
3769 PowerStateChangeReason reason)
3770 {
3771 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3772 if (screenSessionMap_.empty()) {
3773 TLOGE(WmsLogTag::DMS, "[UL_POWER]screenSessionMap is empty");
3774 return NOTIFY_EVENT_FOR_DUAL_FAILED;
3775 }
3776 #ifdef FOLD_ABILITY_ENABLE
3777 // The on/off screen will send a notification based on the number of screens.
3778 // The dual display device just notify the current screen usage
3779 if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
3780 ScreenId currentScreenId = foldScreenController_->GetCurrentScreenId();
3781 auto iter = screenSessionMap_.find(currentScreenId);
3782 if (iter != screenSessionMap_.end() && iter->second != nullptr) {
3783 iter->second->PowerStatusChange(event, status, reason);
3784 }
3785 return NOTIFY_EVENT_FOR_DUAL_SUCESS;
3786 }
3787 #endif
3788 return NO_NEED_NOTIFY_EVENT_FOR_DUAL;
3789 }
3790
NotifyDisplayPowerEvent(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)3791 bool ScreenSessionManager::NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status,
3792 PowerStateChangeReason reason)
3793 {
3794 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER);
3795 if (agents.empty()) {
3796 TLOGI(WmsLogTag::DMS, "[UL_POWER] agents is empty");
3797 return false;
3798 }
3799 TLOGD(WmsLogTag::DMS, "[UL_POWER] start");
3800 for (auto& agent : agents) {
3801 agent->NotifyDisplayPowerEvent(event, status);
3802 }
3803 auto ret = NotifyPowerEventForDualDisplay(event, status, reason);
3804 if (ret == NOTIFY_EVENT_FOR_DUAL_FAILED) {
3805 TLOGE(WmsLogTag::DMS, "[UL_POWER]NotifyPowerEventForDualDisplay ret false");
3806 return false;
3807 } else if (ret == NOTIFY_EVENT_FOR_DUAL_SUCESS) {
3808 TLOGD(WmsLogTag::DMS, "[UL_POWER]NotifyPowerEventForDualDisplay ret sucess");
3809 return true;
3810 }
3811 auto screenIds = GetAllScreenIds();
3812 if (screenIds.empty()) {
3813 TLOGI(WmsLogTag::DMS, "[UL_POWER]no screenID");
3814 return false;
3815 }
3816 auto screenId = screenIds[0];
3817 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3818 if (screenSession == nullptr) {
3819 TLOGE(WmsLogTag::DMS, "[UL_POWER]Cannot get ScreenSession, screenId: %{public}" PRIu64"", screenId);
3820 return false;
3821 }
3822 screenSession->PowerStatusChange(event, status, reason);
3823 return true;
3824 }
3825
NotifyDisplayStateChanged(DisplayId id,DisplayState state)3826 bool ScreenSessionManager::NotifyDisplayStateChanged(DisplayId id, DisplayState state)
3827 {
3828 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_STATE_LISTENER);
3829 if (agents.empty()) {
3830 TLOGI(WmsLogTag::DMS, "agents is empty");
3831 return false;
3832 }
3833 TLOGI(WmsLogTag::DMS, "notify enter!");
3834 for (auto& agent : agents) {
3835 agent->NotifyDisplayStateChanged(id, state);
3836 }
3837 return true;
3838 }
GetAllScreenInfos(std::vector<sptr<ScreenInfo>> & screenInfos)3839 DMError ScreenSessionManager::GetAllScreenInfos(std::vector<sptr<ScreenInfo>>& screenInfos)
3840 {
3841 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3842 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3843 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3844 return DMError::DM_ERROR_NOT_SYSTEM_APP;
3845 }
3846 std::vector<ScreenId> screenIds = GetAllScreenIds();
3847 if (screenIds.empty()) {
3848 TLOGI(WmsLogTag::DMS, "[UL_POWER]no screen info");
3849 return DMError::DM_OK;
3850 }
3851 for (auto screenId : screenIds) {
3852 auto screenInfo = GetScreenInfoById(screenId);
3853 if (screenInfo == nullptr) {
3854 TLOGE(WmsLogTag::DMS, "cannot find screenInfo: %{public}" PRIu64"", screenId);
3855 continue;
3856 }
3857 screenInfos.emplace_back(screenInfo);
3858 }
3859 return DMError::DM_OK;
3860 }
3861
GetAllScreenIds() const3862 std::vector<ScreenId> ScreenSessionManager::GetAllScreenIds() const
3863 {
3864 std::vector<ScreenId> res;
3865 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3866 for (const auto& iter : screenSessionMap_) {
3867 res.emplace_back(iter.first);
3868 }
3869 return res;
3870 }
3871
GetScreenSupportedColorGamuts(ScreenId screenId,std::vector<ScreenColorGamut> & colorGamuts)3872 DMError ScreenSessionManager::GetScreenSupportedColorGamuts(ScreenId screenId,
3873 std::vector<ScreenColorGamut>& colorGamuts)
3874 {
3875 TLOGI(WmsLogTag::DMS, "ENTER");
3876 if (!SessionPermission::IsSystemCalling()) {
3877 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3878 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3879 return DMError::DM_ERROR_NOT_SYSTEM_APP;
3880 }
3881 sptr<ScreenSession> screen = GetScreenSession(screenId);
3882 if (screen == nullptr) {
3883 TLOGE(WmsLogTag::DMS, "nullptr");
3884 return DMError::DM_ERROR_INVALID_PARAM;
3885 }
3886 return screen->GetScreenSupportedColorGamuts(colorGamuts);
3887 }
3888
GetPixelFormat(ScreenId screenId,GraphicPixelFormat & pixelFormat)3889 DMError ScreenSessionManager::GetPixelFormat(ScreenId screenId, GraphicPixelFormat& pixelFormat)
3890 {
3891 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64, screenId);
3892 if (screenId == SCREEN_ID_INVALID) {
3893 TLOGE(WmsLogTag::DMS, "screenId invalid");
3894 return DMError::DM_ERROR_INVALID_PARAM;
3895 }
3896 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3897 if (screenSession == nullptr) {
3898 return DMError::DM_ERROR_INVALID_PARAM;
3899 }
3900 return screenSession->GetPixelFormat(pixelFormat);
3901 }
3902
SetPixelFormat(ScreenId screenId,GraphicPixelFormat pixelFormat)3903 DMError ScreenSessionManager::SetPixelFormat(ScreenId screenId, GraphicPixelFormat pixelFormat)
3904 {
3905 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3906 TLOGE(WmsLogTag::DMS, "permission denied!");
3907 return DMError::DM_ERROR_NOT_SYSTEM_APP;
3908 }
3909
3910 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", pixelFormat %{public}d",
3911 screenId, pixelFormat);
3912 if (screenId == SCREEN_ID_INVALID) {
3913 TLOGE(WmsLogTag::DMS, "screenId invalid");
3914 return DMError::DM_ERROR_INVALID_PARAM;
3915 }
3916 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3917 if (screenSession == nullptr) {
3918 return DMError::DM_ERROR_INVALID_PARAM;
3919 }
3920 return screenSession->SetPixelFormat(pixelFormat);
3921 }
3922
GetSupportedHDRFormats(ScreenId screenId,std::vector<ScreenHDRFormat> & hdrFormats)3923 DMError ScreenSessionManager::GetSupportedHDRFormats(ScreenId screenId,
3924 std::vector<ScreenHDRFormat>& hdrFormats)
3925 {
3926 #ifdef WM_SCREEN_HDR_FORMAT_ENABLE
3927 TLOGI(WmsLogTag::DMS, "start %{public}" PRIu64, screenId);
3928 if (screenId == SCREEN_ID_INVALID) {
3929 TLOGE(WmsLogTag::DMS, "screenId invalid");
3930 return DMError::DM_ERROR_INVALID_PARAM;
3931 }
3932 sptr<ScreenSession> screen = GetScreenSession(screenId);
3933 if (screen == nullptr) {
3934 TLOGE(WmsLogTag::DMS, "nullptr");
3935 return DMError::DM_ERROR_INVALID_PARAM;
3936 }
3937 return screen->GetSupportedHDRFormats(hdrFormats);
3938 #else
3939 return DMError::DM_OK;
3940 #endif
3941 }
3942
GetScreenHDRFormat(ScreenId screenId,ScreenHDRFormat & hdrFormat)3943 DMError ScreenSessionManager::GetScreenHDRFormat(ScreenId screenId, ScreenHDRFormat& hdrFormat)
3944 {
3945 #ifdef WM_SCREEN_HDR_FORMAT_ENABLE
3946 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64, screenId);
3947 if (screenId == SCREEN_ID_INVALID) {
3948 TLOGE(WmsLogTag::DMS, "screenId invalid");
3949 return DMError::DM_ERROR_INVALID_PARAM;
3950 }
3951 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3952 if (screenSession == nullptr) {
3953 return DMError::DM_ERROR_INVALID_PARAM;
3954 }
3955 return screenSession->GetScreenHDRFormat(hdrFormat);
3956 #else
3957 return DMError::DM_OK;
3958 #endif
3959 }
3960
SetScreenHDRFormat(ScreenId screenId,int32_t modeIdx)3961 DMError ScreenSessionManager::SetScreenHDRFormat(ScreenId screenId, int32_t modeIdx)
3962 {
3963 #ifdef WM_SCREEN_HDR_FORMAT_ENABLE
3964 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3965 TLOGE(WmsLogTag::DMS, "permission denied!");
3966 return DMError::DM_ERROR_NOT_SYSTEM_APP;
3967 }
3968
3969 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", modeIdx %{public}d", screenId, modeIdx);
3970 if (screenId == SCREEN_ID_INVALID) {
3971 TLOGE(WmsLogTag::DMS, "screenId invalid");
3972 return DMError::DM_ERROR_INVALID_PARAM;
3973 }
3974 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3975 if (screenSession == nullptr) {
3976 return DMError::DM_ERROR_INVALID_PARAM;
3977 }
3978 return screenSession->SetScreenHDRFormat(modeIdx);
3979 #else
3980 return DMError::DM_OK;
3981 #endif
3982 }
3983
GetSupportedColorSpaces(ScreenId screenId,std::vector<GraphicCM_ColorSpaceType> & colorSpaces)3984 DMError ScreenSessionManager::GetSupportedColorSpaces(ScreenId screenId,
3985 std::vector<GraphicCM_ColorSpaceType>& colorSpaces)
3986 {
3987 #ifdef WM_SCREEN_COLOR_SPACE_ENABLE
3988 TLOGI(WmsLogTag::DMS, "start %{public}" PRIu64, screenId);
3989 if (screenId == SCREEN_ID_INVALID) {
3990 TLOGE(WmsLogTag::DMS, "screenId invalid");
3991 return DMError::DM_ERROR_INVALID_PARAM;
3992 }
3993 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3994 if (screenSession == nullptr) {
3995 TLOGE(WmsLogTag::DMS, "nullptr");
3996 return DMError::DM_ERROR_INVALID_PARAM;
3997 }
3998 return screenSession->GetSupportedColorSpaces(colorSpaces);
3999 #else
4000 return DMError::DM_OK;
4001 #endif
4002 }
4003
GetScreenColorSpace(ScreenId screenId,GraphicCM_ColorSpaceType & colorSpace)4004 DMError ScreenSessionManager::GetScreenColorSpace(ScreenId screenId, GraphicCM_ColorSpaceType& colorSpace)
4005 {
4006 #ifdef WM_SCREEN_COLOR_SPACE_ENABLE
4007 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64, screenId);
4008 if (screenId == SCREEN_ID_INVALID) {
4009 TLOGE(WmsLogTag::DMS, "screenId invalid");
4010 return DMError::DM_ERROR_INVALID_PARAM;
4011 }
4012 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4013 if (screenSession == nullptr) {
4014 return DMError::DM_ERROR_INVALID_PARAM;
4015 }
4016 return screenSession->GetScreenColorSpace(colorSpace);
4017 #else
4018 return DMError::DM_OK;
4019 #endif
4020 }
4021
SetScreenColorSpace(ScreenId screenId,GraphicCM_ColorSpaceType colorSpace)4022 DMError ScreenSessionManager::SetScreenColorSpace(ScreenId screenId, GraphicCM_ColorSpaceType colorSpace)
4023 {
4024 #ifdef WM_SCREEN_COLOR_SPACE_ENABLE
4025 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4026 TLOGE(WmsLogTag::DMS, "permission denied!");
4027 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4028 }
4029
4030 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", colorSpace %{public}d",
4031 screenId, colorSpace);
4032 if (screenId == SCREEN_ID_INVALID) {
4033 TLOGE(WmsLogTag::DMS, "screenId invalid");
4034 return DMError::DM_ERROR_INVALID_PARAM;
4035 }
4036 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4037 if (screenSession == nullptr) {
4038 return DMError::DM_ERROR_INVALID_PARAM;
4039 }
4040 return screenSession->SetScreenColorSpace(colorSpace);
4041 #else
4042 return DMError::DM_OK;
4043 #endif
4044 }
4045
AddVirtualScreenDeathRecipient(const sptr<IRemoteObject> & displayManagerAgent,ScreenId smsScreenId)4046 void ScreenSessionManager::AddVirtualScreenDeathRecipient(const sptr<IRemoteObject>& displayManagerAgent,
4047 ScreenId smsScreenId)
4048 {
4049 if (deathRecipient_ == nullptr) {
4050 TLOGW(WmsLogTag::DMS, "Create deathRecipient");
4051 deathRecipient_ =
4052 new(std::nothrow) AgentDeathRecipient([this](const sptr<IRemoteObject>& agent) { OnRemoteDied(agent); });
4053 }
4054 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4055 if (deathRecipient_ != nullptr) {
4056 auto agIter = screenAgentMap_.find(displayManagerAgent);
4057 if (agIter == screenAgentMap_.end()) {
4058 displayManagerAgent->AddDeathRecipient(deathRecipient_);
4059 }
4060 }
4061 screenAgentMap_[displayManagerAgent].emplace_back(smsScreenId);
4062 }
4063
CreateVirtualScreen(VirtualScreenOption option,const sptr<IRemoteObject> & displayManagerAgent)4064 ScreenId ScreenSessionManager::CreateVirtualScreen(VirtualScreenOption option,
4065 const sptr<IRemoteObject>& displayManagerAgent)
4066 {
4067 if (!Permission::IsSystemCalling() && !SessionPermission::IsShellCall() &&
4068 !Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION)) {
4069 return ERROR_ID_NOT_SYSTEM_APP;
4070 }
4071 if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
4072 !SessionPermission::IsShellCall() && !Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION)) {
4073 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4074 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4075 return SCREEN_ID_INVALID;
4076 }
4077 if (option.virtualScreenType_ != VirtualScreenType::SCREEN_RECORDING) {
4078 ExitCoordination("CreateVirtualScreen(cast)");
4079 }
4080 TLOGI(WmsLogTag::DMS, "ENTER, virtualScreenType: %{public}u", static_cast<uint32_t>(option.virtualScreenType_));
4081 if (SessionPermission::IsBetaVersion()) {
4082 CheckAndSendHiSysEvent("CREATE_VIRTUAL_SCREEN", "hmos.screenrecorder");
4083 }
4084 if (clientProxy_ && option.missionIds_.size() > 0) {
4085 std::vector<uint64_t> surfaceNodeIds;
4086 clientProxy_->OnGetSurfaceNodeIdsFromMissionIdsChanged(option.missionIds_, surfaceNodeIds, true);
4087 option.missionIds_ = surfaceNodeIds;
4088 }
4089 ScreenId rsId = rsInterface_.CreateVirtualScreen(option.name_, option.width_,
4090 option.height_, option.surface_, SCREEN_ID_INVALID, option.flags_);
4091 if (rsId == SCREEN_ID_INVALID) {
4092 TLOGI(WmsLogTag::DMS, "rsId is invalid");
4093 return SCREEN_ID_INVALID;
4094 }
4095 TLOGW(WmsLogTag::DMS, "rsId: %{public}" PRIu64"", rsId);
4096 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CreateVirtualScreen(%s)", option.name_.c_str());
4097 ScreenId smsScreenId = SCREEN_ID_INVALID;
4098 if (!screenIdManager_.ConvertToSmsScreenId(rsId, smsScreenId)) {
4099 TLOGW(WmsLogTag::DMS, "!ConvertToSmsScreenId(rsId, smsScreenId)");
4100 smsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsId);
4101 auto screenSession = InitVirtualScreen(smsScreenId, rsId, option);
4102 if (screenSession == nullptr) {
4103 TLOGW(WmsLogTag::DMS, "screenSession is nullptr");
4104 screenIdManager_.DeleteScreenId(smsScreenId);
4105 return SCREEN_ID_INVALID;
4106 }
4107 screenSession->SetName(option.name_);
4108 screenSession->SetMirrorScreenType(MirrorScreenType::VIRTUAL_MIRROR);
4109 {
4110 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4111 screenSessionMap_.insert(std::make_pair(smsScreenId, screenSession));
4112 }
4113 if (option.name_ == "CastEngine") {
4114 screenSession->SetVirtualScreenFlag(VirtualScreenFlag::CAST);
4115 }
4116 NotifyScreenConnected(screenSession->ConvertToScreenInfo());
4117 TLOGW(WmsLogTag::DMS, "create success. ScreenId: %{public}" PRIu64", rsId: %{public}" PRIu64"",
4118 smsScreenId, rsId);
4119 if (displayManagerAgent == nullptr) {
4120 virtualScreenCount_ = virtualScreenCount_ + 1;
4121 NotifyCaptureStatusChanged();
4122 return smsScreenId;
4123 }
4124 AddVirtualScreenDeathRecipient(displayManagerAgent, smsScreenId);
4125 }
4126 virtualScreenCount_ = virtualScreenCount_ + 1;
4127 NotifyCaptureStatusChanged();
4128 return smsScreenId;
4129 }
4130
SetVirtualScreenSurface(ScreenId screenId,sptr<IBufferProducer> surface)4131 DMError ScreenSessionManager::SetVirtualScreenSurface(ScreenId screenId, sptr<IBufferProducer> surface)
4132 {
4133 bool isCallingByThirdParty = Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION);
4134 if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
4135 !SessionPermission::IsShellCall() && !isCallingByThirdParty) {
4136 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4137 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4138 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4139 }
4140 if (surface == nullptr) {
4141 TLOGE(WmsLogTag::DMS, "surface is null");
4142 return DMError::DM_ERROR_INVALID_PARAM;
4143 }
4144 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4145 if (screenSession == nullptr) {
4146 TLOGE(WmsLogTag::DMS, "No such screen.");
4147 return isCallingByThirdParty ? DMError::DM_ERROR_NULLPTR : DMError::DM_ERROR_INVALID_PARAM;
4148 }
4149 TLOGW(WmsLogTag::DMS, "enter set virtual screen surface");
4150 ScreenId rsScreenId;
4151 int32_t res = -1;
4152 if (screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4153 sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(surface);
4154 if (pSurface != nullptr) {
4155 res = rsInterface_.SetVirtualScreenSurface(rsScreenId, pSurface);
4156 }
4157 }
4158 if (res != 0) {
4159 TLOGE(WmsLogTag::DMS, "fail to set virtual screen surface in RenderService");
4160 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
4161 }
4162 return DMError::DM_OK;
4163 }
4164
AddVirtualScreenBlockList(const std::vector<int32_t> & persistentIds)4165 DMError ScreenSessionManager::AddVirtualScreenBlockList(const std::vector<int32_t>& persistentIds)
4166 {
4167 if (!Permission::IsSystemCalling()) {
4168 TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4169 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4170 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4171 }
4172 MockSessionManagerService::GetInstance().AddSkipSelfWhenShowOnVirtualScreenList(persistentIds);
4173 return DMError::DM_OK;
4174 }
4175
RemoveVirtualScreenBlockList(const std::vector<int32_t> & persistentIds)4176 DMError ScreenSessionManager::RemoveVirtualScreenBlockList(const std::vector<int32_t>& persistentIds)
4177 {
4178 if (!Permission::IsSystemCalling()) {
4179 TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4180 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4181 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4182 }
4183 MockSessionManagerService::GetInstance().RemoveSkipSelfWhenShowOnVirtualScreenList(persistentIds);
4184 return DMError::DM_OK;
4185 }
4186
SetScreenPrivacyMaskImage(ScreenId screenId,const std::shared_ptr<Media::PixelMap> & privacyMaskImg)4187 DMError ScreenSessionManager::SetScreenPrivacyMaskImage(ScreenId screenId,
4188 const std::shared_ptr<Media::PixelMap>& privacyMaskImg)
4189 {
4190 if (!Permission::IsSystemCalling()) {
4191 TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4192 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4193 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4194 }
4195 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4196 if (screenSession == nullptr) {
4197 TLOGE(WmsLogTag::DMS, "No such screen.");
4198 return DMError::DM_ERROR_NULLPTR;
4199 }
4200 ScreenId rsScreenId;
4201 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4202 TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
4203 return DMError::DM_ERROR_INVALID_PARAM;
4204 }
4205 int32_t res = -1;
4206 if (privacyMaskImg == nullptr) {
4207 TLOGI(WmsLogTag::DMS, "Clearing screen privacy mask image for screenId: %{public}" PRIu64"",
4208 static_cast<uint64_t>(screenId));
4209 res = rsInterface_.SetScreenSecurityMask(rsScreenId, nullptr);
4210 if (res != 0) {
4211 TLOGE(WmsLogTag::DMS, "Fail to set privacy mask image in RenderService");
4212 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
4213 }
4214 return DMError::DM_OK;
4215 }
4216 TLOGI(WmsLogTag::DMS, "Setting screen privacy mask image for screenId: %{public}" PRIu64"",
4217 static_cast<uint64_t>(screenId));
4218 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetScreenSecurityMask(%" PRIu64")", screenId);
4219 res = rsInterface_.SetScreenSecurityMask(rsScreenId, privacyMaskImg);
4220 if (res != 0) {
4221 TLOGE(WmsLogTag::DMS, "Fail to set privacy mask image in RenderService");
4222 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
4223 }
4224 return DMError::DM_OK;
4225 }
4226
SetVirtualMirrorScreenScaleMode(ScreenId screenId,ScreenScaleMode scaleMode)4227 DMError ScreenSessionManager::SetVirtualMirrorScreenScaleMode(ScreenId screenId, ScreenScaleMode scaleMode)
4228 {
4229 if (!SessionPermission::IsSystemCalling()) {
4230 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4231 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4232 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4233 }
4234 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4235 if (screenSession == nullptr) {
4236 TLOGE(WmsLogTag::DMS, "No such screen.");
4237 return DMError::DM_ERROR_INVALID_PARAM;
4238 }
4239 ScreenId rsScreenId;
4240 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4241 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
4242 return DMError::DM_ERROR_INVALID_PARAM;
4243 }
4244 bool res = rsInterface_.SetVirtualMirrorScreenScaleMode(rsScreenId, scaleMode);
4245 if (!res) {
4246 TLOGE(WmsLogTag::DMS, "failed in RenderService");
4247 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
4248 }
4249 return DMError::DM_OK;
4250 }
4251
SetVirtualMirrorScreenCanvasRotation(ScreenId screenId,bool autoRotate)4252 DMError ScreenSessionManager::SetVirtualMirrorScreenCanvasRotation(ScreenId screenId, bool autoRotate)
4253 {
4254 if (!SessionPermission::IsSystemCalling()) {
4255 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4256 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4257 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4258 }
4259 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4260 if (screenSession == nullptr) {
4261 TLOGE(WmsLogTag::DMS, "No such screen.");
4262 return DMError::DM_ERROR_INVALID_PARAM;
4263 }
4264 TLOGW(WmsLogTag::DMS, "enter set virtual mirror screen canvas rotation");
4265 bool res = false;
4266 ScreenId rsScreenId;
4267 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4268 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
4269 return DMError::DM_ERROR_INVALID_PARAM;
4270 }
4271 res = rsInterface_.SetVirtualMirrorScreenCanvasRotation(rsScreenId, autoRotate);
4272 if (!res) {
4273 TLOGE(WmsLogTag::DMS, "failed in RenderService");
4274 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
4275 }
4276 TLOGW(WmsLogTag::DMS, "success");
4277 return DMError::DM_OK;
4278 }
4279
ResizeVirtualScreen(ScreenId screenId,uint32_t width,uint32_t height)4280 DMError ScreenSessionManager::ResizeVirtualScreen(ScreenId screenId, uint32_t width, uint32_t height)
4281 {
4282 if (!SessionPermission::IsSystemCalling()) {
4283 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4284 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4285 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4286 }
4287 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64", width: %{public}u, height: %{public}u.",
4288 screenId, width, height);
4289 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4290 if (screenSession == nullptr) {
4291 TLOGE(WmsLogTag::DMS, "No such screen.");
4292 return DMError::DM_ERROR_INVALID_PARAM;
4293 }
4294 ScreenId rsScreenId;
4295 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4296 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
4297 return DMError::DM_ERROR_INVALID_PARAM;
4298 }
4299 rsInterface_.ResizeVirtualScreen(rsScreenId, width, height);
4300 screenSession->Resize(width, height);
4301 screenSession->PropertyChange(screenSession->GetScreenProperty(),
4302 ScreenPropertyChangeReason::VIRTUAL_SCREEN_RESIZE);
4303 return DMError::DM_OK;
4304 }
4305
DestroyVirtualScreen(ScreenId screenId)4306 DMError ScreenSessionManager::DestroyVirtualScreen(ScreenId screenId)
4307 {
4308 bool isCallingByThirdParty = Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION);
4309 if (!SessionPermission::IsSystemCalling() && !isCallingByThirdParty) {
4310 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4311 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4312 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4313 }
4314 if (static_cast<uint64_t>(screenId) < static_cast<uint64_t>(MINIMUM_VIRTUAL_SCREEN_ID)) {
4315 TLOGE(WmsLogTag::DMS, "virtual screenId is invalid, id: %{public}" PRIu64"", static_cast<uint64_t>(screenId));
4316 return DMError::DM_ERROR_INVALID_PARAM;
4317 }
4318 // virtual screen destroy callback to notify scb
4319 TLOGW(WmsLogTag::DMS, "start");
4320 OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED);
4321 ScreenId rsScreenId = SCREEN_ID_INVALID;
4322 {
4323 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4324 screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
4325 for (auto &agentIter : screenAgentMap_) {
4326 auto iter = std::find(agentIter.second.begin(), agentIter.second.end(), screenId);
4327 if (iter != agentIter.second.end()) {
4328 iter = agentIter.second.erase(iter);
4329 if (agentIter.first != nullptr && agentIter.second.empty()) {
4330 screenAgentMap_.erase(agentIter.first);
4331 }
4332 break;
4333 }
4334 }
4335 }
4336 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyVirtualScreen(%" PRIu64")", screenId);
4337 auto screen = GetScreenSession(screenId);
4338 if (rsScreenId != SCREEN_ID_INVALID && screen != nullptr) {
4339 if (CheckScreenInScreenGroup(screen)) {
4340 NotifyDisplayDestroy(screenId);
4341 }
4342 {
4343 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4344 auto screenGroup = RemoveFromGroupLocked(screen);
4345 if (screenGroup != nullptr) {
4346 NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
4347 }
4348 screenSessionMap_.erase(screenId);
4349 }
4350 NotifyScreenDisconnected(screenId);
4351 TLOGW(WmsLogTag::DMS, "destroy success, id: %{public}" PRIu64, screenId);
4352 }
4353 screenIdManager_.DeleteScreenId(screenId);
4354 virtualScreenCount_ = virtualScreenCount_ > 0 ? virtualScreenCount_ - 1 : 0;
4355 NotifyCaptureStatusChanged();
4356 if (rsScreenId == SCREEN_ID_INVALID) {
4357 TLOGE(WmsLogTag::DMS, "No corresponding rsScreenId");
4358 return isCallingByThirdParty ? DMError::DM_ERROR_NULLPTR : DMError::DM_ERROR_INVALID_PARAM;
4359 }
4360 rsInterface_.RemoveVirtualScreen(rsScreenId);
4361 return DMError::DM_OK;
4362 }
4363
DisableMirror(bool disableOrNot)4364 DMError ScreenSessionManager::DisableMirror(bool disableOrNot)
4365 {
4366 TLOGW(WmsLogTag::DMS, "start %{public}d", disableOrNot);
4367 if (!SessionPermission::IsSystemCalling()) {
4368 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4369 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4370 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4371 }
4372 TLOGI(WmsLogTag::DMS, "enter %{public}d", disableOrNot);
4373 if (disableOrNot) {
4374 std::vector<ScreenId> screenIds;
4375 auto allScreenIds = GetAllScreenIds();
4376 for (auto screenId : allScreenIds) {
4377 auto screen = GetScreenSession(screenId);
4378 if (screen && screen->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
4379 screenIds.push_back(screenId);
4380 }
4381 }
4382 StopMirror(screenIds);
4383 }
4384 return DMError::DM_OK;
4385 }
4386
MirrorSwitchNotify(ScreenId screenId)4387 void ScreenSessionManager::MirrorSwitchNotify(ScreenId screenId)
4388 {
4389 auto mirrorScreen = GetScreenSession(screenId);
4390 if (mirrorScreen != nullptr) {
4391 mirrorScreen->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
4392 NotifyScreenChanged(mirrorScreen->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE);
4393 }
4394 }
4395
DoMakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,DMRect mainScreenRegion,ScreenId & screenGroupId)4396 DMError ScreenSessionManager::DoMakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
4397 DMRect mainScreenRegion, ScreenId& screenGroupId)
4398 {
4399 #ifdef WM_MULTI_SCREEN_ENABLE
4400 TLOGW(WmsLogTag::DMS, "enter!");
4401 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4402 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4403 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4404 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4405 }
4406 if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
4407 TLOGW(WmsLogTag::DMS, "disabled by edm!");
4408 return DMError::DM_ERROR_INVALID_PERMISSION;
4409 }
4410
4411 TLOGW(WmsLogTag::DMS, "mainScreenId :%{public}" PRIu64"", mainScreenId);
4412 auto allMirrorScreenIds = GetAllValidScreenIds(mirrorScreenIds);
4413 auto iter = std::find(allMirrorScreenIds.begin(), allMirrorScreenIds.end(), mainScreenId);
4414 if (iter != allMirrorScreenIds.end()) {
4415 allMirrorScreenIds.erase(iter);
4416 }
4417 auto mainScreen = GetScreenSession(mainScreenId);
4418 if (mainScreen == nullptr || allMirrorScreenIds.empty()) {
4419 TLOGE(WmsLogTag::DMS, "MakeMirror fail. mainScreen :%{public}" PRIu64", screens size:%{public}u",
4420 mainScreenId, static_cast<uint32_t>(allMirrorScreenIds.size()));
4421 return DMError::DM_ERROR_NULLPTR;
4422 }
4423 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeMirror start");
4424 for (ScreenId screenId : allMirrorScreenIds) {
4425 OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED);
4426 }
4427 #ifdef FOLD_ABILITY_ENABLE
4428 if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
4429 foldScreenController_->SetMainScreenRegion(mainScreenRegion);
4430 }
4431 #endif
4432 DMError makeResult = MultiScreenManager::GetInstance().MirrorSwitch(mainScreenId,
4433 allMirrorScreenIds, mainScreenRegion, screenGroupId);
4434 if (makeResult != DMError::DM_OK) {
4435 TLOGE(WmsLogTag::DMS, "MakeMirror set mirror failed.");
4436 return makeResult;
4437 }
4438 for (ScreenId screenId : allMirrorScreenIds) {
4439 MirrorSwitchNotify(screenId);
4440 }
4441 RegisterCastObserver(allMirrorScreenIds);
4442 TLOGW(WmsLogTag::DMS, "make mirror notify scb end makeResult=%{public}d", makeResult);
4443 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeMirror end");
4444 return makeResult;
4445 #else
4446 return DMError::DM_OK;
4447 #endif
4448 }
4449
MakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,ScreenId & screenGroupId)4450 DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
4451 ScreenId& screenGroupId)
4452 {
4453 return DoMakeMirror(mainScreenId, mirrorScreenIds, DMRect::NONE(), screenGroupId);
4454 }
4455
MakeMirrorForRecord(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,ScreenId & screenGroupId)4456 DMError ScreenSessionManager::MakeMirrorForRecord(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
4457 ScreenId& screenGroupId)
4458 {
4459 #ifdef FOLD_ABILITY_ENABLE
4460 TLOGW(WmsLogTag::DMS, "start");
4461 ScreenId realScreenId = mainScreenId;
4462 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && mainScreenId == DISPLAY_ID_FAKE) {
4463 if (!SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
4464 TLOGE(WmsLogTag::DMS, "fake display is not exist!");
4465 return DMError::DM_ERROR_INVALID_PARAM;
4466 }
4467 realScreenId = 0;
4468 }
4469 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
4470 SuperFoldPolicy::GetInstance().IsNeedSetSnapshotRect(mainScreenId)) {
4471 DMRect mainScreenRect = SuperFoldPolicy::GetInstance().GetRecordRect(mainScreenId);
4472 return DoMakeMirror(realScreenId, mirrorScreenIds, mainScreenRect, screenGroupId);
4473 }
4474 #endif
4475 return DoMakeMirror(mainScreenId, mirrorScreenIds, DMRect::NONE(), screenGroupId);
4476 }
4477
4478
MakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,DMRect mainScreenRegion,ScreenId & screenGroupId)4479 DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
4480 DMRect mainScreenRegion, ScreenId& screenGroupId)
4481 {
4482 return DoMakeMirror(mainScreenId, mirrorScreenIds, mainScreenRegion, screenGroupId);
4483 }
4484
RegisterCastObserver(std::vector<ScreenId> & mirrorScreenIds)4485 void ScreenSessionManager::RegisterCastObserver(std::vector<ScreenId>& mirrorScreenIds)
4486 {
4487 mirrorScreenIds_ = mirrorScreenIds;
4488 TLOGI(WmsLogTag::DMS, "Register Setting cast Observer");
4489 SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetCastFromSettingData(); };
4490 ScreenSettingHelper::RegisterSettingCastObserver(updateFunc);
4491 }
4492
SetCastFromSettingData()4493 void ScreenSessionManager::SetCastFromSettingData()
4494 {
4495 bool enable;
4496 bool ret = ScreenSettingHelper::GetSettingCast(enable);
4497 if (!ret) {
4498 TLOGW(WmsLogTag::DMS, "get setting cast failed, default enable");
4499 enable = true;
4500 } else {
4501 TLOGI(WmsLogTag::DMS, "get setting cast success, enable: %{public}u", enable);
4502 }
4503 for (ScreenId screenId : mirrorScreenIds_) {
4504 ScreenId rsScreenId;
4505 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4506 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
4507 continue;
4508 }
4509 rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, enable);
4510 }
4511 }
4512
RegisterSettingRotationObserver()4513 void ScreenSessionManager::RegisterSettingRotationObserver()
4514 {
4515 TLOGI(WmsLogTag::DMS, "start");
4516 SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) {
4517 int32_t rotation = -1;
4518 int32_t screenId = -1;
4519 if (ScreenSettingHelper::GetSettingRotation(rotation) &&
4520 ScreenSettingHelper::GetSettingRotationScreenID(screenId)) {
4521 TLOGNI(WmsLogTag::DMS, "current dms setting rotation:%{public}d, screenId:%{public}d",
4522 rotation, screenId);
4523 } else {
4524 TLOGNI(WmsLogTag::DMS, "get current dms setting rotation and screenId failed");
4525 }
4526 };
4527 ScreenSettingHelper::RegisterSettingRotationObserver(updateFunc);
4528 }
4529
RegisterSettingscreenSkipProtectedWindowObserver()4530 void ScreenSessionManager::RegisterSettingscreenSkipProtectedWindowObserver()
4531 {
4532 TLOGI(WmsLogTag::DMS, "start");
4533 SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetScreenSkipProtectedWindowInner(); };
4534 ScreenSettingHelper::RegisterSettingscreenSkipProtectedWindowObserver(updateFunc);
4535 }
4536
StopMirror(const std::vector<ScreenId> & mirrorScreenIds)4537 DMError ScreenSessionManager::StopMirror(const std::vector<ScreenId>& mirrorScreenIds)
4538 {
4539 if (!SessionPermission::IsSystemCalling()) {
4540 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4541 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4542 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4543 }
4544 auto allMirrorScreenIds = GetAllValidScreenIds(mirrorScreenIds);
4545 if (allMirrorScreenIds.empty()) {
4546 TLOGW(WmsLogTag::DMS, "done. screens' size:%{public}u",
4547 static_cast<uint32_t>(allMirrorScreenIds.size()));
4548 return DMError::DM_OK;
4549 }
4550
4551 DMError ret = StopScreens(allMirrorScreenIds, ScreenCombination::SCREEN_MIRROR);
4552 if (ret != DMError::DM_OK) {
4553 TLOGE(WmsLogTag::DMS, "failed.");
4554 return ret;
4555 }
4556 ScreenSettingHelper::UnregisterSettingCastObserver();
4557
4558 return DMError::DM_OK;
4559 }
4560
StopScreens(const std::vector<ScreenId> & screenIds,ScreenCombination stopCombination)4561 DMError ScreenSessionManager::StopScreens(const std::vector<ScreenId>& screenIds, ScreenCombination stopCombination)
4562 {
4563 for (ScreenId screenId : screenIds) {
4564 TLOGW(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64"", screenId);
4565 auto screen = GetScreenSession(screenId);
4566 if (screen == nullptr) {
4567 TLOGW(WmsLogTag::DMS, "screen:%{public}" PRIu64" is nullptr", screenId);
4568 continue;
4569 }
4570 sptr<ScreenSessionGroup> screenGroup = GetAbstractScreenGroup(screen->groupSmsId_);
4571 if (!screenGroup) {
4572 TLOGW(WmsLogTag::DMS, "groupDmsId:%{public}" PRIu64"is not in smsScreenGroupMap_",
4573 screen->groupSmsId_);
4574 continue;
4575 }
4576 if (screenGroup->combination_ != stopCombination) {
4577 TLOGW(WmsLogTag::DMS, "try to stop screen in another combination");
4578 continue;
4579 }
4580 if (screenGroup->combination_ == ScreenCombination::SCREEN_MIRROR &&
4581 screen->screenId_ == screenGroup->mirrorScreenId_) {
4582 TLOGW(WmsLogTag::DMS, "try to stop main mirror screen");
4583 continue;
4584 }
4585 bool res = RemoveChildFromGroup(screen, screenGroup);
4586 if (res) {
4587 NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
4588 }
4589 }
4590 return DMError::DM_OK;
4591 }
4592
GetVirtualScreenFlag(ScreenId screenId)4593 VirtualScreenFlag ScreenSessionManager::GetVirtualScreenFlag(ScreenId screenId)
4594 {
4595 if (!SessionPermission::IsSystemCalling()) {
4596 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4597 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4598 return VirtualScreenFlag::DEFAULT;
4599 }
4600 auto screen = GetScreenSession(screenId);
4601 if (screen == nullptr) {
4602 TLOGE(WmsLogTag::DMS, "screen session null");
4603 return VirtualScreenFlag::DEFAULT;
4604 }
4605 return screen->GetVirtualScreenFlag();
4606 }
4607
SetVirtualScreenFlag(ScreenId screenId,VirtualScreenFlag screenFlag)4608 DMError ScreenSessionManager::SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag)
4609 {
4610 if (!SessionPermission::IsSystemCalling()) {
4611 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4612 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4613 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4614 }
4615 if (screenFlag < VirtualScreenFlag::DEFAULT || screenFlag >= VirtualScreenFlag::MAX) {
4616 TLOGE(WmsLogTag::DMS, "range error");
4617 return DMError::DM_ERROR_INVALID_PARAM;
4618 }
4619 auto screen = GetScreenSession(screenId);
4620 if (screen == nullptr) {
4621 TLOGE(WmsLogTag::DMS, "screen session null");
4622 return DMError::DM_ERROR_INVALID_PARAM;
4623 }
4624 screen->SetVirtualScreenFlag(screenFlag);
4625 return DMError::DM_OK;
4626 }
4627
SetVirtualScreenRefreshRate(ScreenId screenId,uint32_t refreshInterval)4628 DMError ScreenSessionManager::SetVirtualScreenRefreshRate(ScreenId screenId, uint32_t refreshInterval)
4629 {
4630 if (!SessionPermission::IsSystemCalling()) {
4631 TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
4632 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4633 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4634 }
4635 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64", refreshInterval: %{public}u",
4636 screenId, refreshInterval);
4637 if (screenId == GetDefaultScreenId()) {
4638 TLOGE(WmsLogTag::DMS, "cannot set refresh rate of main screen id: %{public}" PRIu64, GetDefaultScreenId());
4639 return DMError::DM_ERROR_INVALID_PARAM;
4640 }
4641 if (refreshInterval == 0) {
4642 TLOGE(WmsLogTag::DMS, "refresh interval is 0.");
4643 return DMError::DM_ERROR_INVALID_PARAM;
4644 }
4645 auto screenSession = GetScreenSession(screenId);
4646 auto defaultScreenSession = GetDefaultScreenSession();
4647 if (screenSession == nullptr || defaultScreenSession == nullptr) {
4648 TLOGE(WmsLogTag::DMS, "screenSession is null.");
4649 return DMError::DM_ERROR_INVALID_PARAM;
4650 }
4651 ScreenId rsScreenId;
4652 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4653 TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
4654 return DMError::DM_ERROR_INVALID_PARAM;
4655 }
4656 int32_t res = rsInterface_.SetScreenSkipFrameInterval(rsScreenId, refreshInterval);
4657 if (res != StatusCode::SUCCESS) {
4658 TLOGE(WmsLogTag::DMS, "rsInterface error: %{public}d", res);
4659 return DMError::DM_ERROR_INVALID_PARAM;
4660 }
4661 // when skipFrameInterval > 10 means the skipFrameInterval is the virtual screen refresh rate
4662 if (refreshInterval > IRREGULAR_REFRESH_RATE_SKIP_THRETHOLD) {
4663 screenSession->UpdateRefreshRate(refreshInterval);
4664 } else {
4665 screenSession->UpdateRefreshRate(defaultScreenSession->GetRefreshRate() / refreshInterval);
4666 }
4667 TLOGW(WmsLogTag::DMS, "refreshInterval is %{public}d", refreshInterval);
4668 return DMError::DM_OK;
4669 }
4670
VirtualScreenUniqueSwitch(const std::vector<ScreenId> & screenIds)4671 DMError ScreenSessionManager::VirtualScreenUniqueSwitch(const std::vector<ScreenId>& screenIds)
4672 {
4673 #ifdef WM_MULTI_SCREEN_ENABLE
4674 TLOGW(WmsLogTag::DMS, "enter");
4675 auto defaultScreen = GetDefaultScreenSession();
4676 if (!defaultScreen) {
4677 TLOGE(WmsLogTag::DMS, "default screen is nullptr");
4678 return DMError::DM_ERROR_NULLPTR;
4679 }
4680 defaultScreen->groupSmsId_ = 1;
4681 {
4682 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4683 auto iter = smsScreenGroupMap_.find(defaultScreen->groupSmsId_);
4684 if (iter != smsScreenGroupMap_.end()) {
4685 smsScreenGroupMap_.erase(iter);
4686 }
4687 }
4688 DMError uniqueSwitchRet = MultiScreenManager::GetInstance().VirtualScreenUniqueSwitch(defaultScreen, screenIds);
4689 TLOGW(WmsLogTag::DMS, "result: %{public}d", uniqueSwitchRet);
4690 return uniqueSwitchRet;
4691 #else
4692 return DMError::DM_OK;
4693 #endif
4694 }
4695
MakeUniqueScreen(const std::vector<ScreenId> & screenIds,std::vector<DisplayId> & displayIds)4696 DMError ScreenSessionManager::MakeUniqueScreen(const std::vector<ScreenId>& screenIds,
4697 std::vector<DisplayId>& displayIds)
4698 {
4699 #ifdef WM_MULTI_SCREEN_ENABLE
4700 bool isCallingByThirdParty = Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION);
4701 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd() && !isCallingByThirdParty) {
4702 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4703 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4704 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4705 }
4706 TLOGW(WmsLogTag::DMS, "enter!");
4707 if (screenIds.empty()) {
4708 TLOGE(WmsLogTag::DMS, "screen is empty");
4709 return DMError::DM_ERROR_INVALID_PARAM;
4710 }
4711 std::vector<ScreenId> validScreenIds;
4712 for (auto screenId : screenIds) {
4713 if (!IsDefaultMirrorMode(screenId)) {
4714 continue;
4715 }
4716 validScreenIds.emplace_back(screenId);
4717 }
4718 const auto& allUniqueScreenIds = GetAllValidScreenIds(validScreenIds);
4719 if (allUniqueScreenIds.empty()) {
4720 TLOGE(WmsLogTag::DMS, "screenIds is invalid.");
4721 return DMError::DM_ERROR_NULLPTR;
4722 }
4723 ScreenId uniqueScreenId = validScreenIds[0];
4724 auto uniqueScreen = GetScreenSession(uniqueScreenId);
4725 if (uniqueScreen != nullptr) {
4726 if (uniqueScreen->GetSourceMode() == ScreenSourceMode::SCREEN_UNIQUE) {
4727 TLOGW(WmsLogTag::DMS, "make unique ignore");
4728 return DMError::DM_OK;
4729 }
4730 if (isCallingByThirdParty) {
4731 uniqueScreen->SetInnerName("CustomScbScreen");
4732 }
4733 return MultiScreenManager::GetInstance().UniqueSwitch(allUniqueScreenIds, displayIds);
4734 }
4735 return DoMakeUniqueScreenOld(allUniqueScreenIds, displayIds, isCallingByThirdParty);
4736 }
4737
DoMakeUniqueScreenOld(const std::vector<ScreenId> & allUniqueScreenIds,std::vector<DisplayId> & displayIds,bool isCallingByThirdParty)4738 DMError ScreenSessionManager::DoMakeUniqueScreenOld(const std::vector<ScreenId>& allUniqueScreenIds,
4739 std::vector<DisplayId>& displayIds, bool isCallingByThirdParty)
4740 {
4741 for (auto screenId : allUniqueScreenIds) {
4742 ScreenId rsScreenId = SCREEN_ID_INVALID;
4743 bool res = ConvertScreenIdToRsScreenId(screenId, rsScreenId);
4744 TLOGI(WmsLogTag::DMS, "unique screenId: %{public}" PRIu64" rsScreenId: %{public}" PRIu64,
4745 screenId, rsScreenId);
4746 if (!res) {
4747 TLOGE(WmsLogTag::DMS, "convert screenId to rsScreenId failed");
4748 continue;
4749 }
4750 auto screenSession = GetScreenSession(screenId);
4751 if (!screenSession) {
4752 TLOGE(WmsLogTag::DMS, "screen session is nullptr");
4753 continue;
4754 }
4755 displayIds.emplace_back(static_cast<uint64_t>(screenId));
4756 Rosen::RSDisplayNodeConfig rsConfig;
4757 rsConfig.screenId = rsScreenId;
4758 screenSession->CreateDisplayNode(rsConfig);
4759 screenSession->SetDisplayNodeScreenId(rsScreenId);
4760 if (isCallingByThirdParty) {
4761 screenSession->SetInnerName("CustomScbScreen");
4762 }
4763 // notify scb to build Screen widget
4764 OnVirtualScreenChange(screenId, ScreenEvent::CONNECTED);
4765 }
4766 auto transactionProxy = RSTransactionProxy::GetInstance();
4767 if (transactionProxy != nullptr) {
4768 TLOGD(WmsLogTag::DMS, "flush data");
4769 transactionProxy->FlushImplicitTransaction();
4770 }
4771 #endif
4772 return DMError::DM_OK;
4773 }
4774
MakeExpand(std::vector<ScreenId> screenId,std::vector<Point> startPoint,ScreenId & screenGroupId)4775 DMError ScreenSessionManager::MakeExpand(std::vector<ScreenId> screenId,
4776 std::vector<Point> startPoint,
4777 ScreenId& screenGroupId)
4778 {
4779 TLOGI(WmsLogTag::DMS, "enter!");
4780 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4781 TLOGE(WmsLogTag::DMS, "permission denied! pid: %{public}d", IPCSkeleton::GetCallingPid());
4782 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4783 }
4784 if (screenId.empty() || startPoint.empty() || screenId.size() != startPoint.size()) {
4785 TLOGE(WmsLogTag::DMS, "create expand fail, screenId size:%{public}ud,startPoint size:%{public}ud",
4786 static_cast<uint32_t>(screenId.size()), static_cast<uint32_t>(startPoint.size()));
4787 return DMError::DM_ERROR_INVALID_PARAM;
4788 }
4789 std::map<ScreenId, Point> pointsMap;
4790 uint32_t size = screenId.size();
4791 for (uint32_t i = 0; i < size; i++) {
4792 if (pointsMap.find(screenId[i]) != pointsMap.end()) {
4793 continue;
4794 }
4795 pointsMap[screenId[i]] = startPoint[i];
4796 }
4797 ScreenId defaultScreenId = GetDefaultScreenId();
4798 auto allExpandScreenIds = GetAllValidScreenIds(screenId);
4799 auto iter = std::find(allExpandScreenIds.begin(), allExpandScreenIds.end(), defaultScreenId);
4800 if (iter != allExpandScreenIds.end()) {
4801 allExpandScreenIds.erase(iter);
4802 }
4803 if (allExpandScreenIds.empty()) {
4804 TLOGE(WmsLogTag::DMS, "allExpandScreenIds is empty. make expand failed.");
4805 return DMError::DM_ERROR_NULLPTR;
4806 }
4807 std::shared_ptr<RSDisplayNode> rsDisplayNode;
4808 std::vector<Point> points;
4809 for (uint32_t i = 0; i < allExpandScreenIds.size(); i++) {
4810 rsDisplayNode = GetRSDisplayNodeByScreenId(allExpandScreenIds[i]);
4811 points.emplace_back(pointsMap[allExpandScreenIds[i]]);
4812 if (rsDisplayNode != nullptr) {
4813 rsDisplayNode->SetDisplayOffset(pointsMap[allExpandScreenIds[i]].posX_,
4814 pointsMap[allExpandScreenIds[i]].posY_);
4815 }
4816 }
4817 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeExpand");
4818 if (!OnMakeExpand(allExpandScreenIds, points)) {
4819 return DMError::DM_ERROR_NULLPTR;
4820 }
4821 auto screen = GetScreenSession(allExpandScreenIds[0]);
4822 if (screen == nullptr || GetAbstractScreenGroup(screen->groupSmsId_) == nullptr) {
4823 return DMError::DM_ERROR_NULLPTR;
4824 }
4825 screenGroupId = screen->groupSmsId_;
4826 return DMError::DM_OK;
4827 }
4828
OnMakeExpand(std::vector<ScreenId> screenId,std::vector<Point> startPoint)4829 bool ScreenSessionManager::OnMakeExpand(std::vector<ScreenId> screenId, std::vector<Point> startPoint)
4830 {
4831 ScreenId defaultScreenId = GetDefaultScreenId();
4832 TLOGI(WmsLogTag::DMS, "defaultScreenId:%{public}" PRIu64"", defaultScreenId);
4833 auto defaultScreen = GetScreenSession(defaultScreenId);
4834 if (defaultScreen == nullptr) {
4835 TLOGI(WmsLogTag::DMS, "failed.");
4836 return false;
4837 }
4838 auto group = GetAbstractScreenGroup(defaultScreen->groupSmsId_);
4839 if (group == nullptr) {
4840 group = AddToGroupLocked(defaultScreen);
4841 if (group == nullptr) {
4842 TLOGE(WmsLogTag::DMS, "group is nullptr");
4843 return false;
4844 }
4845 NotifyScreenGroupChanged(defaultScreen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
4846 }
4847 bool filterExpandScreen = group->combination_ == ScreenCombination::SCREEN_EXPAND;
4848 ChangeScreenGroup(group, screenId, startPoint, filterExpandScreen, ScreenCombination::SCREEN_EXPAND);
4849 TLOGI(WmsLogTag::DMS, "success");
4850 return true;
4851 }
4852
StopExpand(const std::vector<ScreenId> & expandScreenIds)4853 DMError ScreenSessionManager::StopExpand(const std::vector<ScreenId>& expandScreenIds)
4854 {
4855 if (!SessionPermission::IsSystemCalling()) {
4856 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4857 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4858 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4859 }
4860 auto allExpandScreenIds = GetAllValidScreenIds(expandScreenIds);
4861 if (allExpandScreenIds.empty()) {
4862 TLOGI(WmsLogTag::DMS, "done. screens' size:%{public}u",
4863 static_cast<uint32_t>(allExpandScreenIds.size()));
4864 return DMError::DM_OK;
4865 }
4866
4867 DMError ret = StopScreens(allExpandScreenIds, ScreenCombination::SCREEN_EXPAND);
4868 if (ret != DMError::DM_OK) {
4869 TLOGE(WmsLogTag::DMS, "stop expand failed.");
4870 return ret;
4871 }
4872
4873 return DMError::DM_OK;
4874 }
4875
ConvertToRsScreenId(ScreenId smsScreenId,ScreenId & rsScreenId) const4876 bool ScreenSessionManager::ScreenIdManager::ConvertToRsScreenId(ScreenId smsScreenId, ScreenId& rsScreenId) const
4877 {
4878 std::shared_lock lock(screenIdMapMutex_);
4879 auto iter = sms2RsScreenIdMap_.find(smsScreenId);
4880 if (iter == sms2RsScreenIdMap_.end()) {
4881 return false;
4882 }
4883 rsScreenId = iter->second;
4884 return true;
4885 }
4886
ConvertToRsScreenId(ScreenId screenId) const4887 ScreenId ScreenSessionManager::ScreenIdManager::ConvertToRsScreenId(ScreenId screenId) const
4888 {
4889 ScreenId rsScreenId = SCREEN_ID_INVALID;
4890 ConvertToRsScreenId(screenId, rsScreenId);
4891 return rsScreenId;
4892 }
4893
ConvertToSmsScreenId(ScreenId rsScreenId) const4894 ScreenId ScreenSessionManager::ScreenIdManager::ConvertToSmsScreenId(ScreenId rsScreenId) const
4895 {
4896 ScreenId smsScreenId = SCREEN_ID_INVALID;
4897 ConvertToSmsScreenId(rsScreenId, smsScreenId);
4898 return smsScreenId;
4899 }
4900
ConvertToSmsScreenId(ScreenId rsScreenId,ScreenId & smsScreenId) const4901 bool ScreenSessionManager::ScreenIdManager::ConvertToSmsScreenId(ScreenId rsScreenId, ScreenId& smsScreenId) const
4902 {
4903 std::shared_lock lock(screenIdMapMutex_);
4904 auto iter = rs2SmsScreenIdMap_.find(rsScreenId);
4905 if (iter == rs2SmsScreenIdMap_.end()) {
4906 return false;
4907 }
4908 smsScreenId = iter->second;
4909 return true;
4910 }
4911
CreateAndGetNewScreenId(ScreenId rsScreenId)4912 ScreenId ScreenSessionManager::ScreenIdManager::CreateAndGetNewScreenId(ScreenId rsScreenId)
4913 {
4914 std::unique_lock lock(screenIdMapMutex_);
4915 ScreenId smsScreenId = smsScreenCount_++;
4916 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64"", smsScreenId);
4917 if (sms2RsScreenIdMap_.find(smsScreenId) != sms2RsScreenIdMap_.end()) {
4918 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64" exit", smsScreenId);
4919 }
4920 sms2RsScreenIdMap_[smsScreenId] = rsScreenId;
4921 if (rsScreenId == SCREEN_ID_INVALID) {
4922 return smsScreenId;
4923 }
4924 if (rs2SmsScreenIdMap_.find(rsScreenId) != rs2SmsScreenIdMap_.end()) {
4925 TLOGW(WmsLogTag::DMS, "rsScreenId: %{public}" PRIu64" exit", rsScreenId);
4926 }
4927 rs2SmsScreenIdMap_[rsScreenId] = smsScreenId;
4928 return smsScreenId;
4929 }
4930
UpdateScreenId(ScreenId rsScreenId,ScreenId smsScreenId)4931 void ScreenSessionManager::ScreenIdManager::UpdateScreenId(ScreenId rsScreenId, ScreenId smsScreenId)
4932 {
4933 std::unique_lock lock(screenIdMapMutex_);
4934 rs2SmsScreenIdMap_[rsScreenId] = smsScreenId;
4935 sms2RsScreenIdMap_[smsScreenId] = rsScreenId;
4936 }
4937
DeleteScreenId(ScreenId smsScreenId)4938 bool ScreenSessionManager::ScreenIdManager::DeleteScreenId(ScreenId smsScreenId)
4939 {
4940 std::unique_lock lock(screenIdMapMutex_);
4941 auto iter = sms2RsScreenIdMap_.find(smsScreenId);
4942 if (iter == sms2RsScreenIdMap_.end()) {
4943 return false;
4944 }
4945 ScreenId rsScreenId = iter->second;
4946 sms2RsScreenIdMap_.erase(smsScreenId);
4947 rs2SmsScreenIdMap_.erase(rsScreenId);
4948 return true;
4949 }
4950
HasRsScreenId(ScreenId smsScreenId) const4951 bool ScreenSessionManager::ScreenIdManager::HasRsScreenId(ScreenId smsScreenId) const
4952 {
4953 std::shared_lock lock(screenIdMapMutex_);
4954 return rs2SmsScreenIdMap_.find(smsScreenId) != rs2SmsScreenIdMap_.end();
4955 }
4956
InitVirtualScreen(ScreenId smsScreenId,ScreenId rsId,VirtualScreenOption option)4957 sptr<ScreenSession> ScreenSessionManager::InitVirtualScreen(ScreenId smsScreenId, ScreenId rsId,
4958 VirtualScreenOption option)
4959 {
4960 TLOGI(WmsLogTag::DMS, "Enter");
4961 ScreenSessionConfig config = {
4962 .screenId = smsScreenId,
4963 .rsId = rsId,
4964 .defaultScreenId = GetDefaultScreenId(),
4965 .name = option.name_,
4966 };
4967 sptr<ScreenSession> screenSession =
4968 new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
4969 sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
4970 if (screenSession == nullptr || info == nullptr) {
4971 TLOGI(WmsLogTag::DMS, "new screenSession or info failed");
4972 screenIdManager_.DeleteScreenId(smsScreenId);
4973 rsInterface_.RemoveVirtualScreen(rsId);
4974 return nullptr;
4975 }
4976 info->width_ = option.width_;
4977 info->height_ = option.height_;
4978 auto defaultScreen = GetScreenSession(GetDefaultScreenId());
4979 if (defaultScreen != nullptr && defaultScreen->GetActiveScreenMode() != nullptr) {
4980 info->refreshRate_ = defaultScreen->GetActiveScreenMode()->refreshRate_;
4981 }
4982 screenSession->modes_.emplace_back(info);
4983 screenSession->activeIdx_ = 0;
4984 screenSession->SetScreenType(ScreenType::VIRTUAL);
4985 screenSession->SetVirtualPixelRatio(option.density_);
4986 screenSession->SetIsPcUse(g_isPcDevice ? true : false);
4987 screenSession->SetDisplayBoundary(RectF(0, 0, option.width_, option.height_), 0);
4988 screenSession->RegisterScreenChangeListener(this);
4989 return screenSession;
4990 }
4991
InitAbstractScreenModesInfo(sptr<ScreenSession> & screenSession)4992 bool ScreenSessionManager::InitAbstractScreenModesInfo(sptr<ScreenSession>& screenSession)
4993 {
4994 TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenSupportedModes");
4995 std::vector<RSScreenModeInfo> allModes = rsInterface_.GetScreenSupportedModes(
4996 screenIdManager_.ConvertToRsScreenId(screenSession->screenId_));
4997 if (allModes.size() == 0) {
4998 TLOGE(WmsLogTag::DMS, "allModes.size() == 0, screenId=%{public}" PRIu64"", screenSession->rsId_);
4999 return false;
5000 }
5001 for (const RSScreenModeInfo& rsScreenModeInfo : allModes) {
5002 sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
5003 if (info == nullptr) {
5004 TLOGE(WmsLogTag::DMS, "create SupportedScreenModes failed");
5005 return false;
5006 }
5007 info->id_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenModeId());
5008 info->width_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenWidth());
5009 info->height_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenHeight());
5010 info->refreshRate_ = rsScreenModeInfo.GetScreenRefreshRate();
5011 screenSession->modes_.push_back(info);
5012 TLOGW(WmsLogTag::DMS, "fill screen idx:%{public}d w/h:%{public}d/%{public}d",
5013 rsScreenModeInfo.GetScreenModeId(), info->width_, info->height_);
5014 }
5015 TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenActiveMode");
5016 int32_t activeModeId = rsInterface_.GetScreenActiveMode(screenSession->rsId_).GetScreenModeId();
5017 TLOGW(WmsLogTag::DMS, "fill screen activeModeId:%{public}d", activeModeId);
5018 if (static_cast<std::size_t>(activeModeId) >= allModes.size()) {
5019 TLOGE(WmsLogTag::DMS, "activeModeId exceed, screenId=%{public}" PRIu64", activeModeId:%{public}d/%{public}ud",
5020 screenSession->rsId_, activeModeId, static_cast<uint32_t>(allModes.size()));
5021 return false;
5022 }
5023 screenSession->activeIdx_ = activeModeId;
5024 return true;
5025 }
5026
InitAndGetScreen(ScreenId rsScreenId)5027 sptr<ScreenSession> ScreenSessionManager::InitAndGetScreen(ScreenId rsScreenId)
5028 {
5029 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5030 ScreenId smsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsScreenId);
5031 RSScreenCapability screenCapability = rsInterface_.GetScreenCapability(rsScreenId);
5032 TLOGI(WmsLogTag::DMS, "Screen name is %{public}s, phyWidth is %{public}u, phyHeight is %{public}u",
5033 screenCapability.GetName().c_str(), screenCapability.GetPhyWidth(), screenCapability.GetPhyHeight());
5034 ScreenSessionConfig config = {
5035 .screenId = smsScreenId,
5036 .rsId = rsScreenId,
5037 .defaultScreenId = GetDefaultScreenId(),
5038 .name = screenCapability.GetName(),
5039 };
5040 sptr<ScreenSession> screenSession =
5041 new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_VIRTUAL);
5042 if (screenSession == nullptr) {
5043 TLOGE(WmsLogTag::DMS, "screenSession == nullptr.");
5044 screenIdManager_.DeleteScreenId(smsScreenId);
5045 return nullptr;
5046 }
5047 if (!InitAbstractScreenModesInfo(screenSession)) {
5048 screenIdManager_.DeleteScreenId(smsScreenId);
5049 TLOGE(WmsLogTag::DMS, "failed.");
5050 return nullptr;
5051 }
5052 TLOGI(WmsLogTag::DMS, "screenSessionMap_ add screenId=%{public}" PRIu64"", smsScreenId);
5053 screenSessionMap_.insert(std::make_pair(smsScreenId, screenSession));
5054 return screenSession;
5055 }
5056
IsExtendMode()5057 bool ScreenSessionManager::IsExtendMode()
5058 {
5059 std::vector<ScreenId> mainVector;
5060 std::vector<ScreenId> extendVector;
5061 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5062 for (const auto& pair : screenSessionMap_) {
5063 sptr<ScreenSession> session = pair.second;
5064 if (!session) {
5065 TLOGE(WmsLogTag::DMS, "screenId=%{public}" PRIu64", session is null", pair.first);
5066 continue;
5067 }
5068 if (session->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
5069 extendVector.push_back(session->GetScreenId());
5070 }
5071 if (session->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
5072 mainVector.push_back(session->GetScreenId());
5073 }
5074 }
5075 std::ostringstream oss;
5076 oss << "main screenId:";
5077 for (const auto& screenId : mainVector) {
5078 oss << static_cast<uint64_t>(screenId);
5079 }
5080 oss << ", extend screenId:";
5081 for (const auto& screenId : extendVector) {
5082 oss << static_cast<uint64_t>(screenId);
5083 }
5084 oss << std::endl;
5085 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
5086 return mainVector.size() > 0 && extendVector.size() > 0;
5087 }
5088
AddToGroupLocked(sptr<ScreenSession> newScreen,bool isUnique)5089 sptr<ScreenSessionGroup> ScreenSessionManager::AddToGroupLocked(sptr<ScreenSession> newScreen, bool isUnique)
5090 {
5091 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5092 sptr<ScreenSessionGroup> res;
5093 if (smsScreenGroupMap_.empty()) {
5094 TLOGI(WmsLogTag::DMS, "connect the first screen");
5095 res = AddAsFirstScreenLocked(newScreen, isUnique);
5096 } else {
5097 res = AddAsSuccedentScreenLocked(newScreen);
5098 }
5099 return res;
5100 }
5101
AddAsFirstScreenLocked(sptr<ScreenSession> newScreen,bool isUnique)5102 sptr<ScreenSessionGroup> ScreenSessionManager::AddAsFirstScreenLocked(sptr<ScreenSession> newScreen, bool isUnique)
5103 {
5104 ScreenId smsGroupScreenId(1);
5105 std::ostringstream buffer;
5106 buffer << "ScreenGroup_" << smsGroupScreenId;
5107 std::string name = buffer.str();
5108 // default ScreenCombination is mirror
5109 isExpandCombination_ = system::GetParameter("persist.display.expand.enabled", "0") == "1";
5110 sptr<ScreenSessionGroup> screenGroup;
5111 if (isExpandCombination_) {
5112 screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
5113 SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_EXPAND);
5114 } else if (isUnique) {
5115 screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
5116 SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_UNIQUE);
5117 } else {
5118 screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
5119 SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_MIRROR);
5120 }
5121 if (screenGroup == nullptr) {
5122 TLOGE(WmsLogTag::DMS, "new ScreenSessionGroup failed");
5123 screenIdManager_.DeleteScreenId(smsGroupScreenId);
5124 return nullptr;
5125 }
5126 screenGroup->groupSmsId_ = 1;
5127 Point point;
5128 if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none") {
5129 if (IsExtendMode()) {
5130 point = {newScreen->GetScreenProperty().GetStartX(), newScreen->GetScreenProperty().GetStartY()};
5131 }
5132 }
5133 if (!screenGroup->AddChild(newScreen, point, GetScreenSession(GetDefaultScreenId()),
5134 IsExtendMode() && g_isPcDevice)) {
5135 TLOGE(WmsLogTag::DMS, "fail to add screen to group. screen=%{public}" PRIu64"", newScreen->screenId_);
5136 screenIdManager_.DeleteScreenId(smsGroupScreenId);
5137 return nullptr;
5138 }
5139 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5140 auto iter = smsScreenGroupMap_.find(smsGroupScreenId);
5141 if (iter != smsScreenGroupMap_.end()) {
5142 TLOGE(WmsLogTag::DMS, "group screen existed. id=%{public}" PRIu64"", smsGroupScreenId);
5143 smsScreenGroupMap_.erase(iter);
5144 }
5145 smsScreenGroupMap_.insert(std::make_pair(smsGroupScreenId, screenGroup));
5146 screenGroup->mirrorScreenId_ = newScreen->screenId_;
5147 TLOGI(WmsLogTag::DMS, "connect new group screen, screenId: %{public}" PRIu64", screenGroupId: %{public}" PRIu64", "
5148 "combination:%{public}u", newScreen->screenId_, smsGroupScreenId,
5149 newScreen->GetScreenProperty().GetScreenType());
5150 return screenGroup;
5151 }
5152
AddAsSuccedentScreenLocked(sptr<ScreenSession> newScreen)5153 sptr<ScreenSessionGroup> ScreenSessionManager::AddAsSuccedentScreenLocked(sptr<ScreenSession> newScreen)
5154 {
5155 ScreenId defaultScreenId = GetDefaultScreenId();
5156 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5157 auto iter = screenSessionMap_.find(defaultScreenId);
5158 if (iter == screenSessionMap_.end()) {
5159 TLOGE(WmsLogTag::DMS, "defaultScreenId:%{public}" PRIu64" is not in screenSessionMap_.",
5160 defaultScreenId);
5161 return nullptr;
5162 }
5163 auto screen = iter->second;
5164 auto screenGroupIter = smsScreenGroupMap_.find(screen->groupSmsId_);
5165 if (screenGroupIter == smsScreenGroupMap_.end()) {
5166 TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64" is not in smsScreenGroupMap_.",
5167 screen->groupSmsId_);
5168 return nullptr;
5169 }
5170 auto screenGroup = screenGroupIter->second;
5171 Point point;
5172 if (screenGroup->combination_ == ScreenCombination::SCREEN_EXPAND) {
5173 point = {screen->GetActiveScreenMode()->width_, 0};
5174 }
5175 screenGroup->AddChild(newScreen, point, screen);
5176 return screenGroup;
5177 }
5178
RemoveFromGroupLocked(sptr<ScreenSession> screen)5179 sptr<ScreenSessionGroup> ScreenSessionManager::RemoveFromGroupLocked(sptr<ScreenSession> screen)
5180 {
5181 TLOGI(WmsLogTag::DMS, "start");
5182 auto groupSmsId = screen->groupSmsId_;
5183 sptr<ScreenSessionGroup> screenGroup = GetAbstractScreenGroup(groupSmsId);
5184 if (!screenGroup) {
5185 TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64"is not in smsScreenGroupMap_.",
5186 groupSmsId);
5187 return nullptr;
5188 }
5189 if (!RemoveChildFromGroup(screen, screenGroup)) {
5190 return nullptr;
5191 }
5192 return screenGroup;
5193 }
5194
RemoveChildFromGroup(sptr<ScreenSession> screen,sptr<ScreenSessionGroup> screenGroup)5195 bool ScreenSessionManager::RemoveChildFromGroup(sptr<ScreenSession> screen, sptr<ScreenSessionGroup> screenGroup)
5196 {
5197 bool res = screenGroup->RemoveChild(screen);
5198 auto transactionProxy = RSTransactionProxy::GetInstance();
5199 if (transactionProxy != nullptr) {
5200 transactionProxy->FlushImplicitTransaction();
5201 TLOGI(WmsLogTag::DMS, "remove child and call flush.");
5202 }
5203 if (!res) {
5204 TLOGE(WmsLogTag::DMS, "remove screen:%{public}" PRIu64" failed from screenGroup:%{public}" PRIu64".",
5205 screen->screenId_, screen->groupSmsId_);
5206 return false;
5207 }
5208 if (screenGroup->GetChildCount() == 0) {
5209 // Group removed, need to do something.
5210 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5211 smsScreenGroupMap_.erase(screenGroup->screenId_);
5212 screenSessionMap_.erase(screenGroup->screenId_);
5213 TLOGE(WmsLogTag::DMS, "screenSessionMap_ remove screen:%{public}" PRIu64, screenGroup->screenId_);
5214 }
5215 return true;
5216 }
5217
SetMirror(ScreenId screenId,std::vector<ScreenId> screens,DMRect mainScreenRegion)5218 DMError ScreenSessionManager::SetMirror(ScreenId screenId, std::vector<ScreenId> screens, DMRect mainScreenRegion)
5219 {
5220 TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64"", screenId);
5221 sptr<ScreenSession> screen = GetScreenSession(screenId);
5222 if (screen == nullptr || screen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
5223 TLOGE(WmsLogTag::DMS, "screen is nullptr, or screenCommbination is mirror.");
5224 return DMError::DM_ERROR_NULLPTR;
5225 }
5226 screen->groupSmsId_ = 1;
5227 auto group = GetAbstractScreenGroup(screen->groupSmsId_);
5228 if (group == nullptr) {
5229 group = AddToGroupLocked(screen);
5230 if (group == nullptr) {
5231 TLOGE(WmsLogTag::DMS, "group is nullptr");
5232 return DMError::DM_ERROR_NULLPTR;
5233 }
5234 NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
5235 }
5236 Point point;
5237 std::vector<Point> startPoints;
5238 startPoints.insert(startPoints.begin(), screens.size(), point);
5239 bool filterMirroredScreen =
5240 group->combination_ == ScreenCombination::SCREEN_MIRROR && group->mirrorScreenId_ == screen->screenId_;
5241 group->mirrorScreenId_ = screen->screenId_;
5242 ChangeScreenGroup(group, screens, startPoints, filterMirroredScreen, ScreenCombination::SCREEN_MIRROR,
5243 mainScreenRegion);
5244 TLOGI(WmsLogTag::DMS, "success");
5245 return DMError::DM_OK;
5246 }
5247
GetAbstractScreenGroup(ScreenId smsScreenId)5248 sptr<ScreenSessionGroup> ScreenSessionManager::GetAbstractScreenGroup(ScreenId smsScreenId)
5249 {
5250 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5251 auto iter = smsScreenGroupMap_.find(smsScreenId);
5252 if (iter == smsScreenGroupMap_.end()) {
5253 TLOGE(WmsLogTag::DMS, "did not find screen:%{public}" PRIu64"", smsScreenId);
5254 return nullptr;
5255 }
5256 return iter->second;
5257 }
5258
CheckScreenInScreenGroup(sptr<ScreenSession> screen) const5259 bool ScreenSessionManager::CheckScreenInScreenGroup(sptr<ScreenSession> screen) const
5260 {
5261 if (screen == nullptr) {
5262 TLOGE(WmsLogTag::DMS, "screen is nullptr");
5263 return false;
5264 }
5265 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5266 auto groupSmsId = screen->groupSmsId_;
5267 auto iter = smsScreenGroupMap_.find(groupSmsId);
5268 if (iter == smsScreenGroupMap_.end()) {
5269 TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64"is not in smsScreenGroupMap_.", groupSmsId);
5270 return false;
5271 }
5272 sptr<ScreenSessionGroup> screenGroup = iter->second;
5273 return screenGroup->HasChild(screen->screenId_);
5274 }
5275
ChangeScreenGroup(sptr<ScreenSessionGroup> group,const std::vector<ScreenId> & screens,const std::vector<Point> & startPoints,bool filterScreen,ScreenCombination combination,DMRect mainScreenRegion)5276 void ScreenSessionManager::ChangeScreenGroup(sptr<ScreenSessionGroup> group, const std::vector<ScreenId>& screens,
5277 const std::vector<Point>& startPoints, bool filterScreen, ScreenCombination combination, DMRect mainScreenRegion)
5278 {
5279 std::map<ScreenId, bool> removeChildResMap;
5280 std::vector<ScreenId> addScreens;
5281 std::vector<Point> addChildPos;
5282 for (uint64_t i = 0; i != screens.size(); i++) {
5283 ScreenId screenId = screens[i];
5284 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64"", screenId);
5285 auto screen = GetScreenSession(screenId);
5286 if (screen == nullptr) {
5287 TLOGE(WmsLogTag::DMS, "screen:%{public}" PRIu64" is nullptr", screenId);
5288 continue;
5289 }
5290 TLOGI(WmsLogTag::DMS, "Screen->groupSmsId_: %{public}" PRIu64"", screen->groupSmsId_);
5291 screen->groupSmsId_ = 1;
5292 if (filterScreen && screen->groupSmsId_ == group->screenId_ && group->HasChild(screen->screenId_)) {
5293 // screen already in group
5294 if (combination != ScreenCombination::SCREEN_MIRROR ||
5295 (screen->GetMirrorScreenRegion().second == mainScreenRegion &&
5296 screen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR)) {
5297 continue;
5298 }
5299 // mirror mode and mirror area change
5300 TLOGI(WmsLogTag::DMS, "Screen: %{public}" PRIu64
5301 ", apply new region, x:%{public}d y:%{public}d w:%{public}u h:%{public}u",
5302 screenId, mainScreenRegion.posX_, mainScreenRegion.posY_,
5303 mainScreenRegion.width_, mainScreenRegion.height_);
5304 }
5305 if (CheckScreenInScreenGroup(screen)) {
5306 NotifyDisplayDestroy(screenId);
5307 }
5308 auto originGroup = RemoveFromGroupLocked(screen);
5309 addChildPos.emplace_back(startPoints[i]);
5310 removeChildResMap[screenId] = originGroup != nullptr;
5311 addScreens.emplace_back(screenId);
5312 if (combination == ScreenCombination::SCREEN_MIRROR) {
5313 auto mirrorScreenId = group->mirrorScreenId_;
5314 ScreenId rsScreenId = SCREEN_ID_INVALID;
5315 if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
5316 TLOGE(WmsLogTag::DMS, "Screen: %{public}" PRIu64" convert to rs id failed", mirrorScreenId);
5317 } else {
5318 screen->SetMirrorScreenRegion(rsScreenId, mainScreenRegion);
5319 screen->SetIsPhysicalMirrorSwitch(false);
5320 TLOGI(WmsLogTag::DMS, "Screen: %{public}" PRIu64" mirror to %{public}"
5321 PRIu64" with region, x:%{public}d y:%{public}d w:%{public}u h:%{public}u",
5322 screenId, mirrorScreenId, mainScreenRegion.posX_, mainScreenRegion.posY_,
5323 mainScreenRegion.width_, mainScreenRegion.height_);
5324 }
5325 }
5326 }
5327 group->combination_ = combination;
5328 AddScreenToGroup(group, addScreens, addChildPos, removeChildResMap);
5329 }
5330
AddScreenToGroup(sptr<ScreenSessionGroup> group,const std::vector<ScreenId> & addScreens,const std::vector<Point> & addChildPos,std::map<ScreenId,bool> & removeChildResMap)5331 void ScreenSessionManager::AddScreenToGroup(sptr<ScreenSessionGroup> group,
5332 const std::vector<ScreenId>& addScreens, const std::vector<Point>& addChildPos,
5333 std::map<ScreenId, bool>& removeChildResMap)
5334 {
5335 std::vector<sptr<ScreenInfo>> addToGroup;
5336 std::vector<sptr<ScreenInfo>> removeFromGroup;
5337 std::vector<sptr<ScreenInfo>> changeGroup;
5338 for (uint64_t i = 0; i != addScreens.size(); i++) {
5339 ScreenId screenId = addScreens[i];
5340 sptr<ScreenSession> screen = GetScreenSession(screenId);
5341 if (screen == nullptr) {
5342 continue;
5343 }
5344 Point expandPoint = addChildPos[i];
5345 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64", Point: %{public}d, %{public}d",
5346 screen->screenId_, expandPoint.posX_, expandPoint.posY_);
5347 bool addChildRes = group->AddChild(screen, expandPoint, GetScreenSession(group->mirrorScreenId_));
5348 if (removeChildResMap[screenId] && addChildRes) {
5349 changeGroup.emplace_back(screen->ConvertToScreenInfo());
5350 TLOGD(WmsLogTag::DMS, "changeGroup");
5351 } else if (removeChildResMap[screenId]) {
5352 TLOGD(WmsLogTag::DMS, "removeChild");
5353 removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
5354 } else if (addChildRes) {
5355 TLOGD(WmsLogTag::DMS, "AddChild");
5356 addToGroup.emplace_back(screen->ConvertToScreenInfo());
5357 } else {
5358 TLOGD(WmsLogTag::DMS, "default, AddChild failed");
5359 }
5360 NotifyDisplayCreate(screen->ConvertToDisplayInfo());
5361 }
5362
5363 NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
5364 NotifyScreenGroupChanged(changeGroup, ScreenGroupChangeEvent::CHANGE_GROUP);
5365 NotifyScreenGroupChanged(addToGroup, ScreenGroupChangeEvent::ADD_TO_GROUP);
5366 }
5367
RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)5368 void ScreenSessionManager::RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)
5369 {
5370 TLOGW(WmsLogTag::DMS, "enter!");
5371 if (!SessionPermission::IsSystemCalling()) {
5372 TLOGE(WmsLogTag::DMS, "permission denied calling: %{public}s, pid: %{public}d",
5373 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5374 return;
5375 }
5376 if (screens.empty()) {
5377 return;
5378 }
5379 std::vector<sptr<ScreenInfo>> removeFromGroup;
5380 for (ScreenId screenId : screens) {
5381 auto screen = GetScreenSession(screenId);
5382 if (screen == nullptr || screen->GetScreenProperty().GetScreenType() != ScreenType::VIRTUAL) {
5383 continue;
5384 }
5385 auto originGroup = GetAbstractScreenGroup(screen->groupSmsId_);
5386 if (originGroup == nullptr) {
5387 continue;
5388 }
5389 if (!originGroup->HasChild(screenId)) {
5390 continue;
5391 }
5392 RemoveFromGroupLocked(screen);
5393 removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
5394 }
5395 NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
5396 }
5397
GetRSDisplayNodeByScreenId(ScreenId smsScreenId) const5398 const std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetRSDisplayNodeByScreenId(ScreenId smsScreenId) const
5399 {
5400 static std::shared_ptr<RSDisplayNode> notFound = nullptr;
5401 sptr<ScreenSession> screen = GetScreenSession(smsScreenId);
5402 if (screen == nullptr) {
5403 TLOGE(WmsLogTag::DMS, "screen == nullptr!");
5404 return notFound;
5405 }
5406 if (screen->GetDisplayNode() == nullptr) {
5407 TLOGE(WmsLogTag::DMS, "displayNode_ == nullptr!");
5408 return notFound;
5409 }
5410 TLOGI(WmsLogTag::DMS, "screen: %{public}" PRIu64", nodeId: %{public}" PRIu64" ",
5411 screen->screenId_, screen->GetDisplayNode()->GetId());
5412 return screen->GetDisplayNode();
5413 }
5414
GetDisplayNodeByDisplayId(DisplayId displayId)5415 std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetDisplayNodeByDisplayId(DisplayId displayId)
5416 {
5417 std::shared_ptr<RSDisplayNode> displayNode = nullptr;
5418 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5419 for (auto sessionIt : screenSessionMap_) {
5420 auto screenSession = sessionIt.second;
5421 if (screenSession == nullptr) {
5422 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
5423 continue;
5424 }
5425 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
5426 if (displayInfo == nullptr) {
5427 TLOGE(WmsLogTag::DMS, "displayInfo is nullptr!");
5428 continue;
5429 }
5430 if (displayId == displayInfo->GetDisplayId()) {
5431 if (sessionIt.first == SCREEN_ID_INVALID) {
5432 TLOGE(WmsLogTag::DMS, "screenId is invalid!");
5433 continue;
5434 }
5435 displayNode = screenSession->GetDisplayNode();
5436 break;
5437 }
5438 }
5439 return displayNode;
5440 }
5441
IsFakeDisplayExist()5442 bool ScreenSessionManager::IsFakeDisplayExist()
5443 {
5444 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
5445 SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
5446 return true;
5447 }
5448 return false;
5449 }
5450
GetScreenSnapshot(DisplayId displayId,bool isUseDma)5451 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetScreenSnapshot(DisplayId displayId, bool isUseDma)
5452 {
5453 DisplayId realDisplayId = displayId;
5454 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && displayId == DISPLAY_ID_FAKE) {
5455 if (!SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
5456 TLOGE(WmsLogTag::DMS, "fake display is not exist!");
5457 return nullptr;
5458 }
5459 realDisplayId = 0;
5460 }
5461 std::shared_ptr<RSDisplayNode> displayNode = GetDisplayNodeByDisplayId(realDisplayId);
5462 if (displayNode == nullptr) {
5463 TLOGE(WmsLogTag::DMS, "displayNode is null!");
5464 return nullptr;
5465 }
5466 std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
5467 RSSurfaceCaptureConfig config;
5468 config.useDma = isUseDma;
5469 TLOGW(WmsLogTag::DMS, "take surface capture with dma=%{public}d", isUseDma);
5470 #ifdef FOLD_ABILITY_ENABLE
5471 if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
5472 config.mainScreenRect = foldScreenController_->GetScreenSnapshotRect();
5473 }
5474 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
5475 SuperFoldPolicy::GetInstance().IsNeedSetSnapshotRect(displayId)) {
5476 config.mainScreenRect = SuperFoldPolicy::GetInstance().GetSnapshotRect(displayId);
5477 }
5478 #endif
5479 bool ret = rsInterface_.TakeSurfaceCapture(displayNode, callback, config);
5480 if (!ret) {
5481 TLOGE(WmsLogTag::DMS, "TakeSurfaceCapture failed");
5482 return nullptr;
5483 }
5484 std::shared_ptr<Media::PixelMap> screenshot = callback->GetResult(2000); // wait for <= 2000ms
5485 if (screenshot == nullptr) {
5486 TLOGE(WmsLogTag::DMS, "Failed to get pixelmap from RS, return nullptr!");
5487 } else {
5488 TLOGD(WmsLogTag::DMS, "Sucess to get pixelmap from RS!");
5489 }
5490 // notify dm listener
5491 sptr<ScreenshotInfo> snapshotInfo = new ScreenshotInfo();
5492 snapshotInfo->SetTrigger(SysCapUtil::GetClientName());
5493 snapshotInfo->SetDisplayId(displayId);
5494 OnScreenshot(snapshotInfo);
5495 return screenshot;
5496 }
5497
GetDisplaySnapshot(DisplayId displayId,DmErrorCode * errorCode,bool isUseDma)5498 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetDisplaySnapshot(DisplayId displayId,
5499 DmErrorCode* errorCode, bool isUseDma)
5500 {
5501 TLOGD(WmsLogTag::DMS, "enter!");
5502 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall() && errorCode) {
5503 *errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
5504 return nullptr;
5505 }
5506 if (system::GetBoolParameter("persist.edm.disallow_screenshot", false) && errorCode) {
5507 TLOGI(WmsLogTag::DMS, "snapshot disabled by edm!");
5508 *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
5509 return nullptr;
5510 }
5511 if (displayId == DISPLAY_ID_FAKE && !IsFakeDisplayExist() && errorCode) {
5512 *errorCode = DmErrorCode::DM_ERROR_INVALID_SCREEN;
5513 TLOGE(WmsLogTag::DMS, "fake display not exist!");
5514 return nullptr;
5515 }
5516 if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
5517 SessionPermission::IsShellCall()) {
5518 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplaySnapshot(%" PRIu64")", displayId);
5519 auto res = GetScreenSnapshot(displayId, isUseDma);
5520 if (res != nullptr) {
5521 NotifyScreenshot(displayId);
5522 if (SessionPermission::IsBetaVersion()) {
5523 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
5524 }
5525 }
5526 isScreenShot_ = true;
5527 NotifyCaptureStatusChanged();
5528 return res;
5529 } else if (errorCode) {
5530 *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
5531 }
5532 return nullptr;
5533 }
5534
GetDisplaySnapshotWithOption(const CaptureOption & option,DmErrorCode * errorCode)5535 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetDisplaySnapshotWithOption(const CaptureOption& option,
5536 DmErrorCode* errorCode)
5537 {
5538 TLOGD(WmsLogTag::DMS, "enter!");
5539 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall() && errorCode) {
5540 *errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
5541 return nullptr;
5542 }
5543 if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
5544 TLOGI(WmsLogTag::DMS, "snapshot was disabled by edm!");
5545 return nullptr;
5546 }
5547 if (option.displayId_ == DISPLAY_ID_FAKE && !IsFakeDisplayExist() && errorCode) {
5548 TLOGE(WmsLogTag::DMS, "fake display not exist!");
5549 *errorCode = DmErrorCode::DM_ERROR_INVALID_SCREEN;
5550 return nullptr;
5551 }
5552 if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
5553 SessionPermission::IsShellCall()) {
5554 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplaySnapshot(%" PRIu64")", option.displayId_);
5555 auto res = GetScreenSnapshot(option.displayId_, true);
5556 if (res != nullptr) {
5557 if (SessionPermission::IsBetaVersion()) {
5558 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
5559 }
5560 TLOGI(WmsLogTag::DMS, "isNeedNotify_:%{public}d", option.isNeedNotify_);
5561 if (option.isNeedNotify_) {
5562 isScreenShot_ = true;
5563 NotifyScreenshot(option.displayId_);
5564 NotifyCaptureStatusChanged();
5565 }
5566 }
5567 return res;
5568 } else if (errorCode) {
5569 *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
5570 }
5571 return nullptr;
5572 }
5573
GetSnapshotByPicker(Media::Rect & rect,DmErrorCode * errorCode)5574 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetSnapshotByPicker(Media::Rect &rect, DmErrorCode* errorCode)
5575 {
5576 TLOGD(WmsLogTag::DMS, "ENTER!");
5577 *errorCode = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
5578 std::lock_guard<std::mutex> lock(snapBypickerMutex_);
5579
5580 if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
5581 *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
5582 TLOGI(WmsLogTag::DMS, "snapshot was disabled by edm!");
5583 return nullptr;
5584 }
5585 ScreenId screenId = SCREEN_ID_INVALID;
5586 // get snapshot area frome Screenshot extension
5587 if (!GetSnapshotArea(rect, errorCode, screenId)) {
5588 return nullptr;
5589 }
5590 auto screenSession = GetScreenSession(screenId);
5591 if (screenSession == nullptr) {
5592 TLOGE(WmsLogTag::DMS, "can not get screen session");
5593 return nullptr;
5594 }
5595 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
5596 if (displayInfo == nullptr) {
5597 TLOGE(WmsLogTag::DMS, "can not get default display");
5598 return nullptr;
5599 }
5600 DisplayId displayId = displayInfo->GetDisplayId();
5601 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSnapshotByPicker(%" PRIu64")", displayId);
5602 auto pixelMap = GetScreenSnapshot(displayId, false);
5603 if (pixelMap != nullptr && SessionPermission::IsBetaVersion()) {
5604 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
5605 }
5606 isScreenShot_ = true;
5607 NotifyCaptureStatusChanged();
5608 *errorCode = DmErrorCode::DM_OK;
5609 return pixelMap;
5610 }
5611
GetSnapshotArea(Media::Rect & rect,DmErrorCode * errorCode,ScreenId & screenId)5612 bool ScreenSessionManager::GetSnapshotArea(Media::Rect &rect, DmErrorCode* errorCode, ScreenId &screenId)
5613 {
5614 ConfigureScreenSnapshotParams();
5615 if (ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerConnectExtension()) {
5616 int32_t ret = ScreenSnapshotPickerConnection::GetInstance().GetScreenSnapshotInfo(rect, screenId);
5617 if (ret != 0) {
5618 TLOGE(WmsLogTag::DMS, "GetScreenSnapshotInfo failed");
5619 ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerDisconnectExtension();
5620 if (ret == RES_FAILURE_FOR_PRIVACY_WINDOW) {
5621 *errorCode = DmErrorCode::DM_ERROR_INVALID_CALLING;
5622 } else {
5623 *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
5624 }
5625 return false;
5626 }
5627 ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerDisconnectExtension();
5628 } else {
5629 *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
5630 TLOGE(WmsLogTag::DMS, "SnapshotPickerConnectExtension failed");
5631 return false;
5632 }
5633 return true;
5634 }
5635
OnRemoteDied(const sptr<IRemoteObject> & agent)5636 bool ScreenSessionManager::OnRemoteDied(const sptr<IRemoteObject>& agent)
5637 {
5638 if (agent == nullptr) {
5639 return false;
5640 }
5641 auto agentIter = screenAgentMap_.find(agent);
5642 if (agentIter != screenAgentMap_.end()) {
5643 while (screenAgentMap_[agent].size() > 0) {
5644 auto diedId = screenAgentMap_[agent][0];
5645 TLOGI(WmsLogTag::DMS, "destroy screenId in OnRemoteDied: %{public}" PRIu64"", diedId);
5646 DMError res = DestroyVirtualScreen(diedId);
5647 if (res != DMError::DM_OK) {
5648 TLOGE(WmsLogTag::DMS, "destroy failed in OnRemoteDied: %{public}" PRIu64"", diedId);
5649 }
5650 }
5651 screenAgentMap_.erase(agent);
5652 }
5653 return true;
5654 }
5655
GetAllValidScreenIds(const std::vector<ScreenId> & screenIds) const5656 std::vector<ScreenId> ScreenSessionManager::GetAllValidScreenIds(const std::vector<ScreenId>& screenIds) const
5657 {
5658 std::vector<ScreenId> validScreenIds;
5659 for (ScreenId screenId : screenIds) {
5660 auto screenIdIter = std::find(validScreenIds.begin(), validScreenIds.end(), screenId);
5661 if (screenIdIter != validScreenIds.end()) {
5662 continue;
5663 }
5664 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5665 auto iter = screenSessionMap_.find(screenId);
5666 if (iter != screenSessionMap_.end() && iter->second != nullptr &&
5667 iter->second->GetScreenProperty().GetScreenType() != ScreenType::UNDEFINED) {
5668 validScreenIds.emplace_back(screenId);
5669 }
5670 }
5671 return validScreenIds;
5672 }
5673
GetScreenGroupInfoById(ScreenId screenId)5674 sptr<ScreenGroupInfo> ScreenSessionManager::GetScreenGroupInfoById(ScreenId screenId)
5675 {
5676 if (!SessionPermission::IsSystemCalling()) {
5677 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5678 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5679 return nullptr;
5680 }
5681 auto screenSessionGroup = GetAbstractScreenGroup(screenId);
5682 if (screenSessionGroup == nullptr) {
5683 TLOGE(WmsLogTag::DMS, "cannot find screenGroupInfo: %{public}" PRIu64"", screenId);
5684 return nullptr;
5685 }
5686 return screenSessionGroup->ConvertToScreenGroupInfo();
5687 }
5688
NotifyScreenConnected(sptr<ScreenInfo> screenInfo)5689 void ScreenSessionManager::NotifyScreenConnected(sptr<ScreenInfo> screenInfo)
5690 {
5691 if (screenInfo == nullptr) {
5692 TLOGE(WmsLogTag::DMS, "error, screenInfo is nullptr.");
5693 return;
5694 }
5695 auto task = [=] {
5696 TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64"", screenInfo->GetScreenId());
5697 OnScreenConnect(screenInfo);
5698 };
5699 taskScheduler_->PostAsyncTask(task, "NotifyScreenConnected");
5700 }
5701
NotifyScreenDisconnected(ScreenId screenId)5702 void ScreenSessionManager::NotifyScreenDisconnected(ScreenId screenId)
5703 {
5704 auto task = [=] {
5705 TLOGNI(WmsLogTag::DMS, "notify screenId:%{public}" PRIu64"", screenId);
5706 OnScreenDisconnect(screenId);
5707 };
5708 taskScheduler_->PostAsyncTask(task, "NotifyScreenDisconnected");
5709 }
5710
NotifyDisplayCreate(sptr<DisplayInfo> displayInfo)5711 void ScreenSessionManager::NotifyDisplayCreate(sptr<DisplayInfo> displayInfo)
5712 {
5713 if (displayInfo == nullptr) {
5714 return;
5715 }
5716 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
5717 TLOGI(WmsLogTag::DMS, "start, agent size: %{public}u", static_cast<uint32_t>(agents.size()));
5718 if (agents.empty()) {
5719 return;
5720 }
5721 for (auto& agent : agents) {
5722 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
5723 if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
5724 agent->OnDisplayCreate(displayInfo);
5725 }
5726 }
5727 }
5728
NotifyDisplayDestroy(DisplayId displayId)5729 void ScreenSessionManager::NotifyDisplayDestroy(DisplayId displayId)
5730 {
5731 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
5732 TLOGI(WmsLogTag::DMS, "agent size: %{public}u", static_cast<uint32_t>(agents.size()));
5733 if (agents.empty()) {
5734 return;
5735 }
5736 for (auto& agent : agents) {
5737 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
5738 if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
5739 agent->OnDisplayDestroy(displayId);
5740 }
5741 }
5742 }
5743
NotifyScreenGroupChanged(const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent event)5744 void ScreenSessionManager::NotifyScreenGroupChanged(
5745 const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent event)
5746 {
5747 if (screenInfo == nullptr) {
5748 TLOGE(WmsLogTag::DMS, "screenInfo is nullptr.");
5749 return;
5750 }
5751 std::string trigger = SysCapUtil::GetClientName();
5752 auto task = [=] {
5753 TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", trigger:[%{public}s]",
5754 screenInfo->GetScreenId(), trigger.c_str());
5755 OnScreenGroupChange(trigger, screenInfo, event);
5756 };
5757 taskScheduler_->PostAsyncTask(task, "NotifyScreenGroupChanged:PID");
5758 }
5759
NotifyScreenGroupChanged(const std::vector<sptr<ScreenInfo>> & screenInfo,ScreenGroupChangeEvent event)5760 void ScreenSessionManager::NotifyScreenGroupChanged(
5761 const std::vector<sptr<ScreenInfo>>& screenInfo, ScreenGroupChangeEvent event)
5762 {
5763 if (screenInfo.empty()) {
5764 return;
5765 }
5766 std::string trigger = SysCapUtil::GetClientName();
5767 auto task = [=] {
5768 TLOGNI(WmsLogTag::DMS, "trigger:[%{public}s]", trigger.c_str());
5769 OnScreenGroupChange(trigger, screenInfo, event);
5770 };
5771 taskScheduler_->PostAsyncTask(task, "NotifyScreenGroupChanged");
5772 }
5773
NotifyPrivateSessionStateChanged(bool hasPrivate)5774 void ScreenSessionManager::NotifyPrivateSessionStateChanged(bool hasPrivate)
5775 {
5776 if (hasPrivate == screenPrivacyStates) {
5777 TLOGD(WmsLogTag::DMS, "screen session state is not changed, return");
5778 return;
5779 }
5780 TLOGI(WmsLogTag::DMS, "PrivateSession status : %{public}u", hasPrivate);
5781 screenPrivacyStates = hasPrivate;
5782 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::PRIVATE_WINDOW_LISTENER);
5783 if (agents.empty()) {
5784 return;
5785 }
5786 for (auto& agent : agents) {
5787 agent->NotifyPrivateWindowStateChanged(hasPrivate);
5788 }
5789 }
5790
SetScreenPrivacyState(bool hasPrivate)5791 void ScreenSessionManager::SetScreenPrivacyState(bool hasPrivate)
5792 {
5793 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5794 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5795 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5796 return;
5797 }
5798 TLOGI(WmsLogTag::DMS, "enter, hasPrivate: %{public}d", hasPrivate);
5799 ScreenId id = GetDefaultScreenId();
5800 auto screenSession = GetScreenSession(id);
5801 if (screenSession == nullptr) {
5802 TLOGE(WmsLogTag::DMS, "can not get default screen now");
5803 return;
5804 }
5805 screenSession->SetPrivateSessionForeground(hasPrivate);
5806 NotifyPrivateSessionStateChanged(hasPrivate);
5807 }
5808
SetPrivacyStateByDisplayId(DisplayId id,bool hasPrivate)5809 void ScreenSessionManager::SetPrivacyStateByDisplayId(DisplayId id, bool hasPrivate)
5810 {
5811 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5812 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5813 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5814 return;
5815 }
5816 TLOGI(WmsLogTag::DMS, "enter, hasPrivate: %{public}d", hasPrivate);
5817 std::vector<ScreenId> screenIds = GetAllScreenIds();
5818 auto iter = std::find(screenIds.begin(), screenIds.end(), id);
5819 if (iter == screenIds.end()) {
5820 TLOGE(WmsLogTag::DMS, "invalid displayId");
5821 return;
5822 }
5823 auto screenSession = GetScreenSession(id);
5824 if (screenSession == nullptr) {
5825 TLOGE(WmsLogTag::DMS, "can not get id: %{public}" PRIu64" screen now", id);
5826 return;
5827 }
5828 screenSession->SetPrivateSessionForeground(hasPrivate);
5829 NotifyPrivateSessionStateChanged(hasPrivate);
5830 }
5831
SetScreenPrivacyWindowList(DisplayId id,std::vector<std::string> privacyWindowList)5832 void ScreenSessionManager::SetScreenPrivacyWindowList(DisplayId id, std::vector<std::string> privacyWindowList)
5833 {
5834 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5835 TLOGE(WmsLogTag::DMS, "Permmission Denied! calling: %{public}s, pid: %{public}d",
5836 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5837 return;
5838 }
5839 TLOGW(WmsLogTag::DMS, "enter");
5840 std::vector<ScreenId> screenIds = GetAllScreenIds();
5841 auto iter = std::find(screenIds.begin(), screenIds.end(), id);
5842 if (iter == screenIds.end()) {
5843 TLOGE(WmsLogTag::DMS, "invalid displayId");
5844 return;
5845 }
5846 auto screenSession = GetScreenSession(id);
5847 if (screenSession == nullptr) {
5848 TLOGE(WmsLogTag::DMS, "can not get id: %{public}" PRIu64" screen now", id);
5849 return;
5850 }
5851 NotifyPrivateWindowListChanged(id, privacyWindowList);
5852 }
5853
NotifyPrivateWindowListChanged(DisplayId id,std::vector<std::string> privacyWindowList)5854 void ScreenSessionManager::NotifyPrivateWindowListChanged(DisplayId id, std::vector<std::string> privacyWindowList)
5855 {
5856 TLOGI(WmsLogTag::DMS, "Notify displayid: %{public}" PRIu64"", id);
5857 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::PRIVATE_WINDOW_LIST_LISTENER);
5858 if (agents.empty()) {
5859 return;
5860 }
5861 for (auto& agent : agents) {
5862 agent->NotifyPrivateStateWindowListChanged(id, privacyWindowList);
5863 }
5864 }
5865
HasPrivateWindow(DisplayId id,bool & hasPrivateWindow)5866 DMError ScreenSessionManager::HasPrivateWindow(DisplayId id, bool& hasPrivateWindow)
5867 {
5868 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5869 TLOGE(WmsLogTag::DMS, "Permmision Denied! calling: %{public}s, pid: %{public}d",
5870 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5871 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5872 }
5873 if (id == DISPLAY_ID_FAKE) {
5874 auto displayInfo = GetDefaultDisplayInfo();
5875 if (displayInfo) {
5876 id = displayInfo->GetDisplayId();
5877 TLOGI(WmsLogTag::DMS, "change displayId: %{public}" PRIu64" to displayId: %{public}" PRIu64,
5878 DISPLAY_ID_FAKE, id);
5879 }
5880 }
5881 std::vector<ScreenId> screenIds = GetAllScreenIds();
5882 auto iter = std::find(screenIds.begin(), screenIds.end(), id);
5883 if (iter == screenIds.end()) {
5884 TLOGE(WmsLogTag::DMS, "invalid displayId");
5885 return DMError::DM_ERROR_INVALID_PARAM;
5886 }
5887 auto screenSession = GetScreenSession(id);
5888 if (screenSession == nullptr) {
5889 return DMError::DM_ERROR_NULLPTR;
5890 }
5891 hasPrivateWindow = screenSession->HasPrivateSessionForeground();
5892 TLOGI(WmsLogTag::DMS, "id: %{public}" PRIu64" has private window: %{public}u",
5893 id, static_cast<uint32_t>(hasPrivateWindow));
5894 return DMError::DM_OK;
5895 }
5896
OnScreenGroupChange(const std::string & trigger,const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent groupEvent)5897 void ScreenSessionManager::OnScreenGroupChange(const std::string& trigger,
5898 const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent groupEvent)
5899 {
5900 if (screenInfo == nullptr) {
5901 return;
5902 }
5903 std::vector<sptr<ScreenInfo>> screenInfos;
5904 screenInfos.push_back(screenInfo);
5905 OnScreenGroupChange(trigger, screenInfos, groupEvent);
5906 }
5907
OnScreenGroupChange(const std::string & trigger,const std::vector<sptr<ScreenInfo>> & screenInfos,ScreenGroupChangeEvent groupEvent)5908 void ScreenSessionManager::OnScreenGroupChange(const std::string& trigger,
5909 const std::vector<sptr<ScreenInfo>>& screenInfos, ScreenGroupChangeEvent groupEvent)
5910 {
5911 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
5912 std::vector<sptr<ScreenInfo>> infos;
5913 for (auto& screenInfo : screenInfos) {
5914 if (screenInfo != nullptr) {
5915 infos.emplace_back(screenInfo);
5916 }
5917 }
5918 if (agents.empty() || infos.empty()) {
5919 return;
5920 }
5921 for (auto& agent : agents) {
5922 agent->OnScreenGroupChange(trigger, infos, groupEvent);
5923 }
5924 }
5925
OnScreenConnect(const sptr<ScreenInfo> screenInfo)5926 void ScreenSessionManager::OnScreenConnect(const sptr<ScreenInfo> screenInfo)
5927 {
5928 if (screenInfo == nullptr) {
5929 TLOGE(WmsLogTag::DMS, "screenInfo nullptr");
5930 return;
5931 }
5932 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
5933 if (agents.empty()) {
5934 TLOGI(WmsLogTag::DMS, "agents empty");
5935 return;
5936 }
5937 TLOGI(WmsLogTag::DMS, "start");
5938 for (auto& agent : agents) {
5939 agent->OnScreenConnect(screenInfo);
5940 }
5941 NotifyScreenModeChange();
5942 }
5943
OnScreenDisconnect(ScreenId screenId)5944 void ScreenSessionManager::OnScreenDisconnect(ScreenId screenId)
5945 {
5946 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
5947 if (agents.empty()) {
5948 TLOGI(WmsLogTag::DMS, "agents empty");
5949 return;
5950 }
5951 TLOGI(WmsLogTag::DMS, "start");
5952 for (auto& agent : agents) {
5953 agent->OnScreenDisconnect(screenId);
5954 }
5955 NotifyScreenModeChange(screenId);
5956 }
5957
OnScreenshot(sptr<ScreenshotInfo> info)5958 void ScreenSessionManager::OnScreenshot(sptr<ScreenshotInfo> info)
5959 {
5960 if (info == nullptr) {
5961 TLOGE(WmsLogTag::DMS, "info is null");
5962 return;
5963 }
5964 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREENSHOT_EVENT_LISTENER);
5965 if (agents.empty()) {
5966 TLOGD(WmsLogTag::DMS, "agents empty");
5967 return;
5968 }
5969 TLOGI(WmsLogTag::DMS, "start");
5970 for (auto& agent : agents) {
5971 agent->OnScreenshot(info);
5972 }
5973 }
5974
GetCutoutInfo(DisplayId displayId)5975 sptr<CutoutInfo> ScreenSessionManager::GetCutoutInfo(DisplayId displayId)
5976 {
5977 DmsXcollie dmsXcollie("DMS:GetCutoutInfo", XCOLLIE_TIMEOUT_10S);
5978 return screenCutoutController_ ? screenCutoutController_->GetScreenCutoutInfo(displayId) : nullptr;
5979 }
5980
HasImmersiveWindow(ScreenId screenId,bool & immersive)5981 DMError ScreenSessionManager::HasImmersiveWindow(ScreenId screenId, bool& immersive)
5982 {
5983 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5984 TLOGE(WmsLogTag::DMS, "permission denied!");
5985 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5986 }
5987 if (!clientProxy_) {
5988 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
5989 return DMError::DM_ERROR_NULLPTR;
5990 }
5991 clientProxy_->OnImmersiveStateChanged(screenId, immersive);
5992 return DMError::DM_OK;
5993 }
5994
SetDisplayBoundary(const sptr<ScreenSession> screenSession)5995 void ScreenSessionManager::SetDisplayBoundary(const sptr<ScreenSession> screenSession)
5996 {
5997 if (screenSession && screenCutoutController_) {
5998 RectF rect =
5999 screenCutoutController_->CalculateCurvedCompression(screenSession->GetScreenProperty());
6000 if (!rect.IsEmpty()) {
6001 screenSession->SetDisplayBoundary(rect, screenCutoutController_->GetOffsetY());
6002 }
6003 } else {
6004 TLOGW(WmsLogTag::DMS, "screenSession or screenCutoutController_ is null");
6005 }
6006 }
6007
TransferTypeToString(ScreenType type) const6008 std::string ScreenSessionManager::TransferTypeToString(ScreenType type) const
6009 {
6010 std::string screenType;
6011 switch (type) {
6012 case ScreenType::REAL:
6013 screenType = "REAL";
6014 break;
6015 case ScreenType::VIRTUAL:
6016 screenType = "VIRTUAL";
6017 break;
6018 default:
6019 screenType = "UNDEFINED";
6020 break;
6021 }
6022 return screenType;
6023 }
6024
TransferPropertyChangeTypeToString(ScreenPropertyChangeType type) const6025 std::string ScreenSessionManager::TransferPropertyChangeTypeToString(ScreenPropertyChangeType type) const
6026 {
6027 std::string screenType;
6028 switch (type) {
6029 case ScreenPropertyChangeType::UNSPECIFIED:
6030 screenType = "UNSPECIFIED";
6031 break;
6032 case ScreenPropertyChangeType::ROTATION_BEGIN:
6033 screenType = "ROTATION_BEGIN";
6034 break;
6035 case ScreenPropertyChangeType::ROTATION_END:
6036 screenType = "ROTATION_END";
6037 break;
6038 case ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY:
6039 screenType = "ROTATION_UPDATE_PROPERTY_ONLY";
6040 break;
6041 case ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY:
6042 screenType = "ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY";
6043 break;
6044 default:
6045 screenType = "UNDEFINED";
6046 break;
6047 }
6048 return screenType;
6049 }
6050
DumpAllScreensInfo(std::string & dumpInfo)6051 void ScreenSessionManager::DumpAllScreensInfo(std::string& dumpInfo)
6052 {
6053 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
6054 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
6055 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6056 return;
6057 }
6058 std::ostringstream oss;
6059 oss << "--------------------------------------Free Screen"
6060 << "--------------------------------------"
6061 << std::endl;
6062 oss << "ScreenName Type IsGroup DmsId RsId ActiveIdx VPR Rotation Orientation "
6063 << "RequestOrientation NodeId "
6064 << std::endl;
6065 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6066 for (auto sessionIt : screenSessionMap_) {
6067 auto screenSession = sessionIt.second;
6068 if (screenSession == nullptr) {
6069 continue;
6070 }
6071 sptr<ScreenInfo> screenInfo = screenSession->ConvertToScreenInfo();
6072 if (screenInfo == nullptr) {
6073 continue;
6074 }
6075 std::string screenType = TransferTypeToString(screenInfo->GetType());
6076 NodeId nodeId = (screenSession->GetDisplayNode() == nullptr) ?
6077 SCREEN_ID_INVALID : screenSession->GetDisplayNode()->GetId();
6078 oss << std::left << std::setw(21) << screenInfo->GetName() // 21 is width
6079 << std::left << std::setw(9) << screenType // 9 is width
6080 << std::left << std::setw(8) << (screenSession->isScreenGroup_ ? "true" : "false") // 8 is width
6081 << std::left << std::setw(6) << screenSession->screenId_ // 6 is width
6082 << std::left << std::setw(21) << screenSession->rsId_ // 21 is width
6083 << std::left << std::setw(10) << screenSession->activeIdx_ // 10 is width
6084 << std::left << std::setw(4) << screenInfo->GetVirtualPixelRatio() // 4 is width
6085 << std::left << std::setw(9) << static_cast<uint32_t>(screenInfo->GetRotation()) // 9 is width
6086 << std::left << std::setw(12) << static_cast<uint32_t>(screenInfo->GetOrientation()) // 12 is width
6087 << std::left << std::setw(19) // 19 is width
6088 << static_cast<uint32_t>(screenSession->GetScreenRequestedOrientation())
6089 << std::left << std::setw(21) << nodeId // 21 is width
6090 << std::endl;
6091 }
6092 oss << "total screen num: " << screenSessionMap_.size() << std::endl;
6093 dumpInfo.append(oss.str());
6094 }
6095
DumpSpecialScreenInfo(ScreenId id,std::string & dumpInfo)6096 void ScreenSessionManager::DumpSpecialScreenInfo(ScreenId id, std::string& dumpInfo)
6097 {
6098 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
6099 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
6100 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6101 return;
6102 }
6103 std::ostringstream oss;
6104 sptr<ScreenSession> session = GetScreenSession(id);
6105 if (!session) {
6106 TLOGE(WmsLogTag::DMS, "Get screen session failed.");
6107 oss << "This screen id is invalid.";
6108 dumpInfo.append(oss.str());
6109 return;
6110 }
6111 sptr<ScreenInfo> screenInfo = GetScreenInfoById(id);
6112 if (screenInfo == nullptr) {
6113 return;
6114 }
6115 std::string screenType = TransferTypeToString(screenInfo->GetType());
6116 NodeId nodeId = (session->GetDisplayNode() == nullptr) ?
6117 SCREEN_ID_INVALID : session->GetDisplayNode()->GetId();
6118 oss << "ScreenName: " << screenInfo->GetName() << std::endl;
6119 oss << "Type: " << screenType << std::endl;
6120 oss << "IsGroup: " << (session->isScreenGroup_ ? "true" : "false") << std::endl;
6121 oss << "DmsId: " << id << std::endl;
6122 oss << "RsId: " << session->rsId_ << std::endl;
6123 oss << "ActiveIdx: " << session->activeIdx_ << std::endl;
6124 oss << "VPR: " << screenInfo->GetVirtualPixelRatio() << std::endl;
6125 oss << "Rotation: " << static_cast<uint32_t>(screenInfo->GetRotation()) << std::endl;
6126 oss << "Orientation: " << static_cast<uint32_t>(screenInfo->GetOrientation()) << std::endl;
6127 oss << "RequestOrientation: " << static_cast<uint32_t>(session->GetScreenRequestedOrientation()) << std::endl;
6128 oss << "NodeId: " << nodeId << std::endl;
6129 dumpInfo.append(oss.str());
6130 }
6131
6132 // --- Fold Screen ---
GetPhyScreenProperty(ScreenId screenId)6133 ScreenProperty ScreenSessionManager::GetPhyScreenProperty(ScreenId screenId)
6134 {
6135 std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
6136 ScreenProperty property;
6137 auto iter = phyScreenPropMap_.find(screenId);
6138 if (iter == phyScreenPropMap_.end()) {
6139 TLOGI(WmsLogTag::DMS, "Error found physic screen config with id: %{public}" PRIu64, screenId);
6140 return property;
6141 }
6142 return iter->second;
6143 }
6144
UpdateCameraBackSelfie(bool isCameraBackSelfie)6145 void ScreenSessionManager::UpdateCameraBackSelfie(bool isCameraBackSelfie)
6146 {
6147 if (isCameraBackSelfie_ == isCameraBackSelfie) {
6148 return;
6149 }
6150 isCameraBackSelfie_ = isCameraBackSelfie;
6151
6152 auto screenSession = GetDefaultScreenSession();
6153 if (!screenSession) {
6154 TLOGW(WmsLogTag::DMS, "screenSession is null, notify camera back selfie failed");
6155 return;
6156 }
6157 screenSession->HandleCameraBackSelfieChange(isCameraBackSelfie);
6158
6159 if (isCameraBackSelfie) {
6160 TLOGI(WmsLogTag::DMS, "isBackSelfie, SetScreenCorrection MAIN to 270");
6161 rsInterface_.SetScreenCorrection(SCREEN_ID_MAIN, static_cast<ScreenRotation>(ROTATION_270));
6162 } else {
6163 TLOGI(WmsLogTag::DMS, "exit BackSelfie, SetScreenCorrection MAIN to 90");
6164 SetScreenCorrection();
6165 }
6166 }
6167
SetFoldDisplayMode(const FoldDisplayMode displayMode)6168 void ScreenSessionManager::SetFoldDisplayMode(const FoldDisplayMode displayMode)
6169 {
6170 SetFoldDisplayModeInner(displayMode);
6171 }
6172
SetFoldDisplayModeInner(const FoldDisplayMode displayMode,std::string reason)6173 DMError ScreenSessionManager::SetFoldDisplayModeInner(const FoldDisplayMode displayMode, std::string reason)
6174 {
6175 #ifdef FOLD_ABILITY_ENABLE
6176 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6177 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d, reason: %{public}s",
6178 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid(), reason.c_str());
6179 return DMError::DM_ERROR_NOT_SYSTEM_APP;
6180 }
6181 if (!g_foldScreenFlag) {
6182 return DMError::DM_ERROR_INVALID_MODE_ID;
6183 }
6184 if (foldScreenController_ == nullptr) {
6185 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6186 return DMError::DM_ERROR_INVALID_MODE_ID;
6187 }
6188 if (!SessionPermission::IsSystemCalling()) {
6189 TLOGE(WmsLogTag::DMS, "permission denied!");
6190 return DMError::DM_ERROR_NOT_SYSTEM_APP;
6191 }
6192 TLOGI(WmsLogTag::DMS, "calling clientName: %{public}s, calling pid: %{public}d, setmode: %{public}d",
6193 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid(), displayMode);
6194 if (foldScreenController_->GetTentMode() &&
6195 (displayMode == FoldDisplayMode::FULL || displayMode == FoldDisplayMode::COORDINATION)) {
6196 TLOGW(WmsLogTag::DMS, "in TentMode, SetFoldDisplayMode to %{public}d failed", displayMode);
6197 return DMError::DM_ERROR_INVALID_MODE_ID;
6198 } else if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() &&
6199 IsScreenCasting() && displayMode == FoldDisplayMode::COORDINATION) {
6200 TLOGW(WmsLogTag::DMS, "is phone casting, SetFoldDisplayMode to %{public}d is not allowed", displayMode);
6201 return DMError::DM_ERROR_INVALID_MODE_ID;
6202 }
6203 if (reason.compare("backSelfie") == 0) {
6204 UpdateCameraBackSelfie(true);
6205 }
6206 foldScreenController_->SetDisplayMode(displayMode);
6207 NotifyClientProxyUpdateFoldDisplayMode(displayMode);
6208 #endif
6209 return DMError::DM_OK;
6210 }
6211
SetFoldDisplayModeFromJs(const FoldDisplayMode displayMode,std::string reason)6212 DMError ScreenSessionManager::SetFoldDisplayModeFromJs(const FoldDisplayMode displayMode, std::string reason)
6213 {
6214 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6215 TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
6216 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6217 return DMError::DM_ERROR_NOT_SYSTEM_APP;
6218 }
6219 return SetFoldDisplayModeInner(displayMode, reason);
6220 }
6221
UpdateDisplayScaleState(ScreenId screenId)6222 void ScreenSessionManager::UpdateDisplayScaleState(ScreenId screenId)
6223 {
6224 auto session = GetScreenSession(screenId);
6225 if (session == nullptr) {
6226 TLOGE(WmsLogTag::DMS, "session is null");
6227 return;
6228 }
6229 const ScreenProperty& property = session->GetScreenProperty();
6230 if (std::fabs(property.GetScaleX() - DEFAULT_SCALE) < FLT_EPSILON &&
6231 std::fabs(property.GetScaleY() - DEFAULT_SCALE) < FLT_EPSILON &&
6232 std::fabs(property.GetPivotX() - DEFAULT_PIVOT) < FLT_EPSILON &&
6233 std::fabs(property.GetPivotY() - DEFAULT_PIVOT) < FLT_EPSILON) {
6234 TLOGD(WmsLogTag::DMS, "The scale and pivot is default value now. There is no need to update");
6235 return;
6236 }
6237 SetDisplayScaleInner(screenId, property.GetScaleX(), property.GetScaleY(), property.GetPivotX(),
6238 property.GetPivotY());
6239 }
6240
SetDisplayScaleInner(ScreenId screenId,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY)6241 void ScreenSessionManager::SetDisplayScaleInner(ScreenId screenId, const float& scaleX, const float& scaleY,
6242 const float& pivotX, const float& pivotY)
6243 {
6244 auto session = GetScreenSession(screenId);
6245 if (session == nullptr) {
6246 TLOGE(WmsLogTag::DMS, "session is null");
6247 return;
6248 }
6249 if (pivotX > 1.0f || pivotX < 0.0f || pivotY > 1.0f || pivotY < 0.0f) {
6250 TLOGE(WmsLogTag::DMS, "pivotX [%{public}f] and pivotY [%{public}f] should be in [0.0~1.0f]", pivotX, pivotY);
6251 return;
6252 }
6253 float translateX = 0.0f;
6254 float translateY = 0.0f;
6255 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
6256 CalcDisplayNodeTranslateOnPocketFoldRotation(session, scaleX, scaleY, pivotX, pivotY,
6257 translateX, translateY);
6258 } else if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
6259 if (FoldDisplayMode::MAIN == GetFoldDisplayMode()) {
6260 CalcDisplayNodeTranslateOnPocketFoldRotation(session, scaleX, scaleY, pivotX, pivotY,
6261 translateX, translateY);
6262 } else {
6263 CalcDisplayNodeTranslateOnRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
6264 }
6265 } else if (ROTATE_POLICY == FOLDABLE_DEVICE && FoldDisplayMode::FULL == GetFoldDisplayMode()) {
6266 CalcDisplayNodeTranslateOnFoldableRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
6267 } else {
6268 CalcDisplayNodeTranslateOnRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
6269 }
6270 TLOGD(WmsLogTag::DMS,
6271 "screenId %{public}" PRIu64 ", scale [%{public}f, %{public}f], "
6272 "pivot [%{public}f, %{public}f], translate [%{public}f, %{public}f]",
6273 screenId, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
6274 session->SetScreenScale(scaleX, scaleY, pivotX, pivotY, translateX, translateY);
6275 NotifyDisplayStateChange(GetDefaultScreenId(), session->ConvertToDisplayInfo(), {},
6276 DisplayStateChangeType::UPDATE_SCALE);
6277 }
6278
CalcDisplayNodeTranslateOnFoldableRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)6279 void ScreenSessionManager::CalcDisplayNodeTranslateOnFoldableRotation(sptr<ScreenSession>& session, const float& scaleX,
6280 const float& scaleY, const float& pivotX,
6281 const float& pivotY, float& translateX,
6282 float& translateY)
6283 {
6284 if (session == nullptr) {
6285 TLOGE(WmsLogTag::DMS, "session is nullptr");
6286 return;
6287 }
6288 const ScreenProperty& screenProperty = session->GetScreenProperty();
6289 auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
6290 auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
6291 Rotation rotation = session->GetRotation();
6292 float rotatedPivotX = DEFAULT_PIVOT;
6293 float rotatedPivotY = DEFAULT_PIVOT;
6294 float width = 0.0f;
6295 float height = 0.0f;
6296 switch (rotation) {
6297 case Rotation::ROTATION_0:
6298 rotatedPivotX = pivotY;
6299 rotatedPivotY = 1.0f - pivotX;
6300 width = screenHeight;
6301 height = screenWidth;
6302 break;
6303 case Rotation::ROTATION_90:
6304 rotatedPivotX = 1.0f - pivotX;
6305 rotatedPivotY = 1.0f - pivotY;
6306 width = screenWidth;
6307 height = screenHeight;
6308 break;
6309 case Rotation::ROTATION_180:
6310 rotatedPivotX = 1.0f - pivotY;
6311 rotatedPivotY = pivotX;
6312 width = screenHeight;
6313 height = screenWidth;
6314 break;
6315 case Rotation::ROTATION_270:
6316 rotatedPivotX = pivotX;
6317 rotatedPivotY = pivotY;
6318 width = screenWidth;
6319 height = screenHeight;
6320 break;
6321 default:
6322 TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
6323 break;
6324 }
6325 translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
6326 translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
6327 }
6328
CalcDisplayNodeTranslateOnPocketFoldRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)6329 void ScreenSessionManager::CalcDisplayNodeTranslateOnPocketFoldRotation(sptr<ScreenSession>& session,
6330 const float& scaleX, const float& scaleY,
6331 const float& pivotX, const float& pivotY,
6332 float& translateX, float& translateY)
6333 {
6334 if (session == nullptr) {
6335 TLOGE(WmsLogTag::DMS, "session is nullptr");
6336 return;
6337 }
6338 const ScreenProperty& screenProperty = session->GetScreenProperty();
6339 auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
6340 auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
6341 Rotation rotation = session->GetRotation();
6342 float rotatedPivotX = DEFAULT_PIVOT;
6343 float rotatedPivotY = DEFAULT_PIVOT;
6344 float width = 0.0f;
6345 float height = 0.0f;
6346 switch (rotation) {
6347 case Rotation::ROTATION_0:
6348 rotatedPivotX = 1.0f - pivotY;
6349 rotatedPivotY = pivotX;
6350 width = screenHeight;
6351 height = screenWidth;
6352 break;
6353 case Rotation::ROTATION_90:
6354 rotatedPivotX = pivotX;
6355 rotatedPivotY = pivotY;
6356 width = screenWidth;
6357 height = screenHeight;
6358 break;
6359 case Rotation::ROTATION_180:
6360 rotatedPivotX = pivotY;
6361 rotatedPivotY = 1.0f - pivotX;
6362 width = screenHeight;
6363 height = screenWidth;
6364 break;
6365 case Rotation::ROTATION_270:
6366 rotatedPivotX = 1.0f - pivotX;
6367 rotatedPivotY = 1.0f - pivotY;
6368 width = screenWidth;
6369 height = screenHeight;
6370 break;
6371 default:
6372 TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
6373 break;
6374 }
6375 translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
6376 translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
6377 }
6378
CalcDisplayNodeTranslateOnRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)6379 void ScreenSessionManager::CalcDisplayNodeTranslateOnRotation(sptr<ScreenSession>& session, const float& scaleX,
6380 const float& scaleY, const float& pivotX,
6381 const float& pivotY, float& translateX, float& translateY)
6382 {
6383 if (session == nullptr) {
6384 TLOGE(WmsLogTag::DMS, "session is nullptr");
6385 return;
6386 }
6387 const ScreenProperty& screenProperty = session->GetScreenProperty();
6388 auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
6389 auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
6390 Rotation rotation = session->GetRotation();
6391 float rotatedPivotX = DEFAULT_PIVOT;
6392 float rotatedPivotY = DEFAULT_PIVOT;
6393 float width = 0.0f;
6394 float height = 0.0f;
6395 switch (rotation) {
6396 case Rotation::ROTATION_0:
6397 rotatedPivotX = pivotX;
6398 rotatedPivotY = pivotY;
6399 width = screenWidth;
6400 height = screenHeight;
6401 break;
6402 case Rotation::ROTATION_90:
6403 rotatedPivotX = pivotY;
6404 rotatedPivotY = 1.0f - pivotX;
6405 width = screenHeight;
6406 height = screenWidth;
6407 break;
6408 case Rotation::ROTATION_180:
6409 rotatedPivotX = 1.0f - pivotX;
6410 rotatedPivotY = 1.0f - pivotY;
6411 width = screenWidth;
6412 height = screenHeight;
6413 break;
6414 case Rotation::ROTATION_270:
6415 rotatedPivotX = 1.0f - pivotY;
6416 rotatedPivotY = pivotX;
6417 width = screenHeight;
6418 height = screenWidth;
6419 break;
6420 default:
6421 TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
6422 break;
6423 }
6424 translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
6425 translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
6426 }
6427
SetDisplayScale(ScreenId screenId,float scaleX,float scaleY,float pivotX,float pivotY)6428 void ScreenSessionManager::SetDisplayScale(ScreenId screenId, float scaleX, float scaleY, float pivotX,
6429 float pivotY)
6430 {
6431 if (!SessionPermission::IsSACalling()) {
6432 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
6433 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6434 return;
6435 }
6436 SetDisplayScaleInner(screenId, scaleX, scaleY, pivotX, pivotY);
6437 }
6438
SetFoldStatusLocked(bool locked)6439 void ScreenSessionManager::SetFoldStatusLocked(bool locked)
6440 {
6441 #ifdef FOLD_ABILITY_ENABLE
6442 if (!g_foldScreenFlag) {
6443 return;
6444 }
6445 if (foldScreenController_ == nullptr) {
6446 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6447 return;
6448 }
6449 if (!SessionPermission::IsSystemCalling()) {
6450 TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
6451 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6452 return;
6453 }
6454 foldScreenController_->LockDisplayStatus(locked);
6455 #endif
6456 }
6457
SetFoldStatusLockedFromJs(bool locked)6458 DMError ScreenSessionManager::SetFoldStatusLockedFromJs(bool locked)
6459 {
6460 if (!SessionPermission::IsSystemCalling()) {
6461 TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
6462 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6463 return DMError::DM_ERROR_NOT_SYSTEM_APP;
6464 }
6465 SetFoldStatusLocked(locked);
6466 return DMError::DM_OK;
6467 }
6468
GetFoldDisplayMode()6469 FoldDisplayMode ScreenSessionManager::GetFoldDisplayMode()
6470 {
6471 #ifdef FOLD_ABILITY_ENABLE
6472 DmsXcollie dmsXcollie("DMS:GetFoldDisplayMode", XCOLLIE_TIMEOUT_10S);
6473 if (!g_foldScreenFlag) {
6474 return FoldDisplayMode::UNKNOWN;
6475 }
6476 if (foldScreenController_ == nullptr) {
6477 TLOGD(WmsLogTag::DMS, "foldScreenController_ is null");
6478 return FoldDisplayMode::UNKNOWN;
6479 }
6480 return foldScreenController_->GetDisplayMode();
6481 #else
6482 return FoldDisplayMode::UNKNOWN;
6483 #endif
6484 }
6485
IsFoldable()6486 bool ScreenSessionManager::IsFoldable()
6487 {
6488 #ifdef FOLD_ABILITY_ENABLE
6489 // Most applications do not adapt to Lem rotation and are temporarily treated as non fold device
6490 if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
6491 return false;
6492 }
6493
6494 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
6495 return true;
6496 }
6497
6498 if (!g_foldScreenFlag) {
6499 return false;
6500 }
6501 if (foldScreenController_ == nullptr) {
6502 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6503 return false;
6504 }
6505 return foldScreenController_->IsFoldable();
6506 #else
6507 return false;
6508 #endif
6509 }
6510
IsCaptured()6511 bool ScreenSessionManager::IsCaptured()
6512 {
6513 if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none") {
6514 // 如果当前是PC拓展模式,非截屏,录屏,投屏,则返回false
6515 return isScreenShot_ || virtualScreenCount_ > 0 || (hdmiScreenCount_ > 0 && !IsExtendMode());
6516 } else {
6517 return isScreenShot_ || virtualScreenCount_ > 0 || hdmiScreenCount_ > 0;
6518 }
6519 }
6520
IsMultiScreenCollaboration()6521 bool ScreenSessionManager::IsMultiScreenCollaboration()
6522 {
6523 return isMultiScreenCollaboration_;
6524 }
6525
HasCastEngineOrPhyMirror(const std::vector<ScreenId> & screenIdsToExclude)6526 bool ScreenSessionManager::HasCastEngineOrPhyMirror(const std::vector<ScreenId>& screenIdsToExclude)
6527 {
6528 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6529 for (auto sessionItem : screenSessionMap_) {
6530 auto screenId = sessionItem.first;
6531 auto screenSession = sessionItem.second;
6532 if (screenSession == nullptr) {
6533 TLOGI(WmsLogTag::DMS, "screenSession is null");
6534 continue;
6535 }
6536 if (std::find(screenIdsToExclude.begin(), screenIdsToExclude.end(), screenId) != screenIdsToExclude.end()) {
6537 continue;
6538 }
6539 auto screenType = screenSession->GetScreenProperty().GetScreenType();
6540 if (screenType == ScreenType::VIRTUAL
6541 && screenSession->GetName() == "CastEngine") {
6542 return true;
6543 }
6544
6545 if (IsDefaultMirrorMode(screenId) && screenType == ScreenType::REAL &&
6546 screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
6547 return true;
6548 }
6549 }
6550 return false;
6551 }
6552
GetFoldStatus()6553 FoldStatus ScreenSessionManager::GetFoldStatus()
6554 {
6555 #ifdef FOLD_ABILITY_ENABLE
6556 DmsXcollie dmsXcollie("DMS:GetFoldStatus", XCOLLIE_TIMEOUT_10S);
6557 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
6558 SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
6559 return SuperFoldStateManager::GetInstance().MatchSuperFoldStatusToFoldStatus(status);
6560 }
6561 if (!g_foldScreenFlag) {
6562 return FoldStatus::UNKNOWN;
6563 }
6564 if (foldScreenController_ == nullptr) {
6565 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6566 return FoldStatus::UNKNOWN;
6567 }
6568 return foldScreenController_->GetFoldStatus();
6569 #else
6570 return FoldStatus::UNKNOWN;
6571 #endif
6572 }
6573
GetSuperFoldStatus()6574 SuperFoldStatus ScreenSessionManager::GetSuperFoldStatus()
6575 {
6576 #ifdef FOLD_ABILITY_ENABLE
6577 DmsXcollie dmsXcollie("DMS:GetSuperFoldStatus", XCOLLIE_TIMEOUT_10S);
6578 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
6579 return SuperFoldStatus::UNKNOWN;
6580 }
6581 SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
6582 return status;
6583 #else
6584 return SuperFoldStatus::UNKNOWN;
6585 #endif
6586 }
6587
SetLandscapeLockStatus(bool isLocked)6588 void ScreenSessionManager::SetLandscapeLockStatus(bool isLocked)
6589 {
6590 #ifdef FOLD_ABILITY_ENABLE
6591 if (isLocked) {
6592 SetIsExtendScreenConnected(true);
6593 } else {
6594 SetIsExtendScreenConnected(false);
6595 SuperFoldSensorManager::GetInstance().HandleScreenDisconnectChange();
6596 }
6597 #endif
6598 }
6599
GetExtendScreenConnectStatus()6600 ExtendScreenConnectStatus ScreenSessionManager::GetExtendScreenConnectStatus()
6601 {
6602 #ifdef WM_MULTI_SCREEN_ENABLE
6603 DmsXcollie dmsXcollie("DMS:GetExtendScreenConnectStatus", XCOLLIE_TIMEOUT_10S);
6604 return extendScreenConnectStatus_.load();
6605 #else
6606 return ExtendScreenConnectStatus::UNKNOWN;
6607 #endif
6608 }
6609
GetIsExtendScreenConnected()6610 bool ScreenSessionManager::GetIsExtendScreenConnected()
6611 {
6612 return isExtendScreenConnected_;
6613 }
6614
SetIsExtendScreenConnected(bool isExtendScreenConnected)6615 void ScreenSessionManager::SetIsExtendScreenConnected(bool isExtendScreenConnected)
6616 {
6617 isExtendScreenConnected_ = isExtendScreenConnected;
6618 }
6619
HandleExtendScreenConnect(ScreenId screenId)6620 void ScreenSessionManager::HandleExtendScreenConnect(ScreenId screenId)
6621 {
6622 #ifdef FOLD_ABILITY_ENABLE
6623 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
6624 TLOGI(WmsLogTag::DMS, "not super fold display device.");
6625 return;
6626 }
6627 SetIsExtendScreenConnected(true);
6628 SuperFoldSensorManager::GetInstance().HandleScreenConnectChange();
6629 OnExtendScreenConnectStatusChange(screenId, ExtendScreenConnectStatus::CONNECT);
6630 extendScreenConnectStatus_.store(ExtendScreenConnectStatus::CONNECT);
6631 #endif
6632 }
6633
HandleExtendScreenDisconnect(ScreenId screenId)6634 void ScreenSessionManager::HandleExtendScreenDisconnect(ScreenId screenId)
6635 {
6636 #ifdef FOLD_ABILITY_ENABLE
6637 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
6638 TLOGI(WmsLogTag::DMS, "not super fold display device.");
6639 return;
6640 }
6641 SetIsExtendScreenConnected(false);
6642 SuperFoldSensorManager::GetInstance().HandleScreenDisconnectChange();
6643 OnExtendScreenConnectStatusChange(screenId, ExtendScreenConnectStatus::DISCONNECT);
6644 extendScreenConnectStatus_.store(ExtendScreenConnectStatus::DISCONNECT);
6645 #endif
6646 }
6647
GetTentMode()6648 bool ScreenSessionManager::GetTentMode()
6649 {
6650 #ifdef FOLD_ABILITY_ENABLE
6651 if (!g_foldScreenFlag) {
6652 return false;
6653 }
6654 if (foldScreenController_ == nullptr) {
6655 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6656 return false;
6657 }
6658 return foldScreenController_->GetTentMode();
6659 #else
6660 return false;
6661 #endif
6662 }
6663
GetCameraMode()6664 bool ScreenSessionManager::GetCameraMode()
6665 {
6666 if (!g_foldScreenFlag) {
6667 return false;
6668 }
6669 if (foldScreenController_ == nullptr) {
6670 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6671 return false;
6672 }
6673 return foldScreenController_->GetCameraMode();
6674 }
6675
GetCurrentFoldCreaseRegion()6676 sptr<FoldCreaseRegion> ScreenSessionManager::GetCurrentFoldCreaseRegion()
6677 {
6678 #ifdef FOLD_ABILITY_ENABLE
6679 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
6680 return SuperFoldStateManager::GetInstance().GetCurrentFoldCreaseRegion();
6681 }
6682 if (!g_foldScreenFlag) {
6683 return nullptr;
6684 }
6685 if (foldScreenController_ == nullptr) {
6686 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
6687 return nullptr;
6688 }
6689 return foldScreenController_->GetCurrentFoldCreaseRegion();
6690 #else
6691 return nullptr;
6692 #endif
6693 }
6694
GetCurvedCompressionArea()6695 uint32_t ScreenSessionManager::GetCurvedCompressionArea()
6696 {
6697 return ScreenSceneConfig::GetCurvedCompressionAreaInLandscape();
6698 }
6699
NotifyFoldStatusChanged(FoldStatus foldStatus)6700 void ScreenSessionManager::NotifyFoldStatusChanged(FoldStatus foldStatus)
6701 {
6702 #ifdef FOLD_ABILITY_ENABLE
6703 sptr<ScreenSession> screenSession = GetDefaultScreenSession();
6704 if (screenSession != nullptr) {
6705 if (foldStatus == FoldStatus::FOLDED && !FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
6706 screenSession->SetDefaultDeviceRotationOffset(0);
6707 } else {
6708 screenSession->SetDefaultDeviceRotationOffset(defaultDeviceRotationOffset_);
6709 }
6710 }
6711 if (screenSession != nullptr && FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() &&
6712 foldStatus == FoldStatus::FOLDED) {
6713 // sub screen default rotation offset is 270
6714 screenSession->SetDefaultDeviceRotationOffset(270);
6715 }
6716 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER);
6717 TLOGI(WmsLogTag::DMS, "foldStatus:%{public}d, agent size: %{public}u",
6718 foldStatus, static_cast<uint32_t>(agents.size()));
6719 if (agents.empty()) {
6720 return;
6721 }
6722 for (auto& agent : agents) {
6723 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6724 if (!IsFreezed(agentPid, DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER)) {
6725 agent->NotifyFoldStatusChanged(foldStatus);
6726 }
6727 }
6728 if (lowTemp_ == LowTempMode::LOW_TEMP_ON) {
6729 ScreenSessionPublish::GetInstance().PublishSmartNotificationEvent(FAULT_DESCRIPTION, FAULT_SUGGESTION);
6730 }
6731 #endif
6732 }
6733
SetLowTemp(LowTempMode lowTemp)6734 void ScreenSessionManager::SetLowTemp(LowTempMode lowTemp)
6735 {
6736 std::lock_guard<std::mutex> lock(lowTempMutex_);
6737 if (lowTemp == LowTempMode::LOW_TEMP_ON && lowTemp_ != lowTemp) {
6738 TLOGI(WmsLogTag::DMS, "device enter low temperature mode.");
6739 ScreenSessionPublish::GetInstance().PublishSmartNotificationEvent(FAULT_DESCRIPTION, FAULT_SUGGESTION);
6740 }
6741 if (lowTemp == LowTempMode::LOW_TEMP_OFF) {
6742 TLOGI(WmsLogTag::DMS, "device exit low temperature mode.");
6743 }
6744 lowTemp_ = lowTemp;
6745 }
6746
NotifyFoldAngleChanged(std::vector<float> foldAngles)6747 void ScreenSessionManager::NotifyFoldAngleChanged(std::vector<float> foldAngles)
6748 {
6749 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER);
6750 if (agents.empty()) {
6751 TLOGI(WmsLogTag::DMS, "agents is empty");
6752 return;
6753 }
6754 {
6755 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
6756 lastFoldAngles_ = foldAngles;
6757 }
6758 for (auto& agent : agents) {
6759 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6760 if (!IsFreezed(agentPid, DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER)) {
6761 agent->NotifyFoldAngleChanged(foldAngles);
6762 }
6763 }
6764 }
6765
NotifyCaptureStatusChanged()6766 void ScreenSessionManager::NotifyCaptureStatusChanged()
6767 {
6768 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER);
6769 bool isCapture = IsCaptured();
6770 isScreenShot_ = false;
6771 if (agents.empty()) {
6772 return;
6773 }
6774 for (auto& agent : agents) {
6775 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6776 if (!IsFreezed(agentPid, DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER)) {
6777 agent->NotifyCaptureStatusChanged(isCapture);
6778 }
6779 }
6780 }
6781
NotifyCaptureStatusChanged(bool isCapture)6782 void ScreenSessionManager::NotifyCaptureStatusChanged(bool isCapture)
6783 {
6784 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER);
6785 if (agents.empty()) {
6786 return;
6787 }
6788 for (auto& agent : agents) {
6789 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6790 if (!IsFreezed(agentPid, DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER)) {
6791 agent->NotifyCaptureStatusChanged(isCapture);
6792 }
6793 }
6794 }
6795
NotifyDisplayChangeInfoChanged(const sptr<DisplayChangeInfo> & info)6796 void ScreenSessionManager::NotifyDisplayChangeInfoChanged(const sptr<DisplayChangeInfo>& info)
6797 {
6798 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER);
6799 if (agents.empty()) {
6800 return;
6801 }
6802 {
6803 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
6804 lastDisplayChangeInfo_ = info;
6805 }
6806 for (auto& agent : agents) {
6807 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6808 if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER)) {
6809 agent->NotifyDisplayChangeInfoChanged(info);
6810 }
6811 }
6812 }
6813
RefreshMirrorScreenRegion(ScreenId screenId)6814 void ScreenSessionManager::RefreshMirrorScreenRegion(ScreenId screenId)
6815 {
6816 #if defined(FOLD_ABILITY_ENABLE) && defined(WM_MULTI_SCREEN_ENABLE)
6817 auto screenSession = GetScreenSession(screenId);
6818 if (screenSession == nullptr) {
6819 TLOGE(WmsLogTag::DMS, "can not get screen session");
6820 return;
6821 }
6822 if (screenSession->GetName() == "CastEngine" || screenSession->GetName() == "Cooperation") {
6823 DMRect mainScreenRegion = {0, 0, 0, 0};
6824 foldScreenController_->SetMainScreenRegion(mainScreenRegion);
6825 ScreenId rsScreenId = SCREEN_ID_INVALID;
6826 if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
6827 TLOGE(WmsLogTag::DMS, "Screen: %{public}" PRIu64" convert to rs id failed", screenId);
6828 } else {
6829 screenSession->SetMirrorScreenRegion(rsScreenId, mainScreenRegion);
6830 screenSession->EnableMirrorScreenRegion();
6831 }
6832 }
6833 #endif
6834 }
6835
NotifyDisplayModeChanged(FoldDisplayMode displayMode)6836 void ScreenSessionManager::NotifyDisplayModeChanged(FoldDisplayMode displayMode)
6837 {
6838 NotifyClientProxyUpdateFoldDisplayMode(displayMode);
6839 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER);
6840 TLOGI(WmsLogTag::DMS, "DisplayMode:%{public}d, agent size: %{public}u",
6841 displayMode, static_cast<uint32_t>(agents.size()));
6842 if (agents.empty()) {
6843 return;
6844 }
6845 for (auto& agent : agents) {
6846 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6847 if (!IsFreezed(agentPid,
6848 DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER)) {
6849 agent->NotifyDisplayModeChanged(displayMode);
6850 }
6851 }
6852 #ifdef FOLD_ABILITY_ENABLE
6853 if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
6854 auto screenIds = GetAllScreenIds();
6855 for (auto screenId : screenIds) {
6856 RefreshMirrorScreenRegion(screenId);
6857 }
6858 }
6859 #endif
6860 }
6861
NotifyScreenMagneticStateChanged(bool isMagneticState)6862 void ScreenSessionManager::NotifyScreenMagneticStateChanged(bool isMagneticState)
6863 {
6864 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_MAGNETIC_STATE_CHANGED_LISTENER);
6865 TLOGI(WmsLogTag::DMS, "IsScreenMagneticState:%{public}u, agent size: %{public}u",
6866 static_cast<uint32_t>(isMagneticState), static_cast<uint32_t>(agents.size()));
6867 if (agents.empty()) {
6868 return;
6869 }
6870 for (auto& agent : agents) {
6871 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6872 if (!IsFreezed(agentPid,
6873 DisplayManagerAgentType::SCREEN_MAGNETIC_STATE_CHANGED_LISTENER)) {
6874 agent->NotifyScreenMagneticStateChanged(isMagneticState);
6875 }
6876 }
6877 }
6878
SetDisplayNodeScreenId(ScreenId screenId,ScreenId displayNodeScreenId)6879 void ScreenSessionManager::SetDisplayNodeScreenId(ScreenId screenId, ScreenId displayNodeScreenId)
6880 {
6881 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " displayNodeScreenId: %{public}" PRIu64,
6882 screenId, displayNodeScreenId);
6883 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetDisplayNodeScreenId");
6884 if (!clientProxy_) {
6885 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
6886 return;
6887 }
6888 clientProxy_->SetDisplayNodeScreenId(screenId, displayNodeScreenId);
6889 #ifdef DEVICE_STATUS_ENABLE
6890 SetDragWindowScreenId(screenId, displayNodeScreenId);
6891 #endif // DEVICE_STATUS_ENABLE
6892 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SetMultiWindowScreenId");
6893 MMI::InputManager::GetInstance()->SetMultiWindowScreenId(screenId, displayNodeScreenId);
6894 }
6895
6896 #ifdef DEVICE_STATUS_ENABLE
SetDragWindowScreenId(ScreenId screenId,ScreenId displayNodeScreenId)6897 void ScreenSessionManager::SetDragWindowScreenId(ScreenId screenId, ScreenId displayNodeScreenId)
6898 {
6899 auto interactionManager = Msdp::DeviceStatus::InteractionManager::GetInstance();
6900 if (interactionManager != nullptr) {
6901 interactionManager->SetDragWindowScreenId(screenId, displayNodeScreenId);
6902 }
6903 }
6904 #endif // DEVICE_STATUS_ENABLE
6905
OnPropertyChange(const ScreenProperty & newProperty,ScreenPropertyChangeReason reason,ScreenId screenId)6906 void ScreenSessionManager::OnPropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason,
6907 ScreenId screenId)
6908 {
6909 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " reason: %{public}d", screenId, static_cast<int>(reason));
6910 if (!clientProxy_) {
6911 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
6912 if (foldScreenController_ != nullptr) {
6913 foldScreenController_->SetdisplayModeChangeStatus(false);
6914 }
6915 return;
6916 }
6917 clientProxy_->OnPropertyChanged(screenId, newProperty, reason);
6918 }
6919
OnPowerStatusChange(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)6920 void ScreenSessionManager::OnPowerStatusChange(DisplayPowerEvent event, EventStatus status,
6921 PowerStateChangeReason reason)
6922 {
6923 TLOGI(WmsLogTag::DMS, "[UL_POWER]event: %{public}d, status: %{public}d, reason: %{public}d",
6924 static_cast<int>(event),
6925 static_cast<int>(status), static_cast<int>(reason));
6926 if (!clientProxy_) {
6927 TLOGI(WmsLogTag::DMS, "[UL_POWER] clientProxy_ is null");
6928 return;
6929 }
6930 clientProxy_->OnPowerStatusChanged(event, status, reason);
6931 }
6932
OnSensorRotationChange(float sensorRotation,ScreenId screenId)6933 void ScreenSessionManager::OnSensorRotationChange(float sensorRotation, ScreenId screenId)
6934 {
6935 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " sensorRotation: %{public}f", screenId, sensorRotation);
6936 if (!clientProxy_) {
6937 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
6938 return;
6939 }
6940 clientProxy_->OnSensorRotationChanged(screenId, sensorRotation);
6941 }
6942
OnHoverStatusChange(int32_t hoverStatus,bool needRotate,ScreenId screenId)6943 void ScreenSessionManager::OnHoverStatusChange(int32_t hoverStatus, bool needRotate, ScreenId screenId)
6944 {
6945 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " hoverStatus: %{public}d", screenId, hoverStatus);
6946 if (!clientProxy_) {
6947 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
6948 return;
6949 }
6950 clientProxy_->OnHoverStatusChanged(screenId, hoverStatus, needRotate);
6951 }
6952
OnScreenOrientationChange(float screenOrientation,ScreenId screenId)6953 void ScreenSessionManager::OnScreenOrientationChange(float screenOrientation, ScreenId screenId)
6954 {
6955 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " screenOrientation: %{public}f", screenId, screenOrientation);
6956 if (!clientProxy_) {
6957 TLOGI(WmsLogTag::DMS, "ClientProxy_ is null");
6958 return;
6959 }
6960 clientProxy_->OnScreenOrientationChanged(screenId, screenOrientation);
6961 }
6962
OnScreenRotationLockedChange(bool isLocked,ScreenId screenId)6963 void ScreenSessionManager::OnScreenRotationLockedChange(bool isLocked, ScreenId screenId)
6964 {
6965 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " isLocked: %{public}d", screenId, isLocked);
6966 if (!clientProxy_) {
6967 TLOGI(WmsLogTag::DMS, "ClientProxy_ is null");
6968 return;
6969 }
6970 clientProxy_->OnScreenRotationLockedChanged(screenId, isLocked);
6971 }
6972
OnCameraBackSelfieChange(bool isCameraBackSelfie,ScreenId screenId)6973 void ScreenSessionManager::OnCameraBackSelfieChange(bool isCameraBackSelfie, ScreenId screenId)
6974 {
6975 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " isCameraBackSelfie: %{public}d", screenId, isCameraBackSelfie);
6976 if (!clientProxy_) {
6977 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
6978 return;
6979 }
6980 clientProxy_->OnCameraBackSelfieChanged(screenId, isCameraBackSelfie);
6981 }
6982
NotifyClientProxyUpdateFoldDisplayMode(FoldDisplayMode displayMode)6983 void ScreenSessionManager::NotifyClientProxyUpdateFoldDisplayMode(FoldDisplayMode displayMode)
6984 {
6985 if (clientProxy_) {
6986 TLOGI(WmsLogTag::DMS, "displayMode = %{public}d",
6987 static_cast<int>(displayMode));
6988 clientProxy_->OnUpdateFoldDisplayMode(displayMode);
6989 }
6990 }
6991
ScbClientDeathCallback(int32_t deathScbPid)6992 void ScreenSessionManager::ScbClientDeathCallback(int32_t deathScbPid)
6993 {
6994 std::unique_lock<std::mutex> lock(oldScbPidsMutex_);
6995 if (deathScbPid == currentScbPId_ || currentScbPId_ == INVALID_SCB_PID) {
6996 clientProxy_ = nullptr;
6997 TLOGE(WmsLogTag::DMS, "death callback and set clientProxy null");
6998 }
6999 if (scbSwitchCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_SCBSWITCH_MS))
7000 == std::cv_status::timeout) {
7001 TLOGE(WmsLogTag::DMS, "set client task deathScbPid:%{public}d, timeout: %{public}d",
7002 deathScbPid, CV_WAIT_SCBSWITCH_MS);
7003 }
7004 std::ostringstream oss;
7005 oss << "Scb client death: " << deathScbPid;
7006 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
7007 screenEventTracker_.RecordEvent(oss.str());
7008 oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), deathScbPid), oldScbPids_.end());
7009 }
7010
AddScbClientDeathRecipient(const sptr<IScreenSessionManagerClient> & scbClient,int32_t scbPid)7011 void ScreenSessionManager::AddScbClientDeathRecipient(const sptr<IScreenSessionManagerClient>& scbClient,
7012 int32_t scbPid)
7013 {
7014 sptr<ScbClientListenerDeathRecipient> scbClientDeathListener =
7015 new (std::nothrow) ScbClientListenerDeathRecipient(scbPid);
7016 if (scbClientDeathListener == nullptr) {
7017 TLOGE(WmsLogTag::DMS, "add scb: %{public}d death listener failed", scbPid);
7018 return;
7019 }
7020 if (scbClient != nullptr && scbClient->AsObject() != nullptr) {
7021 TLOGI(WmsLogTag::DMS, "add scb: %{public}d death listener", scbPid);
7022 scbClient->AsObject()->AddDeathRecipient(scbClientDeathListener);
7023 }
7024 }
7025
SwitchUser()7026 void ScreenSessionManager::SwitchUser()
7027 {
7028 #ifdef WM_MULTI_USR_ABILITY_ENABLE
7029 if (!SessionPermission::IsSystemCalling()) {
7030 TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
7031 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7032 return;
7033 }
7034 auto userId = GetUserIdByCallingUid();
7035 auto newScbPid = IPCSkeleton::GetCallingPid();
7036 currentUserIdForSettings_ = userId;
7037 SwitchScbNodeHandle(userId, newScbPid, false);
7038 MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, GetDefaultScreenId(), false);
7039 #endif
7040 }
7041
ScbStatusRecoveryWhenSwitchUser(std::vector<int32_t> oldScbPids,int32_t newScbPid)7042 void ScreenSessionManager::ScbStatusRecoveryWhenSwitchUser(std::vector<int32_t> oldScbPids, int32_t newScbPid)
7043 {
7044 #ifdef WM_MULTI_USR_ABILITY_ENABLE
7045 sptr<ScreenSession> screenSession = GetDefaultScreenSession();
7046 if (screenSession == nullptr) {
7047 TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
7048 return;
7049 }
7050 if (g_foldScreenFlag) {
7051 NotifyFoldStatusChanged(GetFoldStatus());
7052 NotifyDisplayModeChanged(GetFoldDisplayMode());
7053 }
7054 int64_t delayTime = 0;
7055 if (g_foldScreenFlag && oldScbDisplayMode_ != GetFoldDisplayMode() &&
7056 !FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
7057 delayTime = SWITCH_USER_DISPLAYMODE_CHANGE_DELAY;
7058 auto foldStatus = GetFoldStatus();
7059 TLOGE(WmsLogTag::DMS, "old mode: %{public}u, cur mode: %{public}u", oldScbDisplayMode_, GetFoldDisplayMode());
7060 if (foldStatus == FoldStatus::EXPAND || foldStatus == FoldStatus::HALF_FOLD ||
7061 FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7062 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7063 screenSession->UpdatePropertyByFoldControl(screenSession->GetScreenProperty());
7064 } else {
7065 screenSession->UpdatePropertyByFoldControl(GetPhyScreenProperty(SCREEN_ID_FULL));
7066 }
7067 screenSession->PropertyChange(screenSession->GetScreenProperty(),
7068 ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
7069 } else if (foldStatus == FoldStatus::FOLDED) {
7070 screenSession->UpdatePropertyByFoldControl(GetPhyScreenProperty(SCREEN_ID_MAIN));
7071 screenSession->PropertyChange(screenSession->GetScreenProperty(),
7072 ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING);
7073 } else {
7074 TLOGE(WmsLogTag::DMS, "unsupport foldStatus: %{public}u", foldStatus);
7075 }
7076 } else {
7077 screenSession->UpdateValidRotationToScb();
7078 }
7079 auto task = [=] {
7080 if (!clientProxy_) {
7081 TLOGE(WmsLogTag::DMS, "ScbStatusRecoveryWhenSwitchUser clientProxy_ is null");
7082 return;
7083 }
7084 clientProxy_->SwitchUserCallback(oldScbPids, newScbPid);
7085 RecoverMultiScreenModeWhenSwitchUser();
7086 };
7087 taskScheduler_->PostAsyncTask(task, "clientProxy_ SwitchUserCallback task", delayTime);
7088 #endif
7089 }
7090
RecoverMultiScreenModeWhenSwitchUser()7091 void ScreenSessionManager::RecoverMultiScreenModeWhenSwitchUser()
7092 {
7093 std::map<std::string, MultiScreenInfo> multiScreenInfoMap = ScreenSettingHelper::GetMultiScreenInfo();
7094 if (multiScreenInfoMap.empty()) {
7095 TLOGE(WmsLogTag::DMS, "no restored screen, use default mode!");
7096 return;
7097 }
7098 {
7099 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
7100 for (auto sessionIt : screenSessionMap_) {
7101 auto screenSession = sessionIt.second;
7102 if (screenSession == nullptr) {
7103 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
7104 continue;
7105 }
7106 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
7107 screenSession->GetIsExtend()) {
7108 TLOGI(WmsLogTag::DMS, "recover extend screen, screenId = %{public}" PRIu64"",
7109 sessionIt.first);
7110 RecoverMultiScreenMode(screenSession);
7111 }
7112 }
7113 }
7114 }
7115
SetClient(const sptr<IScreenSessionManagerClient> & client)7116 void ScreenSessionManager::SetClient(const sptr<IScreenSessionManagerClient>& client)
7117 {
7118 if (!SessionPermission::IsSystemCalling()) {
7119 TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
7120 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7121 return;
7122 }
7123 if (!client) {
7124 TLOGE(WmsLogTag::DMS, "SetClient client is null");
7125 return;
7126 }
7127 clientProxy_ = client;
7128 auto userId = GetUserIdByCallingUid();
7129 auto newScbPid = IPCSkeleton::GetCallingPid();
7130
7131 std::ostringstream oss;
7132 oss << "set client userId: " << userId
7133 << " clientName: " << SysCapUtil::GetClientName();
7134 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
7135 screenEventTracker_.RecordEvent(oss.str());
7136 currentUserIdForSettings_ = userId;
7137 MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, GetDefaultScreenId(), true);
7138 NotifyClientProxyUpdateFoldDisplayMode(GetFoldDisplayMode());
7139 SetClientInner();
7140 SwitchScbNodeHandle(userId, newScbPid, true);
7141 AddScbClientDeathRecipient(client, newScbPid);
7142 }
7143
SwitchScbNodeHandle(int32_t newUserId,int32_t newScbPid,bool coldBoot)7144 void ScreenSessionManager::SwitchScbNodeHandle(int32_t newUserId, int32_t newScbPid, bool coldBoot)
7145 {
7146 #ifdef WM_MULTI_USR_ABILITY_ENABLE
7147 std::ostringstream oss;
7148 oss << "currentUserId: " << currentUserId_
7149 << " currentScbPId: " << currentScbPId_
7150 << " newUserId: " << newUserId
7151 << " newScbPid: " << newScbPid
7152 << " coldBoot: " << static_cast<int32_t>(coldBoot);
7153 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
7154 screenEventTracker_.RecordEvent(oss.str());
7155
7156 std::unique_lock<std::mutex> lock(oldScbPidsMutex_);
7157 if (currentScbPId_ != INVALID_SCB_PID) {
7158 auto pidIter = std::find(oldScbPids_.begin(), oldScbPids_.end(), currentScbPId_);
7159 if (pidIter == oldScbPids_.end() && currentScbPId_ > 0) {
7160 oldScbPids_.emplace_back(currentScbPId_);
7161 }
7162 oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), newScbPid), oldScbPids_.end());
7163 if (oldScbPids_.size() == 0) {
7164 TLOGE(WmsLogTag::DMS, "swicth user failed, oldScbPids is null");
7165 screenEventTracker_.RecordEvent("swicth user failed, oldScbPids is null");
7166 }
7167 }
7168 if (!clientProxy_) {
7169 TLOGE(WmsLogTag::DMS, "clientProxy is null");
7170 return;
7171 }
7172 if (coldBoot) {
7173 clientProxy_->SwitchUserCallback(oldScbPids_, newScbPid);
7174 clientProxyMap_[newUserId] = clientProxy_;
7175 } else {
7176 HotSwitch(newUserId, newScbPid);
7177 }
7178 UpdateDisplayScaleState(GetDefaultScreenId());
7179 currentUserId_ = newUserId;
7180 currentScbPId_ = newScbPid;
7181 scbSwitchCV_.notify_all();
7182 oldScbDisplayMode_ = GetFoldDisplayMode();
7183 #endif
7184 }
7185
NotifyCastWhenSwitchScbNode()7186 void ScreenSessionManager::NotifyCastWhenSwitchScbNode()
7187 {
7188 std::map<ScreenId, sptr<ScreenSession>> screenSessionMapCopy;
7189 {
7190 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
7191 screenSessionMapCopy = screenSessionMap_;
7192 }
7193 for (const auto& sessionIt : screenSessionMapCopy) {
7194 auto screenSession = sessionIt.second;
7195 if (screenSession == nullptr) {
7196 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first);
7197 continue;
7198 }
7199 if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL ||
7200 !IsDefaultMirrorMode(screenSession->GetScreenId())) {
7201 TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"", sessionIt.first);
7202 continue;
7203 }
7204 bool isScreenMirror = screenSession ->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR;
7205 NotifyCastWhenScreenConnectChange(isScreenMirror);
7206 return;
7207 }
7208 }
7209
HotSwitch(int32_t newUserId,int32_t newScbPid)7210 void ScreenSessionManager::HotSwitch(int32_t newUserId, int32_t newScbPid)
7211 {
7212 // hot switch
7213 if (clientProxyMap_.count(newUserId) == 0) {
7214 TLOGE(WmsLogTag::DMS, "not found client proxy. userId:%{public}d.", newUserId);
7215 return;
7216 }
7217 if (newUserId == currentUserId_) {
7218 TLOGI(WmsLogTag::DMS, "switch user not change");
7219 return;
7220 }
7221 if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
7222 // Delete the screen whose ID is 5 generated by Coordination before switching the private space.
7223 SessionOption option = {
7224 .screenId_ = SCREEN_ID_MAIN,
7225 };
7226 clientProxy_->OnScreenConnectionChanged(option, ScreenEvent::DISCONNECTED);
7227 }
7228 clientProxy_ = clientProxyMap_[newUserId];
7229 ScbStatusRecoveryWhenSwitchUser(oldScbPids_, newScbPid);
7230 }
7231
GetCurrentUserId()7232 int32_t ScreenSessionManager::GetCurrentUserId()
7233 {
7234 return currentUserIdForSettings_;
7235 }
7236
SetClientInner()7237 void ScreenSessionManager::SetClientInner()
7238 {
7239 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
7240 for (const auto& iter : screenSessionMap_) {
7241 if (!iter.second) {
7242 continue;
7243 }
7244 // In the rotating state, after scb restarts, the screen information needs to be reset.
7245 float phyWidth = 0.0f;
7246 float phyHeight = 0.0f;
7247 bool isReset = true;
7248 GetCurrentScreenPhyBounds(phyWidth, phyHeight, isReset, iter.first);
7249 auto localRotation = iter.second->GetRotation();
7250 TLOGI(WmsLogTag::DMS, "phyWidth = :%{public}f, phyHeight = :%{public}f, localRotation = :%{public}u",
7251 phyWidth, phyHeight, localRotation);
7252 bool isModeChanged = localRotation != Rotation::ROTATION_0;
7253 if (isModeChanged && isReset) {
7254 TLOGI(WmsLogTag::DMS, "screen(id:%{public}" PRIu64 ") current is not default mode, reset it", iter.first);
7255 SetRotation(iter.first, Rotation::ROTATION_0, false);
7256 SetPhysicalRotationClientInner(iter.first, 0);
7257 iter.second->SetDisplayBoundary(RectF(0, 0, phyWidth, phyHeight), 0);
7258 }
7259 if (!clientProxy_) {
7260 TLOGE(WmsLogTag::DMS, "clientProxy is null");
7261 return;
7262 }
7263 if (iter.second->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
7264 TLOGI(WmsLogTag::DMS, "current screen is extend and mirror, return before OnScreenConnectionChanged");
7265 RecoverMultiScreenMode(iter.second);
7266 continue;
7267 }
7268 if (g_isPcDevice && g_outerOnly == ONLY_OUTER_SCREEN_VALUE && !iter.second->GetIsExtend()) {
7269 defaultScreenId_ = iter.first;
7270 }
7271 if (!g_isPcDevice) {
7272 clientProxy_->OnScreenConnectionChanged(GetSessionOption(iter.second, iter.first),
7273 ScreenEvent::CONNECTED);
7274 } else {
7275 TLOGI(WmsLogTag::DMS, "recover screen, id: %{public}" PRIu64, iter.first);
7276 RecoverMultiScreenMode(iter.second);
7277 }
7278 }
7279 }
7280
SetPhysicalRotationClientInner(ScreenId screenId,int rotation)7281 void ScreenSessionManager::SetPhysicalRotationClientInner(ScreenId screenId, int rotation)
7282 {
7283 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
7284 if (screenSession == nullptr) {
7285 TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"",
7286 screenId);
7287 return;
7288 }
7289 screenSession->SetPhysicalRotation(rotation);
7290 screenSession->SetScreenComponentRotation(rotation);
7291 TLOGI(WmsLogTag::DMS, "SetPhysicalRotationClientInner end");
7292 }
7293
RecoverMultiScreenMode(sptr<ScreenSession> screenSession)7294 void ScreenSessionManager::RecoverMultiScreenMode(sptr<ScreenSession> screenSession)
7295 {
7296 ScreenId screenId = screenSession->GetScreenId();
7297 if (screenSession == nullptr) {
7298 TLOGE(WmsLogTag::DMS, "screenSession is null!");
7299 return;
7300 }
7301 SetExtendedScreenFallbackPlan(screenId);
7302 if (!RecoverRestoredMultiScreenMode(screenSession)) {
7303 clientProxy_->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), ScreenEvent::CONNECTED);
7304 SetMultiScreenDefaultRelativePosition();
7305 if (screenSession->GetScreenCombination() != ScreenCombination::SCREEN_MAIN) {
7306 ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_EXTEND);
7307 }
7308 }
7309 if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
7310 screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::UNDEFINED);
7311 }
7312 }
7313
GetCurrentScreenPhyBounds(float & phyWidth,float & phyHeight,bool & isReset,const ScreenId & screenid)7314 void ScreenSessionManager::GetCurrentScreenPhyBounds(float& phyWidth, float& phyHeight,
7315 bool& isReset, const ScreenId& screenid)
7316 {
7317 #ifdef FOLD_ABILITY_ENABLE
7318 if (foldScreenController_ != nullptr) {
7319 FoldDisplayMode displayMode = GetFoldDisplayMode();
7320 TLOGI(WmsLogTag::DMS, "fold screen with displayMode = %{public}u", displayMode);
7321 if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
7322 auto phyBounds = GetPhyScreenProperty(screenid).GetPhyBounds();
7323 phyWidth = phyBounds.rect_.width_;
7324 phyHeight = phyBounds.rect_.height_;
7325 if (displayMode == FoldDisplayMode::UNKNOWN) {
7326 isReset = false;
7327 }
7328 return;
7329 }
7330 if (displayMode == FoldDisplayMode::MAIN) {
7331 auto phyBounds = GetPhyScreenProperty(SCREEN_ID_MAIN).GetPhyBounds();
7332 phyWidth = phyBounds.rect_.width_;
7333 phyHeight = phyBounds.rect_.height_;
7334 } else if (displayMode == FoldDisplayMode::FULL) {
7335 auto phyBounds = GetPhyScreenProperty(SCREEN_ID_FULL).GetPhyBounds();
7336 phyWidth = phyBounds.rect_.width_;
7337 phyHeight = phyBounds.rect_.height_;
7338 if (SCREEN_ROTATION_OFFSET == ROTATION_90 || SCREEN_ROTATION_OFFSET == ROTATION_270) {
7339 std::swap(phyWidth, phyHeight);
7340 }
7341 } else {
7342 isReset = false;
7343 }
7344 return;
7345 }
7346 #endif
7347 int id = HiviewDFX::XCollie::GetInstance().SetTimer("GetCurrentScreenPhyBounds", XCOLLIE_TIMEOUT_10S, nullptr,
7348 nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
7349 auto remoteScreenMode = rsInterface_.GetScreenActiveMode(screenid);
7350 HiviewDFX::XCollie::GetInstance().CancelTimer(id);
7351 phyWidth = remoteScreenMode.GetScreenWidth();
7352 phyHeight = remoteScreenMode.GetScreenHeight();
7353 }
7354
GetScreenProperty(ScreenId screenId)7355 ScreenProperty ScreenSessionManager::GetScreenProperty(ScreenId screenId)
7356 {
7357 DmsXcollie dmsXcollie("DMS:GetScreenProperty", XCOLLIE_TIMEOUT_10S);
7358 auto screenSession = GetScreenSession(screenId);
7359 if (!screenSession) {
7360 TLOGI(WmsLogTag::DMS, "screenSession is null");
7361 return {};
7362 }
7363 return screenSession->GetScreenProperty();
7364 }
7365
GetDisplayNode(ScreenId screenId)7366 std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetDisplayNode(ScreenId screenId)
7367 {
7368 DmsXcollie dmsXcollie("DMS:GetDisplayNode", XCOLLIE_TIMEOUT_10S);
7369 auto screenSession = GetScreenSession(screenId);
7370 if (!screenSession) {
7371 TLOGE(WmsLogTag::DMS, "screenSession is null");
7372 return nullptr;
7373 }
7374 return screenSession->GetDisplayNode();
7375 }
7376
GetScreenCombination(ScreenId screenId)7377 ScreenCombination ScreenSessionManager::GetScreenCombination(ScreenId screenId)
7378 {
7379 DmsXcollie dmsXcollie("DMS:GetScreenCombination", XCOLLIE_TIMEOUT_10S);
7380 auto screenSession = GetScreenSession(screenId);
7381 if (!screenSession) {
7382 TLOGI(WmsLogTag::DMS, "screenSession is null");
7383 return ScreenCombination::SCREEN_ALONE;
7384 }
7385 return screenSession->GetScreenCombination();
7386 }
7387
Dump(int fd,const std::vector<std::u16string> & args)7388 int ScreenSessionManager::Dump(int fd, const std::vector<std::u16string>& args)
7389 {
7390 TLOGI(WmsLogTag::DMS, "Dump begin");
7391 sptr<ScreenSessionDumper> dumper = new ScreenSessionDumper(fd, args);
7392 if (dumper == nullptr) {
7393 TLOGE(WmsLogTag::DMS, "dumper is nullptr");
7394 return -1;
7395 }
7396 dumper->DumpFreezedPidList(freezedPidList_);
7397 dumper->DumpEventTracker(screenEventTracker_);
7398 dumper->DumpMultiUserInfo(oldScbPids_, currentUserId_, currentScbPId_);
7399 dumper->ExecuteDumpCmd();
7400 TLOGI(WmsLogTag::DMS, "dump end");
7401 return 0;
7402 }
7403
TriggerFoldStatusChange(FoldStatus foldStatus)7404 void ScreenSessionManager::TriggerFoldStatusChange(FoldStatus foldStatus)
7405 {
7406 #ifdef FOLD_ABILITY_ENABLE
7407 TLOGI(WmsLogTag::DMS, "enter foldStatus = %{public}d.", foldStatus);
7408 if (foldScreenController_ == nullptr) {
7409 return;
7410 }
7411 foldScreenController_->SetFoldStatus(foldStatus);
7412 FoldDisplayMode displayMode = foldScreenController_->GetModeMatchStatus();
7413 SetFoldDisplayMode(displayMode);
7414 NotifyFoldStatusChanged(foldStatus);
7415 #endif
7416 }
7417
NotifyFoldStatusChanged(const std::string & statusParam)7418 int ScreenSessionManager::NotifyFoldStatusChanged(const std::string& statusParam)
7419 {
7420 #ifdef FOLD_ABILITY_ENABLE
7421 TLOGI(WmsLogTag::DMS, "is dump log");
7422 if (statusParam.empty()) {
7423 return -1;
7424 }
7425 FoldStatus foldStatus = FoldStatus::UNKNOWN;
7426 FoldDisplayMode displayMode = FoldDisplayMode::UNKNOWN;
7427 if (statusParam == STATUS_FOLD_HALF) {
7428 foldStatus = FoldStatus::HALF_FOLD;
7429 displayMode = FoldDisplayMode::FULL;
7430 } else if (statusParam == STATUS_EXPAND) {
7431 foldStatus = FoldStatus::EXPAND;
7432 displayMode = FoldDisplayMode::FULL;
7433 } else if (statusParam == STATUS_FOLD) {
7434 foldStatus = FoldStatus::FOLDED;
7435 displayMode = FoldDisplayMode::MAIN;
7436 } else {
7437 TLOGW(WmsLogTag::DMS, "status not support");
7438 return -1;
7439 }
7440 SetFoldDisplayMode(displayMode);
7441 if (foldScreenController_ != nullptr) {
7442 foldScreenController_->SetFoldStatus(foldStatus);
7443 }
7444 NotifyFoldStatusChanged(foldStatus);
7445 #endif
7446 return 0;
7447 }
7448
NotifyAvailableAreaChanged(DMRect area,DisplayId displayId)7449 void ScreenSessionManager::NotifyAvailableAreaChanged(DMRect area, DisplayId displayId)
7450 {
7451 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER);
7452 TLOGI(WmsLogTag::DMS, "entry, agent size: %{public}u", static_cast<uint32_t>(agents.size()));
7453 if (agents.empty()) {
7454 return;
7455 }
7456 TLOGI(WmsLogTag::DMS, "displayId: %{public}" PRIu64
7457 ", AvailableArea: [%{public}d, %{public}d, %{public}u, %{public}u]",
7458 static_cast<DisplayId>(displayId), area.posX_, area.posY_, area.width_, area.height_);
7459 for (auto& agent : agents) {
7460 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
7461 if (!IsFreezed(agentPid,
7462 DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER)) {
7463 agent->NotifyAvailableAreaChanged(area, displayId);
7464 }
7465 }
7466 }
7467
GetAvailableArea(DisplayId displayId,DMRect & area)7468 DMError ScreenSessionManager::GetAvailableArea(DisplayId displayId, DMRect& area)
7469 {
7470 auto displayInfo = GetDisplayInfoById(displayId);
7471 if (displayInfo == nullptr) {
7472 TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
7473 return DMError::DM_ERROR_NULLPTR;
7474 }
7475 sptr<ScreenSession> screenSession;
7476 if (displayId == DISPLAY_ID_FAKE) {
7477 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7478 return DMError::DM_ERROR_NULLPTR;
7479 }
7480 ScreenId internalScreenId = GetInternalScreenId();
7481 sptr<ScreenSession> internalScreenSession = GetScreenSession(internalScreenId);
7482 if (internalScreenSession == nullptr) {
7483 TLOGE(WmsLogTag::DMS, "internal session is nullptr.");
7484 return DMError::DM_ERROR_NULLPTR;
7485 }
7486 if (!internalScreenSession->GetScreenProperty().GetIsFakeInUse()) {
7487 return DMError::DM_ERROR_NULLPTR;
7488 }
7489 screenSession = internalScreenSession->GetFakeScreenSession();
7490 } else {
7491 screenSession = GetScreenSession(displayInfo->GetScreenId());
7492 }
7493 if (screenSession == nullptr) {
7494 TLOGE(WmsLogTag::DMS, "can not get screen now");
7495 return DMError::DM_ERROR_NULLPTR;
7496 }
7497 area = screenSession->GetAvailableArea();
7498 return DMError::DM_OK;
7499 }
7500
GetExpandAvailableArea(DisplayId displayId,DMRect & area)7501 DMError ScreenSessionManager::GetExpandAvailableArea(DisplayId displayId, DMRect& area)
7502 {
7503 auto displayInfo = GetDisplayInfoById(displayId);
7504 if (displayInfo == nullptr) {
7505 TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
7506 return DMError::DM_ERROR_NULLPTR;
7507 }
7508 sptr<ScreenSession> screenSession;
7509 screenSession = GetScreenSession(displayInfo->GetScreenId());
7510 if (screenSession == nullptr) {
7511 TLOGE(WmsLogTag::DMS, "can not get screen now");
7512 return DMError::DM_ERROR_NULLPTR;
7513 }
7514 area = screenSession->GetExpandAvailableArea();
7515 return DMError::DM_OK;
7516 }
7517
UpdateAvailableArea(ScreenId screenId,DMRect area)7518 void ScreenSessionManager::UpdateAvailableArea(ScreenId screenId, DMRect area)
7519 {
7520 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7521 TLOGE(WmsLogTag::DMS, "update available area permission denied!");
7522 return;
7523 }
7524
7525 auto screenSession = GetScreenSession(screenId);
7526 if (screenSession == nullptr) {
7527 TLOGE(WmsLogTag::DMS, "can not get default screen now");
7528 return;
7529 }
7530 if (!screenSession->UpdateAvailableArea(area)) {
7531 return;
7532 }
7533 NotifyAvailableAreaChanged(area, screenId);
7534 }
7535
UpdateSuperFoldAvailableArea(ScreenId screenId,DMRect bArea,DMRect cArea)7536 void ScreenSessionManager::UpdateSuperFoldAvailableArea(ScreenId screenId, DMRect bArea, DMRect cArea)
7537 {
7538 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7539 TLOGE(WmsLogTag::DMS, "update super fold available area permission denied!");
7540 return;
7541 }
7542
7543 auto screenSession = GetScreenSession(screenId);
7544 if (screenSession == nullptr) {
7545 TLOGE(WmsLogTag::DMS, "can not get default screen now");
7546 return;
7547 }
7548 if (screenSession->UpdateAvailableArea(bArea)) {
7549 NotifyAvailableAreaChanged(bArea, screenId);
7550 }
7551 if (!screenSession->GetIsFakeInUse()) {
7552 TLOGE(WmsLogTag::DMS, "fake screen session is not in use");
7553 return;
7554 }
7555 auto fakeScreenSession = screenSession->GetFakeScreenSession();
7556 if (fakeScreenSession == nullptr) {
7557 TLOGE(WmsLogTag::DMS, "can not get fake screen now");
7558 return;
7559 }
7560 if (fakeScreenSession->UpdateAvailableArea(cArea) && cArea.width_ > 0) {
7561 NotifyAvailableAreaChanged(cArea, fakeScreenSession->GetScreenId());
7562 }
7563 }
7564
UpdateSuperFoldExpandAvailableArea(ScreenId screenId,DMRect area)7565 void ScreenSessionManager::UpdateSuperFoldExpandAvailableArea(ScreenId screenId, DMRect area)
7566 {
7567 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7568 TLOGE(WmsLogTag::DMS, "update super fold available area permission denied!");
7569 return;
7570 }
7571
7572 auto screenSession = GetScreenSession(screenId);
7573 if (screenSession == nullptr) {
7574 TLOGE(WmsLogTag::DMS, "can not get default screen now");
7575 return;
7576 }
7577 if (screenSession->UpdateExpandAvailableArea(area)) {
7578 TLOGI(WmsLogTag::DMS,
7579 "ExpandAvailableArea x: %{public}d, y: %{public}d, width: %{public}d, height: %{public}d",
7580 area.posX_, area.posY_, area.width_, area.height_);
7581 }
7582 }
7583
NotifyFoldToExpandCompletion(bool foldToExpand)7584 void ScreenSessionManager::NotifyFoldToExpandCompletion(bool foldToExpand)
7585 {
7586 #ifdef FOLD_ABILITY_ENABLE
7587 TLOGI(WmsLogTag::DMS, "ENTER");
7588 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7589 TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
7590 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7591 return;
7592 }
7593 if (!FoldScreenStateInternel::IsDualDisplayFoldDevice() &&
7594 !FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
7595 !FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7596 SetDisplayNodeScreenId(SCREEN_ID_FULL, foldToExpand ? SCREEN_ID_FULL : SCREEN_ID_MAIN);
7597 }
7598 /* Avoid fold to expand process queues */
7599 if (foldScreenController_ != nullptr) {
7600 foldScreenController_->SetdisplayModeChangeStatus(false);
7601 }
7602 sptr<ScreenSession> screenSession = GetDefaultScreenSession();
7603 if (screenSession == nullptr) {
7604 TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
7605 return;
7606 }
7607 screenSession->UpdateRotationAfterBoot(foldToExpand);
7608 #endif
7609 }
7610
RecordEventFromScb(std::string description,bool needRecordEvent)7611 void ScreenSessionManager::RecordEventFromScb(std::string description, bool needRecordEvent)
7612 {
7613 TLOGW(WmsLogTag::DMS, "%{public}s", description.c_str());
7614 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7615 TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
7616 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7617 return;
7618 }
7619 if (needRecordEvent) {
7620 screenEventTracker_.RecordEvent(description);
7621 }
7622 }
7623
CheckAndSendHiSysEvent(const std::string & eventName,const std::string & bundleName) const7624 void ScreenSessionManager::CheckAndSendHiSysEvent(const std::string& eventName, const std::string& bundleName) const
7625 {
7626 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CheckAndSendHiSysEvent");
7627 if (eventName != "CREATE_VIRTUAL_SCREEN") {
7628 if (!Permission::CheckIsCallingBundleName(bundleName)) {
7629 TLOGD(WmsLogTag::DMS, "BundleName not in whitelist!");
7630 return;
7631 }
7632 }
7633 int32_t eventRet = HiSysEventWrite(
7634 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
7635 eventName, // CREATE_VIRTUAL_SCREEN, GET_DISPLAY_SNAPSHOT
7636 OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,
7637 "PID", getpid(),
7638 "UID", getuid());
7639 TLOGI(WmsLogTag::DMS, "%{public}s: Write HiSysEvent ret:%{public}d", eventName.c_str(), eventRet);
7640 }
7641
ProxyForFreeze(const std::set<int32_t> & pidList,bool isProxy)7642 DMError ScreenSessionManager::ProxyForFreeze(const std::set<int32_t>& pidList, bool isProxy)
7643 {
7644 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7645 TLOGE(WmsLogTag::DMS, "permission denied!");
7646 return DMError::DM_ERROR_NOT_SYSTEM_APP;
7647 }
7648 {
7649 std::lock_guard<std::mutex> lock(freezedPidListMutex_);
7650 for (auto pid : pidList) {
7651 if (isProxy) {
7652 freezedPidList_.insert(pid);
7653 } else {
7654 freezedPidList_.erase(pid); // set删除不存在的元素不会引发异常
7655 }
7656 }
7657 }
7658 if (isProxy) {
7659 return DMError::DM_OK;
7660 }
7661
7662 // 进程解冻时刷新一次displaychange
7663 sptr<ScreenSession> screenSession = GetScreenSession(GetDefaultScreenId());
7664 if (!screenSession) {
7665 return DMError::DM_ERROR_NULLPTR;
7666 }
7667 auto task = [=] {
7668 NotifyUnfreezed(pidList, screenSession);
7669 };
7670 taskScheduler_->PostAsyncTask(task, "ProxyForUnFreeze NotifyDisplayChanged");
7671 return DMError::DM_OK;
7672 }
7673
NotifyUnfreezedAgents(const int32_t & pid,const std::set<int32_t> & unfreezedPidList,const std::set<DisplayManagerAgentType> & pidAgentTypes,const sptr<ScreenSession> & screenSession)7674 void ScreenSessionManager::NotifyUnfreezedAgents(const int32_t& pid, const std::set<int32_t>& unfreezedPidList,
7675 const std::set<DisplayManagerAgentType>& pidAgentTypes, const sptr<ScreenSession>& screenSession)
7676 {
7677 bool isAgentTypeNotify = false;
7678 for (auto agentType : pidAgentTypes) {
7679 auto agents = dmAgentContainer_.GetAgentsByType(agentType);
7680 for (auto agent : agents) {
7681 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
7682 if (agentPid != pid || unfreezedPidList.count(pid) == 0) {
7683 continue;
7684 }
7685 isAgentTypeNotify = true;
7686 if (agentType == DisplayManagerAgentType::DISPLAY_EVENT_LISTENER) {
7687 agent->OnDisplayChange(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_UNFREEZED);
7688 } else if (agentType == DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER) {
7689 FoldDisplayMode displayMode = GetFoldDisplayMode();
7690 agent->NotifyDisplayModeChanged(displayMode);
7691 } else if (agentType == DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER) {
7692 FoldStatus foldStatus = GetFoldStatus();
7693 agent->NotifyFoldStatusChanged(foldStatus);
7694 } else if (agentType == DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER) {
7695 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
7696 agent->NotifyFoldAngleChanged(lastFoldAngles_);
7697 } else if (agentType == DisplayManagerAgentType::SCREEN_EVENT_LISTENER) {
7698 auto displayInfo = screenSession->ConvertToDisplayInfo();
7699 auto screenInfo = GetScreenInfoById(displayInfo->GetScreenId());
7700 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
7701 agent->OnScreenChange(screenInfo, lastScreenChangeEvent_);
7702 } else if (agentType == DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER) {
7703 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
7704 agent->NotifyDisplayChangeInfoChanged(lastDisplayChangeInfo_);
7705 } else if (agentType == DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER) {
7706 auto area = screenSession->GetAvailableArea();
7707 auto displayId = screenSession->ConvertToDisplayInfo()->GetDisplayId();
7708 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
7709 agent->NotifyAvailableAreaChanged(area, displayId);
7710 } else {
7711 isAgentTypeNotify = false;
7712 TLOGI(WmsLogTag::DMS, "Unknown agentType.");
7713 }
7714 }
7715 if (isAgentTypeNotify) {
7716 pidAgentTypeMap_[pid].erase(agentType);
7717 }
7718 }
7719 }
7720
NotifyUnfreezed(const std::set<int32_t> & unfreezedPidList,const sptr<ScreenSession> & screenSession)7721 void ScreenSessionManager::NotifyUnfreezed(const std::set<int32_t>& unfreezedPidList,
7722 const sptr<ScreenSession>& screenSession)
7723 {
7724 std::lock_guard<std::mutex> lock(freezedPidListMutex_);
7725 for (auto iter = pidAgentTypeMap_.begin(); iter != pidAgentTypeMap_.end();) {
7726 int32_t pid = iter->first;
7727 auto pidAgentTypes = iter->second;
7728 NotifyUnfreezedAgents(pid, unfreezedPidList, pidAgentTypes, screenSession);
7729 if (pidAgentTypeMap_[pid].empty()) {
7730 iter = pidAgentTypeMap_.erase(iter);
7731 } else {
7732 iter++;
7733 }
7734 }
7735 }
7736
ResetAllFreezeStatus()7737 DMError ScreenSessionManager::ResetAllFreezeStatus()
7738 {
7739 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7740 TLOGE(WmsLogTag::DMS, "permission denied!");
7741 return DMError::DM_ERROR_NOT_SYSTEM_APP;
7742 }
7743 std::lock_guard<std::mutex> lock(freezedPidListMutex_);
7744 freezedPidList_.clear();
7745 pidAgentTypeMap_.clear();
7746 TLOGI(WmsLogTag::DMS, "freezedPidList_ has been clear.");
7747 return DMError::DM_OK;
7748 }
7749
GetDeviceScreenConfig()7750 DeviceScreenConfig ScreenSessionManager::GetDeviceScreenConfig()
7751 {
7752 DmsXcollie dmsXcollie("DMS:GetDeviceScreenConfig", XCOLLIE_TIMEOUT_10S);
7753 return deviceScreenConfig_;
7754 }
7755
RegisterApplicationStateObserver()7756 void ScreenSessionManager::RegisterApplicationStateObserver()
7757 {
7758 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
7759 std::string identify = IPCSkeleton::ResetCallingIdentity();
7760 if (!FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7761 FoldScreenSensorManager::GetInstance().RegisterApplicationStateObserver();
7762 }
7763 IPCSkeleton::SetCallingIdentity(identify);
7764 #endif
7765 }
7766
SetVirtualScreenBlackList(ScreenId screenId,std::vector<uint64_t> & windowIdList,std::vector<uint64_t> surfaceIdList)7767 void ScreenSessionManager::SetVirtualScreenBlackList(ScreenId screenId, std::vector<uint64_t>& windowIdList,
7768 std::vector<uint64_t> surfaceIdList)
7769 {
7770 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7771 TLOGE(WmsLogTag::DMS, "permission denied!");
7772 return;
7773 }
7774 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64, screenId);
7775 ScreenId rsScreenId = SCREEN_ID_INVALID;
7776 if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
7777 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
7778 return;
7779 }
7780 if (windowIdList.empty()) {
7781 TLOGI(WmsLogTag::DMS, "WindowIdList is empty");
7782 rsInterface_.SetVirtualScreenBlackList(rsScreenId, surfaceIdList);
7783 return;
7784 }
7785 if (!clientProxy_) {
7786 TLOGE(WmsLogTag::DMS, "clientProxy_ is nullptr");
7787 return;
7788 }
7789 std::vector<uint64_t> surfaceNodeIdsToRS;
7790 clientProxy_->OnGetSurfaceNodeIdsFromMissionIdsChanged(windowIdList, surfaceNodeIdsToRS, true);
7791 if (!surfaceIdList.empty()) {
7792 for (auto surfaceId : surfaceIdList) {
7793 auto it = std::find(surfaceNodeIdsToRS.begin(), surfaceNodeIdsToRS.end(), surfaceId);
7794 if (it != surfaceNodeIdsToRS.end()) {
7795 continue;
7796 }
7797 surfaceNodeIdsToRS.push_back(surfaceId);
7798 }
7799 }
7800 std::ostringstream oss;
7801 oss << "surfaceNodeIdsToRS: ";
7802 for (auto val : surfaceNodeIdsToRS) {
7803 oss << val << " ";
7804 }
7805 TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
7806 rsInterface_.SetVirtualScreenBlackList(rsScreenId, surfaceNodeIdsToRS);
7807 }
7808
SetVirtualDisplayMuteFlag(ScreenId screenId,bool muteFlag)7809 void ScreenSessionManager::SetVirtualDisplayMuteFlag(ScreenId screenId, bool muteFlag)
7810 {
7811 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7812 TLOGE(WmsLogTag::DMS, "permission denied!");
7813 return;
7814 }
7815 sptr<ScreenSession> virtualScreenSession = GetScreenSession(screenId);
7816 if (!virtualScreenSession) {
7817 TLOGE(WmsLogTag::DMS, "ScreenSession is null");
7818 return;
7819 }
7820 std::shared_ptr<RSDisplayNode> virtualDisplayNode = virtualScreenSession->GetDisplayNode();
7821 if (virtualDisplayNode) {
7822 virtualDisplayNode->SetVirtualScreenMuteStatus(muteFlag);
7823 } else {
7824 TLOGE(WmsLogTag::DMS, "DisplayNode is null");
7825 return;
7826 }
7827 auto transactionProxy = RSTransactionProxy::GetInstance();
7828 if (transactionProxy != nullptr) {
7829 TLOGI(WmsLogTag::DMS, "flush displayNode mute");
7830 transactionProxy->FlushImplicitTransaction();
7831 }
7832 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " muteFlag: %{public}d", screenId, muteFlag);
7833 }
7834
DisablePowerOffRenderControl(ScreenId screenId)7835 void ScreenSessionManager::DisablePowerOffRenderControl(ScreenId screenId)
7836 {
7837 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7838 TLOGE(WmsLogTag::DMS, "permission denied!");
7839 return;
7840 }
7841 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64, screenId);
7842 ScreenId rsScreenId = SCREEN_ID_INVALID;
7843 if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
7844 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
7845 return;
7846 }
7847 rsInterface_.DisablePowerOffRenderControl(rsScreenId);
7848 }
7849
ReportFoldStatusToScb(std::vector<std::string> & screenFoldInfo)7850 void ScreenSessionManager::ReportFoldStatusToScb(std::vector<std::string>& screenFoldInfo)
7851 {
7852 if (clientProxy_) {
7853 auto screenInfo = GetDefaultScreenSession();
7854 int32_t rotation = -1;
7855 if (screenInfo != nullptr) {
7856 rotation = static_cast<int32_t>(screenInfo->GetRotation());
7857 }
7858 screenFoldInfo.emplace_back(std::to_string(rotation));
7859
7860 clientProxy_->OnFoldStatusChangedReportUE(screenFoldInfo);
7861 }
7862 }
7863
GetAllDisplayPhysicalResolution()7864 std::vector<DisplayPhysicalResolution> ScreenSessionManager::GetAllDisplayPhysicalResolution()
7865 {
7866 if (allDisplayPhysicalResolution_.empty()) {
7867 sptr<ScreenSession> defaultScreen = GetDefaultScreenSession();
7868 if (defaultScreen == nullptr) {
7869 TLOGE(WmsLogTag::DMS, "default screen null");
7870 return allDisplayPhysicalResolution_;
7871 }
7872 ScreenProperty defaultScreenProperty = defaultScreen->GetScreenProperty();
7873 DisplayPhysicalResolution defaultSize;
7874 defaultSize.foldDisplayMode_ = FoldDisplayMode::UNKNOWN;
7875 defaultSize.physicalWidth_ = defaultScreenProperty.GetPhyBounds().rect_.width_;
7876 defaultSize.physicalHeight_ = defaultScreenProperty.GetPhyBounds().rect_.height_;
7877 allDisplayPhysicalResolution_.emplace_back(defaultSize);
7878 }
7879 for (auto& info : allDisplayPhysicalResolution_) {
7880 if (info.foldDisplayMode_ == FoldDisplayMode::GLOBAL_FULL) {
7881 info.foldDisplayMode_ = FoldDisplayMode::FULL;
7882 break;
7883 }
7884 }
7885 return allDisplayPhysicalResolution_;
7886 }
7887
GetCapabilityJson(FoldStatus foldStatus,FoldDisplayMode displayMode,std::vector<std::string> rotation,std::vector<std::string> orientation)7888 nlohmann::ordered_json ScreenSessionManager::GetCapabilityJson(FoldStatus foldStatus, FoldDisplayMode displayMode,
7889 std::vector<std::string> rotation, std::vector<std::string> orientation)
7890 {
7891 nlohmann::ordered_json capabilityInfo;
7892 capabilityInfo["foldStatus"] = std::to_string(static_cast<int32_t>(foldStatus));
7893 capabilityInfo["foldDisplayMode"] = std::to_string(static_cast<int32_t>(displayMode));
7894 capabilityInfo["rotation"] = rotation;
7895 capabilityInfo["orientation"] = orientation;
7896 return capabilityInfo;
7897 }
7898
GetDisplayCapability(std::string & capabilitInfo)7899 DMError ScreenSessionManager::GetDisplayCapability(std::string& capabilitInfo)
7900 {
7901 if (g_foldScreenFlag) {
7902 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7903 return GetSecondaryDisplayCapability(capabilitInfo);
7904 }
7905 return GetFoldableDeviceCapability(capabilitInfo);
7906 }
7907 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7908 return GetSuperFoldCapability(capabilitInfo);
7909 }
7910
7911 std::vector<std::string> orientation = ORIENTATION_DEFAULT;
7912 if (g_isPcDevice && !FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7913 orientation = {"1", "0", "3", "2"};
7914 }
7915 nlohmann::ordered_json jsonDisplayCapabilityList;
7916 jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
7917 nlohmann::ordered_json capabilityInfo = GetCapabilityJson(FoldStatus::UNKNOWN, FoldDisplayMode::UNKNOWN,
7918 ROTATION_DEFAULT, orientation);
7919 jsonDisplayCapabilityList["capability"].push_back(std::move(capabilityInfo));
7920
7921 capabilitInfo = jsonDisplayCapabilityList.dump();
7922 return DMError::DM_OK;
7923 }
7924
GetSecondaryDisplayCapability(std::string & capabilitInfo)7925 DMError ScreenSessionManager::GetSecondaryDisplayCapability(std::string& capabilitInfo)
7926 {
7927 nlohmann::ordered_json jsonDisplayCapabilityList;
7928 jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
7929
7930 nlohmann::ordered_json fCapabilityInfo = GetCapabilityJson(FoldStatus::FOLDED, FoldDisplayMode::MAIN,
7931 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7932 jsonDisplayCapabilityList["capability"].push_back(std::move(fCapabilityInfo));
7933 nlohmann::ordered_json nCapability = GetCapabilityJson(FoldStatus::FOLD_STATE_FOLDED_WITH_SECOND_EXPAND,
7934 FoldDisplayMode::MAIN, ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7935 jsonDisplayCapabilityList["capability"].push_back(std::move(nCapability));
7936 nlohmann::ordered_json mCapabilityInfo = GetCapabilityJson(FoldStatus::EXPAND, FoldDisplayMode::FULL,
7937 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7938 jsonDisplayCapabilityList["capability"].push_back(std::move(mCapabilityInfo));
7939 std::vector<std::string> orientation = {"3", "0", "1", "2"};
7940 nlohmann::ordered_json gCapability = GetCapabilityJson(FoldStatus::FOLD_STATE_EXPAND_WITH_SECOND_EXPAND,
7941 FoldDisplayMode::FULL, ROTATION_DEFAULT, orientation);
7942 jsonDisplayCapabilityList["capability"].push_back(std::move(gCapability));
7943
7944 capabilitInfo = jsonDisplayCapabilityList.dump();
7945 return DMError::DM_OK;
7946 }
7947
GetFoldableDeviceCapability(std::string & capabilitInfo)7948 DMError ScreenSessionManager::GetFoldableDeviceCapability(std::string& capabilitInfo)
7949 {
7950 nlohmann::ordered_json jsonDisplayCapabilityList;
7951 jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
7952 FoldStatus expandStatus = FoldStatus::EXPAND;
7953 FoldStatus foldStatus = FoldStatus::FOLDED;
7954 FoldDisplayMode expandDisplayMode = FoldDisplayMode::FULL;
7955 FoldDisplayMode foldDisplayMode = FoldDisplayMode::MAIN;
7956 if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
7957 expandDisplayMode = FoldDisplayMode::MAIN;
7958 foldDisplayMode = FoldDisplayMode::SUB;
7959 }
7960 nlohmann::ordered_json expandCapabilityInfo = GetCapabilityJson(expandStatus, expandDisplayMode,
7961 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7962 jsonDisplayCapabilityList["capability"].push_back(std::move(expandCapabilityInfo));
7963 nlohmann::ordered_json foldCapabilityInfo = GetCapabilityJson(foldStatus, foldDisplayMode,
7964 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7965 jsonDisplayCapabilityList["capability"].push_back(std::move(foldCapabilityInfo));
7966
7967 capabilitInfo = jsonDisplayCapabilityList.dump();
7968 return DMError::DM_OK;
7969 }
7970
GetSuperFoldCapability(std::string & capabilitInfo)7971 DMError ScreenSessionManager::GetSuperFoldCapability(std::string& capabilitInfo)
7972 {
7973 nlohmann::ordered_json jsonDisplayCapabilityList;
7974 jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
7975
7976 nlohmann::ordered_json expandCapabilityInfo = GetCapabilityJson(FoldStatus::EXPAND, FoldDisplayMode::UNKNOWN,
7977 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7978 jsonDisplayCapabilityList["capability"].push_back(std::move(expandCapabilityInfo));
7979 nlohmann::ordered_json foldCapabilityInfo = GetCapabilityJson(FoldStatus::FOLDED, FoldDisplayMode::UNKNOWN,
7980 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7981 jsonDisplayCapabilityList["capability"].push_back(std::move(foldCapabilityInfo));
7982 nlohmann::ordered_json halfFoldCapabilityInfo = GetCapabilityJson(FoldStatus::HALF_FOLD, FoldDisplayMode::UNKNOWN,
7983 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
7984 jsonDisplayCapabilityList["capability"].push_back(std::move(halfFoldCapabilityInfo));
7985
7986 capabilitInfo = jsonDisplayCapabilityList.dump();
7987 return DMError::DM_OK;
7988 }
7989
SetVirtualScreenStatus(ScreenId screenId,VirtualScreenStatus screenStatus)7990 bool ScreenSessionManager::SetVirtualScreenStatus(ScreenId screenId, VirtualScreenStatus screenStatus)
7991 {
7992 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7993 TLOGE(WmsLogTag::DMS, "permission denied!");
7994 return false;
7995 }
7996 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 " screenStatus: %{public}d",
7997 screenId, static_cast<int32_t>(screenStatus));
7998 ScreenId rsScreenId = SCREEN_ID_INVALID;
7999 if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
8000 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
8001 return false;
8002 }
8003
8004 return rsInterface_.SetVirtualScreenStatus(rsScreenId, screenStatus);
8005 }
8006
GetOrCreateFakeScreenSession(sptr<ScreenSession> screenSession)8007 sptr<ScreenSession> ScreenSessionManager::GetOrCreateFakeScreenSession(sptr<ScreenSession> screenSession)
8008 {
8009 sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
8010 if (fakeScreenSession != nullptr) {
8011 TLOGI(WmsLogTag::DMS, "fake screen session has exist");
8012 return fakeScreenSession;
8013 }
8014 ScreenProperty screenProperty = screenSession->GetScreenProperty();
8015 ScreenSessionConfig config = {
8016 .screenId = SCREEN_ID_FAKE,
8017 .defaultScreenId = SCREEN_ID_INVALID,
8018 .property = screenProperty,
8019 };
8020 fakeScreenSession =
8021 new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
8022 if (fakeScreenSession == nullptr) {
8023 return nullptr;
8024 }
8025 return fakeScreenSession;
8026 }
8027
InitFakeScreenSession(sptr<ScreenSession> screenSession)8028 void ScreenSessionManager::InitFakeScreenSession(sptr<ScreenSession> screenSession)
8029 {
8030 if (screenSession == nullptr) {
8031 TLOGE(WmsLogTag::DMS, "screen session is null");
8032 return;
8033 }
8034 sptr<ScreenSession> fakeScreenSession = GetOrCreateFakeScreenSession(screenSession);
8035 if (fakeScreenSession == nullptr) {
8036 TLOGE(WmsLogTag::DMS, "get or create fake screen session failed");
8037 return;
8038 }
8039 ScreenProperty screenProperty = screenSession->GetScreenProperty();
8040 uint32_t screenWidth = screenProperty.GetBounds().rect_.GetWidth();
8041 uint32_t screenHeight = screenProperty.GetBounds().rect_.GetHeight();
8042 uint32_t fakeScreenHeight = screenHeight / HALF_SCREEN_PARAM;
8043 DMRect creaseRect = screenProperty.GetCreaseRect();
8044 if (creaseRect.height_ > 0) {
8045 fakeScreenHeight = screenHeight - (static_cast<uint32_t>(creaseRect.posY_) + creaseRect.height_);
8046 }
8047 fakeScreenSession->UpdatePropertyByResolution(screenWidth, fakeScreenHeight);
8048 fakeScreenSession->SetXYPosition(0, DISPLAY_B_HEIGHT);
8049 fakeScreenSession->SetScreenCombination(ScreenCombination::SCREEN_EXTEND);
8050 screenSession->UpdatePropertyByFakeBounds(screenWidth, fakeScreenHeight);
8051 screenSession->SetFakeScreenSession(fakeScreenSession);
8052 screenSession->SetIsFakeInUse(true);
8053 }
8054
SetVirtualScreenSecurityExemption(ScreenId screenId,uint32_t pid,std::vector<uint64_t> & windowIdList)8055 DMError ScreenSessionManager::SetVirtualScreenSecurityExemption(ScreenId screenId, uint32_t pid,
8056 std::vector<uint64_t>& windowIdList)
8057 {
8058 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8059 TLOGE(WmsLogTag::DMS, "permission denied!");
8060 return DMError::DM_ERROR_INVALID_CALLING;
8061 }
8062 std::vector<uint64_t> surfaceNodeIds;
8063 if (!windowIdList.empty()) {
8064 MockSessionManagerService::GetInstance().GetProcessSurfaceNodeIdByPersistentId(
8065 pid, windowIdList, surfaceNodeIds);
8066 }
8067 auto rsId = screenIdManager_.ConvertToRsScreenId(screenId);
8068 auto ret = rsInterface_.SetVirtualScreenSecurityExemptionList(rsId, surfaceNodeIds);
8069
8070 std::ostringstream oss;
8071 oss << "screenId:" << screenId << ", rsID: " << rsId << ", pid: " << pid
8072 << ", winListSize:[ ";
8073 for (auto val : windowIdList) {
8074 oss << val << " ";
8075 }
8076 oss << "]" << ", surfaceListSize:[ ";
8077 for (auto val : surfaceNodeIds) {
8078 oss << val << " ";
8079 }
8080 oss << "]" << ", ret: " << ret;
8081 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
8082 return ret == 0 ? DMError::DM_OK : DMError::DM_ERROR_UNKNOWN;
8083 }
8084
SetDefaultScreenId(ScreenId defaultScreenId)8085 void ScreenSessionManager::SetDefaultScreenId(ScreenId defaultScreenId)
8086 {
8087 defaultScreenId_ = defaultScreenId;
8088 }
8089
GetClientProxy()8090 sptr<IScreenSessionManagerClient> ScreenSessionManager::GetClientProxy()
8091 {
8092 return clientProxy_;
8093 }
8094
SetMultiScreenMode(ScreenId mainScreenId,ScreenId secondaryScreenId,MultiScreenMode screenMode)8095 DMError ScreenSessionManager::SetMultiScreenMode(ScreenId mainScreenId, ScreenId secondaryScreenId,
8096 MultiScreenMode screenMode)
8097 {
8098 #ifdef WM_MULTI_SCREEN_ENABLE
8099 TLOGW(WmsLogTag::DMS, "mainScreenId:%{public}" PRIu64",secondaryScreenId:%{public}" PRIu64",Mode:%{public}u",
8100 mainScreenId, secondaryScreenId, screenMode);
8101 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8102 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
8103 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8104 return DMError::DM_ERROR_NOT_SYSTEM_APP;
8105 }
8106 if (screenMode == MultiScreenMode::SCREEN_MIRROR) {
8107 MultiScreenModeChange(mainScreenId, secondaryScreenId, "mirror");
8108 SetExtendedScreenFallbackPlan(secondaryScreenId);
8109 sptr<ScreenSession> screenSession = GetScreenSession(secondaryScreenId);
8110 if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
8111 MultiScreenPositionOptions defaultOptions = { GetDefaultScreenId(), 0, 0 };
8112 SetRelativePositionForDisconnect(defaultOptions);
8113 NotifyCaptureStatusChanged(true);
8114 }
8115 } else if (screenMode == MultiScreenMode::SCREEN_EXTEND) {
8116 bool lastScreenMirror = false;
8117 sptr<ScreenSession> screenSession = GetScreenSession(secondaryScreenId);
8118 if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
8119 lastScreenMirror = true;
8120 }
8121 MultiScreenModeChange(mainScreenId, secondaryScreenId, "extend");
8122 SetExtendedScreenFallbackPlan(secondaryScreenId);
8123 if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND &&
8124 lastScreenMirror) {
8125 NotifyCaptureStatusChanged(false);
8126 }
8127 } else {
8128 TLOGE(WmsLogTag::DMS, "operate mode error");
8129 }
8130 NotifyScreenModeChange();
8131 #endif
8132 return DMError::DM_OK;
8133 }
8134
SetMultiScreenRelativePosition(MultiScreenPositionOptions mainScreenOptions,MultiScreenPositionOptions secondScreenOption)8135 DMError ScreenSessionManager::SetMultiScreenRelativePosition(MultiScreenPositionOptions mainScreenOptions,
8136 MultiScreenPositionOptions secondScreenOption)
8137 {
8138 #ifdef WM_MULTI_SCREEN_ENABLE
8139 TLOGI(WmsLogTag::DMS,
8140 "mID:%{public}" PRIu64", X:%{public}u, Y:%{public}u,sID:%{public}" PRIu64", X:%{public}u, Y:%{public}u",
8141 mainScreenOptions.screenId_, mainScreenOptions.startX_, mainScreenOptions.startY_,
8142 secondScreenOption.screenId_, secondScreenOption.startX_, secondScreenOption.startY_);
8143 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8144 TLOGE(WmsLogTag::DMS, "permission denied! clientName: %{public}s, pid: %{public}d",
8145 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8146 return DMError::DM_ERROR_NOT_SYSTEM_APP;
8147 }
8148 sptr<ScreenSession> firstScreenSession = GetScreenSession(mainScreenOptions.screenId_);
8149 sptr<ScreenSession> secondScreenSession = GetScreenSession(secondScreenOption.screenId_);
8150 if (!firstScreenSession || !secondScreenSession) {
8151 TLOGE(WmsLogTag::DMS, "ScreenSession is null");
8152 return DMError::DM_ERROR_NULLPTR;
8153 }
8154 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
8155 !MultiScreenManager::GetInstance().AreScreensTouching(firstScreenSession, secondScreenSession,
8156 mainScreenOptions, secondScreenOption)) {
8157 TLOGE(WmsLogTag::DMS, "Options incorrect!");
8158 return DMError::DM_ERROR_INVALID_PARAM;
8159 }
8160 firstScreenSession->SetStartPosition(mainScreenOptions.startX_, mainScreenOptions.startY_);
8161 CalculateXYPosition(firstScreenSession);
8162 firstScreenSession->PropertyChange(firstScreenSession->GetScreenProperty(),
8163 ScreenPropertyChangeReason::RELATIVE_POSITION_CHANGE);
8164 secondScreenSession->SetStartPosition(secondScreenOption.startX_, secondScreenOption.startY_);
8165 CalculateXYPosition(secondScreenSession);
8166 secondScreenSession->PropertyChange(secondScreenSession->GetScreenProperty(),
8167 ScreenPropertyChangeReason::RELATIVE_POSITION_CHANGE);
8168 std::shared_ptr<RSDisplayNode> firstDisplayNode = firstScreenSession->GetDisplayNode();
8169 std::shared_ptr<RSDisplayNode> secondDisplayNode = secondScreenSession->GetDisplayNode();
8170 if (firstDisplayNode && secondDisplayNode) {
8171 firstDisplayNode->SetDisplayOffset(mainScreenOptions.startX_, mainScreenOptions.startY_);
8172 secondDisplayNode->SetDisplayOffset(secondScreenOption.startX_, secondScreenOption.startY_);
8173 } else {
8174 TLOGW(WmsLogTag::DMS, "DisplayNode is null");
8175 }
8176 auto transactionProxy = RSTransactionProxy::GetInstance();
8177 if (transactionProxy != nullptr) {
8178 TLOGI(WmsLogTag::DMS, "free displayNode");
8179 transactionProxy->FlushImplicitTransaction();
8180 }
8181 #endif
8182 return DMError::DM_OK;
8183 }
8184
SetRelativePositionForDisconnect(MultiScreenPositionOptions defaultScreenOptions)8185 void ScreenSessionManager::SetRelativePositionForDisconnect(MultiScreenPositionOptions defaultScreenOptions)
8186 {
8187 #ifdef WM_MULTI_SCREEN_ENABLE
8188 TLOGI(WmsLogTag::DMS, "mID:%{public}" PRIu64", X:%{public}u, Y:%{public}u",
8189 defaultScreenOptions.screenId_, defaultScreenOptions.startX_, defaultScreenOptions.startY_);
8190 sptr<ScreenSession> defaultScreenSession = GetScreenSession(defaultScreenOptions.screenId_);
8191 if (!defaultScreenSession) {
8192 TLOGE(WmsLogTag::DMS, "ScreenSession is null");
8193 return;
8194 }
8195 defaultScreenSession->SetStartPosition(defaultScreenOptions.startX_, defaultScreenOptions.startY_);
8196 CalculateXYPosition(defaultScreenSession);
8197 defaultScreenSession->PropertyChange(defaultScreenSession->GetScreenProperty(),
8198 ScreenPropertyChangeReason::RELATIVE_POSITION_CHANGE);
8199 std::shared_ptr<RSDisplayNode> defaultDisplayNode = defaultScreenSession->GetDisplayNode();
8200 if (defaultDisplayNode) {
8201 defaultDisplayNode->SetDisplayOffset(defaultScreenOptions.startX_, defaultScreenOptions.startY_);
8202 } else {
8203 TLOGW(WmsLogTag::DMS, "DisplayNode is null");
8204 }
8205 auto transactionProxy = RSTransactionProxy::GetInstance();
8206 if (transactionProxy != nullptr) {
8207 TLOGI(WmsLogTag::DMS, "free displayNode");
8208 transactionProxy->FlushImplicitTransaction();
8209 }
8210 #endif
8211 }
8212
MultiScreenModeChange(ScreenId mainScreenId,ScreenId secondaryScreenId,const std::string & operateMode)8213 void ScreenSessionManager::MultiScreenModeChange(ScreenId mainScreenId, ScreenId secondaryScreenId,
8214 const std::string& operateMode)
8215 {
8216 #ifdef WM_MULTI_SCREEN_ENABLE
8217 TLOGW(WmsLogTag::DMS, "mainId=%{public}" PRIu64" secondId=%{public}" PRIu64" operateType: %{public}s",
8218 mainScreenId, secondaryScreenId, operateMode.c_str());
8219 sptr<ScreenSession> firstSession = nullptr;
8220 sptr<ScreenSession> secondarySession = nullptr;
8221 {
8222 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8223 for (auto sessionIt : screenSessionMap_) {
8224 auto screenSession = sessionIt.second;
8225 if (screenSession == nullptr) {
8226 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
8227 continue;
8228 }
8229 if (!screenSession->GetIsCurrentInUse()) {
8230 TLOGE(WmsLogTag::DMS, "current screen: %{public}" PRIu64" is not in user!", sessionIt.first);
8231 continue;
8232 }
8233 if (sessionIt.first == mainScreenId) {
8234 firstSession = screenSession;
8235 }
8236 if (sessionIt.first == secondaryScreenId) {
8237 secondarySession = screenSession;
8238 }
8239 }
8240 }
8241
8242 if (firstSession != nullptr && secondarySession != nullptr) {
8243 ScreenCombination firstCombination = firstSession->GetScreenCombination();
8244 ScreenCombination secondaryCombination = secondarySession->GetScreenCombination();
8245 MultiScreenManager::GetInstance().MultiScreenModeChange(firstSession, secondarySession, operateMode);
8246 if ((firstCombination == ScreenCombination::SCREEN_MIRROR ||
8247 secondaryCombination == ScreenCombination::SCREEN_MIRROR) &&
8248 operateMode == SCREEN_EXTEND) {
8249 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_MIRROR, MULTI_SCREEN_EXIT_STR);
8250 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_ENTER_STR);
8251 } else if ((firstCombination == ScreenCombination::SCREEN_EXTEND ||
8252 secondaryCombination == ScreenCombination::SCREEN_EXTEND) &&
8253 operateMode == SCREEN_MIRROR) {
8254 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_EXIT_STR);
8255 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_MIRROR, MULTI_SCREEN_ENTER_STR);
8256 }
8257 } else {
8258 TLOGE(WmsLogTag::DMS, "params error");
8259 }
8260 #endif
8261 }
8262
SwitchScrollParam(FoldDisplayMode displayMode)8263 void ScreenSessionManager::SwitchScrollParam(FoldDisplayMode displayMode)
8264 {
8265 auto task = [=]() {
8266 std::map<FoldDisplayMode, ScrollableParam> scrollableParams = ScreenSceneConfig::GetAllScrollableParam();
8267 std::string scrollVelocityScale = scrollableParams.count(displayMode) != 0 ?
8268 scrollableParams[displayMode].velocityScale_ : "0";
8269 std::string scrollFriction = scrollableParams.count(displayMode) != 0 ?
8270 scrollableParams[displayMode].friction_ : "0";
8271 system::SetParameter("persist.scrollable.velocityScale", scrollVelocityScale);
8272 system::SetParameter("persist.scrollable.friction", scrollFriction);
8273 };
8274 taskScheduler_->PostAsyncTask(task, "SwitchScrollParam");
8275 }
8276
MultiScreenModeChange(const std::string & firstScreenIdStr,const std::string & secondaryScreenIdStr,const std::string & secondaryChandeMode)8277 void ScreenSessionManager::MultiScreenModeChange(const std::string& firstScreenIdStr,
8278 const std::string& secondaryScreenIdStr, const std::string& secondaryChandeMode)
8279 {
8280 #ifdef WM_MULTI_SCREEN_ENABLE
8281 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8282 TLOGE(WmsLogTag::DMS, "permission denied! clientName: %{public}s, pid: %{public}d",
8283 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8284 return;
8285 }
8286 ScreenId firstScreenId = static_cast<ScreenId>(std::stoi(firstScreenIdStr));
8287 ScreenId secondaryScreenId = static_cast<ScreenId>(std::stoi(secondaryScreenIdStr));
8288 if (secondaryChandeMode == "mirror" || secondaryChandeMode == "extend") {
8289 MultiScreenModeChange(firstScreenId, secondaryScreenId, secondaryChandeMode);
8290 } else {
8291 TLOGE(WmsLogTag::DMS, "dumper params error");
8292 }
8293 #endif
8294 }
8295
OnScreenExtendChange(ScreenId mainScreenId,ScreenId extendScreenId)8296 void ScreenSessionManager::OnScreenExtendChange(ScreenId mainScreenId, ScreenId extendScreenId)
8297 {
8298 if (!clientProxy_) {
8299 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8300 return;
8301 }
8302 clientProxy_->OnScreenExtendChanged(mainScreenId, extendScreenId);
8303 }
8304
OnTentModeChanged(int tentType,int32_t hall)8305 void ScreenSessionManager::OnTentModeChanged(int tentType, int32_t hall)
8306 {
8307 #ifdef FOLD_ABILITY_ENABLE
8308 if (!foldScreenController_) {
8309 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
8310 return;
8311 }
8312 foldScreenController_->OnTentModeChanged(tentType, hall);
8313 #endif
8314 }
8315
SetCoordinationFlag(bool isCoordinationFlag)8316 void ScreenSessionManager::SetCoordinationFlag(bool isCoordinationFlag)
8317 {
8318 TLOGI(WmsLogTag::DMS, "set coordination flag %{public}d", isCoordinationFlag);
8319 isCoordinationFlag_ = isCoordinationFlag;
8320 }
8321
SetVirtualScreenMaxRefreshRate(ScreenId id,uint32_t refreshRate,uint32_t & actualRefreshRate)8322 DMError ScreenSessionManager::SetVirtualScreenMaxRefreshRate(ScreenId id, uint32_t refreshRate,
8323 uint32_t& actualRefreshRate)
8324 {
8325 if (!SessionPermission::IsSystemCalling()) {
8326 TLOGE(WmsLogTag::DMS, "permission denied! clientName: %{public}s, pid: %{public}d",
8327 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8328 return DMError::DM_ERROR_NOT_SYSTEM_APP;
8329 }
8330 TLOGI(WmsLogTag::DMS, "ID:%{public}" PRIu64", refreshRate:%{public}u, actualRefreshRate:%{public}u",
8331 id, refreshRate, actualRefreshRate);
8332 if (id == GetDefaultScreenId()) {
8333 TLOGE(WmsLogTag::DMS, "cannot set refresh main screen id: %{public}" PRIu64".", GetDefaultScreenId());
8334 return DMError::DM_ERROR_INVALID_PARAM;
8335 }
8336 auto screenSession = GetScreenSession(id);
8337 if (screenSession == nullptr) {
8338 TLOGE(WmsLogTag::DMS, "screenSession is null.");
8339 return DMError::DM_ERROR_INVALID_PARAM;
8340 }
8341 ScreenId rsScreenId;
8342 if (!screenIdManager_.ConvertToRsScreenId(id, rsScreenId)) {
8343 TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
8344 return DMError::DM_ERROR_INVALID_PARAM;
8345 }
8346 int32_t res = rsInterface_.SetVirtualScreenRefreshRate(rsScreenId, refreshRate, actualRefreshRate);
8347 TLOGI(WmsLogTag::DMS, "refreshRate:%{public}u, actualRefreshRate:%{public}u", refreshRate, actualRefreshRate);
8348 if (res != StatusCode::SUCCESS) {
8349 TLOGE(WmsLogTag::DMS, "rsInterface error: %{public}d", res);
8350 return DMError::DM_ERROR_INVALID_PARAM;
8351 }
8352 screenSession->UpdateRefreshRate(actualRefreshRate);
8353 return DMError::DM_OK;
8354 }
8355
OnScreenCaptureNotify(ScreenId mainScreenId,int32_t uid,const std::string & clientName)8356 void ScreenSessionManager::OnScreenCaptureNotify(ScreenId mainScreenId, int32_t uid, const std::string& clientName)
8357 {
8358 if (!clientProxy_) {
8359 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8360 return;
8361 }
8362 clientProxy_->ScreenCaptureNotify(mainScreenId, uid, clientName);
8363 }
8364
AddPermissionUsedRecord(const std::string & permission,int32_t successCount,int32_t failCount)8365 void ScreenSessionManager::AddPermissionUsedRecord(const std::string& permission, int32_t successCount,
8366 int32_t failCount)
8367 {
8368 int32_t ret = Security::AccessToken::PrivacyKit::AddPermissionUsedRecord(IPCSkeleton::GetCallingTokenID(),
8369 permission, successCount, failCount);
8370 if (ret != 0) {
8371 TLOGW(WmsLogTag::DMS, "permission:%{public}s, successCount %{public}d, failedCount %{public}d",
8372 permission.c_str(), successCount, failCount);
8373 }
8374 }
8375
GetScreenCapture(const CaptureOption & captureOption,DmErrorCode * errorCode)8376 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetScreenCapture(const CaptureOption& captureOption,
8377 DmErrorCode* errorCode)
8378 {
8379 TLOGI(WmsLogTag::DMS, "enter!");
8380 if (errorCode == nullptr) {
8381 TLOGE(WmsLogTag::DMS, "param is null.");
8382 return nullptr;
8383 }
8384 if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
8385 TLOGW(WmsLogTag::DMS, "capture disabled by edm!");
8386 *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
8387 return nullptr;
8388 }
8389 if (!ScreenSceneConfig::IsSupportCapture()) {
8390 TLOGW(WmsLogTag::DMS, "device not support capture.");
8391 *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
8392 return nullptr;
8393 }
8394 if (!Permission::CheckCallingPermission(CUSTOM_SCREEN_CAPTURE_PERMISSION) && !SessionPermission::IsShellCall()) {
8395 TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d.",
8396 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingRealPid());
8397 *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
8398 return nullptr;
8399 }
8400 if (captureOption.displayId_ == DISPLAY_ID_INVALID ||
8401 (captureOption.displayId_ == DISPLAY_ID_FAKE && !IsFakeDisplayExist())) {
8402 TLOGE(WmsLogTag::DMS, "display id invalid.");
8403 *errorCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
8404 return nullptr;
8405 }
8406 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetScreenCapture(%" PRIu64")", captureOption.displayId_);
8407 auto res = GetScreenSnapshot(captureOption.displayId_, false);
8408 AddPermissionUsedRecord(CUSTOM_SCREEN_CAPTURE_PERMISSION,
8409 static_cast<int32_t>(res != nullptr), static_cast<int32_t>(res == nullptr));
8410 if (res == nullptr) {
8411 TLOGE(WmsLogTag::DMS, "get capture null.");
8412 *errorCode = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
8413 return nullptr;
8414 }
8415 NotifyScreenshot(captureOption.displayId_);
8416 if (SessionPermission::IsBetaVersion()) {
8417 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
8418 }
8419 *errorCode = DmErrorCode::DM_OK;
8420 isScreenShot_ = true;
8421 /* notify scb to do toast */
8422 OnScreenCaptureNotify(GetDefaultScreenId(), IPCSkeleton::GetCallingUid(), SysCapUtil::GetClientName());
8423 /* notify application capture happend */
8424 NotifyCaptureStatusChanged();
8425 return res;
8426 }
8427
GetPrimaryDisplayInfo()8428 sptr<DisplayInfo> ScreenSessionManager::GetPrimaryDisplayInfo()
8429 {
8430 sptr<ScreenSession> screenSession = nullptr;
8431 {
8432 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8433 for (auto sessionIt : screenSessionMap_) {
8434 screenSession = sessionIt.second;
8435 if (screenSession == nullptr) {
8436 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
8437 continue;
8438 }
8439 if (!screenSession->GetIsExtend()) {
8440 TLOGE(WmsLogTag::DMS, "find primary %{public}" PRIu64, screenSession->screenId_);
8441 break;
8442 }
8443 }
8444 }
8445 if (screenSession == nullptr) {
8446 TLOGW(WmsLogTag::DMS, "get extend screen faild use default!");
8447 screenSession = GetScreenSession(GetDefaultScreenId());
8448 }
8449 if (screenSession) {
8450 std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
8451 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
8452 if (displayInfo == nullptr) {
8453 TLOGI(WmsLogTag::DMS, "convert display error.");
8454 return nullptr;
8455 }
8456 displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
8457 return displayInfo;
8458 } else {
8459 TLOGE(WmsLogTag::DMS, "failed");
8460 return nullptr;
8461 }
8462 }
8463
OnSuperFoldStatusChange(ScreenId screenId,SuperFoldStatus superFoldStatus)8464 void ScreenSessionManager::OnSuperFoldStatusChange(ScreenId screenId, SuperFoldStatus superFoldStatus)
8465 {
8466 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", superFoldStatus: %{public}d", screenId,
8467 static_cast<uint32_t>(superFoldStatus));
8468 if (!clientProxy_) {
8469 TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
8470 return;
8471 }
8472 clientProxy_->OnSuperFoldStatusChanged(screenId, superFoldStatus);
8473 }
8474
OnExtendScreenConnectStatusChange(ScreenId screenId,ExtendScreenConnectStatus extendScreenConnectStatus)8475 void ScreenSessionManager::OnExtendScreenConnectStatusChange(ScreenId screenId,
8476 ExtendScreenConnectStatus extendScreenConnectStatus)
8477 {
8478 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", extendScreenConnectStatus: %{public}d", screenId,
8479 static_cast<uint32_t>(extendScreenConnectStatus));
8480 if (!clientProxy_) {
8481 TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
8482 return;
8483 }
8484 clientProxy_->OnExtendScreenConnectStatusChanged(screenId, extendScreenConnectStatus);
8485 }
8486
OnSecondaryReflexionChange(ScreenId screenId,bool isSecondaryReflexion)8487 void ScreenSessionManager::OnSecondaryReflexionChange(ScreenId screenId, bool isSecondaryReflexion)
8488 {
8489 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", isSecondaryReflexion: %{public}d", screenId,
8490 isSecondaryReflexion);
8491 if (!clientProxy_) {
8492 TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
8493 return;
8494 }
8495 clientProxy_->OnSecondaryReflexionChanged(screenId, isSecondaryReflexion);
8496 }
8497
GetCameraStatus()8498 int32_t ScreenSessionManager::GetCameraStatus()
8499 {
8500 return cameraStatus_;
8501 }
8502
GetCameraPosition()8503 int32_t ScreenSessionManager::GetCameraPosition()
8504 {
8505 return cameraPosition_;
8506 }
8507
IsScreenCasting()8508 bool ScreenSessionManager::IsScreenCasting()
8509 {
8510 if (virtualScreenCount_ > 0 || hdmiScreenCount_ > 0) {
8511 TLOGI(WmsLogTag::DMS, "virtualScreenCount_: %{public}" PRIu32 ", hdmiScreenCount_: %{public}d",
8512 virtualScreenCount_, hdmiScreenCount_);
8513 return true;
8514 }
8515 TLOGI(WmsLogTag::DMS, "not casting");
8516 return false;
8517 }
8518
SetMultiScreenOuterMode(sptr<ScreenSession> & innerSession,sptr<ScreenSession> & outerSession)8519 void ScreenSessionManager::SetMultiScreenOuterMode(sptr<ScreenSession>& innerSession,
8520 sptr<ScreenSession>& outerSession)
8521 {
8522 #ifdef WM_MULTI_SCREEN_ENABLE
8523 std::string screenMode = "";
8524 if (clientProxy_ == nullptr) {
8525 TLOGE(WmsLogTag::DMS, "client proxy is null.");
8526 return;
8527 }
8528 TLOGI(WmsLogTag::DMS, "switch outer start");
8529 ScreenCombination outerCombination = outerSession->GetScreenCombination();
8530 if (outerCombination != ScreenCombination::SCREEN_MIRROR && outerCombination != ScreenCombination::SCREEN_EXTEND) {
8531 TLOGE(WmsLogTag::DMS, "outer mode error.");
8532 return;
8533 }
8534 screenMode = outerCombination == ScreenCombination::SCREEN_MIRROR ? SCREEN_MIRROR : SCREEN_EXTEND;
8535 MultiScreenManager::GetInstance().MultiScreenModeChange(outerSession, innerSession, screenMode);
8536 clientProxy_->OnScreenConnectionChanged(GetSessionOption(innerSession), ScreenEvent::DISCONNECTED);
8537 {
8538 std::shared_ptr<RSDisplayNode> displayNode = innerSession->GetDisplayNode();
8539 if (displayNode != nullptr) {
8540 displayNode->RemoveFromTree();
8541 innerSession->ReleaseDisplayNode();
8542 }
8543 displayNode = nullptr;
8544 }
8545 auto transactionProxy = RSTransactionProxy::GetInstance();
8546 if (transactionProxy != nullptr) {
8547 TLOGI(WmsLogTag::DMS, "free displayNode");
8548 transactionProxy->FlushImplicitTransaction();
8549 }
8550 ScreenSettingHelper::SetSettingValue("only_second_screen_info", screenMode);
8551 CallRsSetScreenPowerStatusSync(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
8552 TLOGI(WmsLogTag::DMS, "switch out end.");
8553 #endif
8554 }
8555
RecoveryMultiScreenNormalMode(sptr<ScreenSession> & innerSession,sptr<ScreenSession> & outerSession)8556 void ScreenSessionManager::RecoveryMultiScreenNormalMode(sptr<ScreenSession>& innerSession,
8557 sptr<ScreenSession>& outerSession)
8558 {
8559 #ifdef WM_MULTI_SCREEN_ENABLE
8560 std::string screenMode = "";
8561 TLOGI(WmsLogTag::DMS, "recovery normal mode.");
8562 ScreenSettingHelper::GetSettingValue("only_second_screen_info", screenMode);
8563 if (clientProxy_ == nullptr || screenMode == "") {
8564 TLOGE(WmsLogTag::DMS, "client proxy is null.");
8565 return;
8566 }
8567 Rosen::RSDisplayNodeConfig rsConfig;
8568 rsConfig = {.screenId = innerSession->GetScreenId()};
8569 innerSession->CreateDisplayNode(rsConfig);
8570 innerSession->SetIsExtend(false);
8571 outerSession->SetIsExtend(true);
8572 CallRsSetScreenPowerStatusSync(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
8573 clientProxy_->OnScreenConnectionChanged(GetSessionOption(outerSession), ScreenEvent::DISCONNECTED);
8574 int64_t timeStamp = 50; // wait notify
8575 std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
8576 if (screenMode == SCREEN_MIRROR) {
8577 NodeId nodeId = innerSession->GetDisplayNode()->GetId();
8578 rsConfig = {.screenId = outerSession->GetScreenId(), .isMirrored = true, .mirrorNodeId = nodeId};
8579 outerSession->CreateDisplayNode(rsConfig);
8580 outerSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
8581 } else if (screenMode == SCREEN_EXTEND) {
8582 rsConfig = {.screenId = outerSession->GetScreenId()};
8583 outerSession->CreateDisplayNode(rsConfig);
8584 outerSession->SetScreenCombination(ScreenCombination::SCREEN_EXTEND);
8585 }
8586 innerSession->SetScreenCombination(ScreenCombination::SCREEN_MAIN);
8587 clientProxy_->OnScreenConnectionChanged(GetSessionOption(innerSession), ScreenEvent::CONNECTED);
8588 std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
8589 if (screenMode == SCREEN_EXTEND) {
8590 clientProxy_->OnScreenConnectionChanged(GetSessionOption(outerSession), ScreenEvent::CONNECTED);
8591 }
8592 ScreenSettingHelper::SetSettingValue("only_second_screen_info", "");
8593 TLOGI(WmsLogTag::DMS, "recovery normal mode end.");
8594 #endif
8595 }
8596
GetSessionOption(sptr<ScreenSession> screenSession)8597 SessionOption ScreenSessionManager::GetSessionOption(sptr<ScreenSession> screenSession)
8598 {
8599 SessionOption option = {
8600 .rsId_ = screenSession->GetRSScreenId(),
8601 .name_ = screenSession->GetName(),
8602 .isExtend_ = screenSession->GetIsExtend(),
8603 .innerName_ = screenSession->GetInnerName(),
8604 .screenId_ = screenSession->GetScreenId(),
8605 };
8606 return option;
8607 }
8608
GetSessionOption(sptr<ScreenSession> screenSession,ScreenId screenId)8609 SessionOption ScreenSessionManager::GetSessionOption(sptr<ScreenSession> screenSession, ScreenId screenId)
8610 {
8611 SessionOption option = {
8612 .rsId_ = screenSession->GetRSScreenId(),
8613 .name_ = screenSession->GetName(),
8614 .isExtend_ = screenSession->GetIsExtend(),
8615 .innerName_ = screenSession->GetInnerName(),
8616 .screenId_ = screenId,
8617 };
8618 return option;
8619 }
8620
MultiScreenChangeOuter(const std::string & outerFlag)8621 void ScreenSessionManager::MultiScreenChangeOuter(const std::string& outerFlag)
8622 {
8623 #ifdef WM_MULTI_SCREEN_ENABLE
8624 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8625 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
8626 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8627 return;
8628 }
8629 if (!clientProxy_ || (outerFlag != "1" && outerFlag != "0")) {
8630 TLOGE(WmsLogTag::DMS, "change params error.");
8631 return;
8632 }
8633 sptr<ScreenSession> innerSession = nullptr;
8634 sptr<ScreenSession> outerSession = nullptr;
8635 {
8636 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8637 for (auto sessionIt : screenSessionMap_) {
8638 auto screenSession = sessionIt.second;
8639 if (screenSession == nullptr) {
8640 TLOGE(WmsLogTag::DMS, "screenSession is nullptr.");
8641 continue;
8642 }
8643 if (!screenSession->GetIsCurrentInUse()) {
8644 continue;
8645 }
8646 if (screenSession->GetIsInternal()) {
8647 innerSession = screenSession;
8648 } else {
8649 outerSession = screenSession;
8650 }
8651 }
8652 }
8653 if (innerSession == nullptr || outerSession == nullptr) {
8654 TLOGE(WmsLogTag::DMS, "innerSession or outerSession is nullptr.");
8655 return;
8656 }
8657 if (outerFlag == "1") {
8658 SetMultiScreenOuterMode(innerSession, outerSession);
8659 } else {
8660 RecoveryMultiScreenNormalMode(innerSession, outerSession);
8661 }
8662 FixPowerStatus();
8663 #endif
8664 }
8665
SetScreenSkipProtectedWindow(const std::vector<ScreenId> & screenIds,bool isEnable)8666 DMError ScreenSessionManager::SetScreenSkipProtectedWindow(const std::vector<ScreenId>& screenIds, bool isEnable)
8667 {
8668 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8669 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
8670 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8671 return DMError::DM_ERROR_NOT_SYSTEM_APP;
8672 }
8673 std::ostringstream oss;
8674 for (ScreenId screenId : screenIds) {
8675 oss << screenId << " ";
8676 }
8677 TLOGI(WmsLogTag::DMS, "screenIds:%{public}s, isEnable:%{public}d", oss.str().c_str(), isEnable);
8678 {
8679 std::lock_guard<std::mutex> lock(shareProtectMutex_);
8680 for (ScreenId screenId : screenIds) {
8681 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
8682 if (screenSession == nullptr) {
8683 continue;
8684 }
8685 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
8686 screenSession->SetShareProtect(isEnable);
8687 }
8688 }
8689 }
8690 SetScreenSkipProtectedWindowInner();
8691 return DMError::DM_OK;
8692 }
8693
SetScreenSkipProtectedWindowInner()8694 void ScreenSessionManager::SetScreenSkipProtectedWindowInner()
8695 {
8696 TLOGI(WmsLogTag::DMS, "enter");
8697 bool screenSkipProtectedWindowValue = false;
8698 bool ret = ScreenSettingHelper::GetSettingscreenSkipProtectedWindow(screenSkipProtectedWindowValue);
8699 if (!ret) {
8700 TLOGE(WmsLogTag::DMS, "get setting failed, default value false");
8701 }
8702 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8703 for (auto sessionIt : screenSessionMap_) {
8704 auto screenSession = sessionIt.second;
8705 if (screenSession == nullptr) {
8706 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, ScreenId:%{public}" PRIu64"",
8707 sessionIt.first);
8708 continue;
8709 }
8710 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
8711 ScreenId rsScreenId;
8712 if (!screenIdManager_.ConvertToRsScreenId(screenSession->GetScreenId(), rsScreenId)) {
8713 TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
8714 continue;
8715 }
8716 bool requiredSkipWindow = screenSession->GetShareProtect() && screenSkipProtectedWindowValue;
8717 TLOGI(WmsLogTag::DMS, "virtualScreenId:%{public}" PRIu64 " requiredSkipWindow:%{public}d",
8718 sessionIt.first, requiredSkipWindow);
8719 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
8720 "SetCastScreenEnableSkipWindow(%" PRIu64")", sessionIt.first);
8721 rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, requiredSkipWindow);
8722 }
8723 }
8724 }
8725
IsOrientationNeedChanged()8726 bool ScreenSessionManager::IsOrientationNeedChanged()
8727 {
8728 if (GetFoldDisplayMode() == FoldDisplayMode::GLOBAL_FULL) {
8729 return true;
8730 }
8731 return false;
8732 }
8733
UpdateValidArea(ScreenId screenId,uint32_t validWidth,uint32_t validHeight)8734 void ScreenSessionManager::UpdateValidArea(ScreenId screenId, uint32_t validWidth, uint32_t validHeight)
8735 {
8736 auto screenSession = GetScreenSession(screenId);
8737 if (!screenSession) {
8738 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
8739 return;
8740 }
8741 screenSession->SetValidWidth(validWidth);
8742 screenSession->SetValidHeight(validHeight);
8743 }
8744
GetIsRealScreen(ScreenId screenId)8745 bool ScreenSessionManager::GetIsRealScreen(ScreenId screenId)
8746 {
8747 if (!SessionPermission::IsSystemCalling()) {
8748 TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
8749 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8750 return false;
8751 }
8752 auto screenSession = GetScreenSession(screenId);
8753 if (!screenSession) {
8754 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
8755 return false;
8756 }
8757 return screenSession->GetIsRealScreen();
8758 }
8759
SetSystemKeyboardStatus(bool isOn)8760 DMError ScreenSessionManager::SetSystemKeyboardStatus(bool isOn)
8761 {
8762 if (!SessionPermission::IsSACalling()) {
8763 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
8764 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8765 return DMError::DM_ERROR_NOT_SYSTEM_APP;
8766 }
8767 #ifdef FOLD_ABILITY_ENABLE
8768 std::string hprProductType = "HPR";
8769 std::string productType = OHOS::system::GetParameter("const.build.product", "HYM");
8770 if (productType == hprProductType) {
8771 SuperFoldStateManager::GetInstance().SetSystemKeyboardStatus(isOn);
8772 return DMError::DM_OK;
8773 } else {
8774 return DMError::DM_ERROR_DEVICE_NOT_SUPPORT;
8775 }
8776 #endif // FOLD_ABILITY_ENABLE
8777 return DMError::DM_ERROR_DEVICE_NOT_SUPPORT;
8778 }
8779
WakeUpPictureFrameBlock(DisplayEvent event)8780 void ScreenSessionManager::WakeUpPictureFrameBlock(DisplayEvent event)
8781 {
8782 std::unique_lock <std::mutex> lock(screenWaitPictureFrameMutex_);
8783 if (event == DisplayEvent::SCREEN_LOCK_START_DREAM) {
8784 TLOGI(WmsLogTag::DMS, "[UL_POWER]get pictureFrameReady");
8785 pictureFrameReady_ = true;
8786 } else if (event == DisplayEvent::SCREEN_LOCK_END_DREAM) {
8787 TLOGI(WmsLogTag::DMS, "[UL_POWER]get pictureFrameBreak");
8788 pictureFrameBreak_ = true;
8789 }
8790 screenWaitPictureFrameCV_.notify_all();
8791 }
8792
BlockScreenWaitPictureFrameByCV(bool isStartDream)8793 bool ScreenSessionManager::BlockScreenWaitPictureFrameByCV(bool isStartDream)
8794 {
8795 TLOGI(WmsLogTag::DMS, "[UL_POWER]enter");
8796 std::unique_lock <std::mutex> lock(screenWaitPictureFrameMutex_);
8797 pictureFrameReady_ = false;
8798 pictureFrameBreak_ = false;
8799 if (screenWaitPictureFrameCV_.wait_for(lock, std::chrono::milliseconds(SCREEN_WAIT_PICTURE_FRAME_TIME))
8800 == std::cv_status::timeout) {
8801 TLOGI(WmsLogTag::DMS, "[UL_POWER]wait picture frame timeout");
8802 return true;
8803 }
8804 return isStartDream ? pictureFrameReady_ : pictureFrameBreak_;
8805 }
8806 } // namespace OHOS::Rosen
8807