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 <unordered_set>
25 #include "input_manager.h"
26
27 #include <hitrace_meter.h>
28 #ifdef DEVICE_STATUS_ENABLE
29 #include <interaction_manager.h>
30 #endif // DEVICE_STATUS_ENABLE
31 #include <ipc_skeleton.h>
32 #include <parameter.h>
33 #include <parameters.h>
34 #include <privacy_kit.h>
35 #include <system_ability_definition.h>
36 #include <transaction/rs_interfaces.h>
37 #include <xcollie/watchdog.h>
38 #include <hisysevent.h>
39 #include <power_mgr_client.h>
40 #include <screen_power_utils.h>
41
42 #include "dm_common.h"
43 #include "fold_screen_state_internel.h"
44 #ifdef WM_MULTI_SCREEN_ENABLE
45 #include "multi_screen_manager.h"
46 #include "multi_screen_power_change_manager.h"
47 #include "multi_screen_change_utils.h"
48 #endif
49 #include "pipeline/rs_node_map.h"
50 #include "rs_adapter.h"
51 #include "scene_board_judgement.h"
52 #include "session_permission.h"
53 #include "screen_scene_config.h"
54 #include "surface_capture_future.h"
55 #include "sys_cap_util.h"
56 #include "permission.h"
57 #include "window_manager_hilog.h"
58 #include "screen_rotation_property.h"
59 #include "screen_sensor_connector.h"
60 #include "screen_setting_helper.h"
61 #include "screen_session_dumper.h"
62 #include "mock_session_manager_service.h"
63 #include "connection/screen_snapshot_picker_connection.h"
64 #include "connection/screen_cast_connection.h"
65 #include "publish/screen_session_publish.h"
66 #include "dms_xcollie.h"
67 #include "screen_sensor_plugin.h"
68 #include "screen_cache.h"
69 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
70 #include <display_power_mgr_client.h>
71 #endif
72 #ifdef FOLD_ABILITY_ENABLE
73 #include "fold_screen_controller/super_fold_sensor_manager.h"
74 #include "fold_screen_controller/super_fold_state_manager.h"
75 #include "fold_screen_controller/secondary_fold_sensor_manager.h"
76 #include "fold_screen_controller/super_fold_policy.h"
77 #endif
78 #include "screen_aod_plugin.h"
79
80 namespace OHOS::Rosen {
81 namespace {
82 const std::string SCREEN_SESSION_MANAGER_THREAD = "OS_ScreenSessionManager";
83 const std::string SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD = "OS_ScreenSessionManager_ScreenPower";
84 const std::string SCREEN_CAPTURE_PERMISSION = "ohos.permission.CAPTURE_SCREEN";
85 const std::string CUSTOM_SCREEN_CAPTURE_PERMISSION = "ohos.permission.CUSTOM_SCREEN_CAPTURE";
86 const std::string BOOTEVENT_BOOT_COMPLETED = "bootevent.boot.completed";
87 const std::string ACCESS_VIRTUAL_SCREEN_PERMISSION = "ohos.permission.ACCESS_VIRTUAL_SCREEN";
88 const std::string IS_PC_MODE_KEY = "persist.sceneboard.ispcmode";
89 const std::string PC_MODE_DPI_KEY = "pcModeDpi";
90 const int32_t CV_WAIT_SCREENON_MS = 300;
91 const int32_t CV_WAIT_SCREENOFF_MS = 1500;
92 const int32_t CV_WAIT_SCREENOFF_MS_MAX = 3000;
93 const int32_t CV_WAIT_SCBSWITCH_MS = 3000;
94 const int32_t CV_WAIT_USERSWITCH_MS = 3000;
95 #ifdef WM_MULTI_USR_ABILITY_ENABLE
96 const int64_t SWITCH_USER_DISPLAYMODE_CHANGE_DELAY = 500;
97 #endif
98 const int32_t SCREEN_OFF_MIN_DELAY_TIME = 300;
99 const int32_t SCREEN_WAIT_PICTURE_FRAME_TIME = 1500;
100 const std::string STATUS_FOLD_HALF = "-z";
101 const std::string STATUS_EXPAND = "-y";
102 const std::string STATUS_FOLD = "-p";
103 const std::string SETTING_LOCKED_KEY = "settings.general.accelerometer_rotation_status";
104 const ScreenId SCREEN_ID_DEFAULT = 0;
105 const ScreenId RS_ID_DEFAULT = 0;
106 const ScreenId SCREEN_ID_FULL = 0;
107 const ScreenId SCREEN_ID_MAIN = 5;
108 const ScreenId SCREEN_ID_PC_MAIN = 9;
109 const ScreenId MINIMUM_VIRTUAL_SCREEN_ID = 1000;
110 constexpr int32_t INVALID_UID = -1;
111 constexpr int32_t INVALID_USER_ID = -1;
112 constexpr int32_t INVALID_SCB_PID = -1;
113 constexpr int32_t BASE_USER_RANGE = 200000;
114 static bool g_foldScreenFlag = system::GetParameter("const.window.foldscreen.type", "") != "";
115 static const int32_t g_screenRotationOffSet = system::GetIntParameter<int32_t>("const.fold.screen_rotation.offset", 0);
116 static const int32_t ROTATION_90 = 1;
117 #ifdef FOLD_ABILITY_ENABLE
118 static const int32_t ROTATION_270 = 3;
119 constexpr int32_t REMOVE_DISPLAY_MODE = 0;
120 #endif
121 const unsigned int XCOLLIE_TIMEOUT_10S = 10;
122 constexpr int32_t CAST_WIRED_PROJECTION_START = 1005;
123 constexpr int32_t CAST_WIRED_PROJECTION_STOP = 1007;
124 constexpr int32_t RES_FAILURE_FOR_PRIVACY_WINDOW = -2;
125 constexpr int32_t IRREGULAR_REFRESH_RATE_SKIP_THRETHOLD = 10;
126 constexpr float EXTEND_SCREEN_DPI_DEFAULT_PARAMETER = 1.0f;
127 static const int32_t AUTO_ROTATE_OFF = 0;
128 static const int NOTIFY_EVENT_FOR_DUAL_FAILED = 0;
129 static const int NOTIFY_EVENT_FOR_DUAL_SUCESS = 1;
130 static const int NO_NEED_NOTIFY_EVENT_FOR_DUAL = 2;
131 static bool g_isPcDevice = false;
132 static float g_extendScreenDpiCoef = EXTEND_SCREEN_DPI_DEFAULT_PARAMETER;
133 static uint32_t g_internalWidth = 3120;
134 #ifdef WM_MULTI_SCREEN_CTL_ABILITY_ENABLE
135 constexpr uint32_t NUMBER_OF_PHYSICAL_SCREEN = 2;
136 constexpr bool ADD_VOTE = true;
137 constexpr bool REMOVE_VOTE = false;
138 constexpr uint32_t OLED_60_HZ = 60;
139 #endif
140 constexpr uint32_t FOUR_K_WIDTH = 3840;
141 constexpr uint32_t THREE_K_WIDTH = 3000;
142 constexpr uint32_t DISPLAY_B_HEIGHT = 1608;
143
144 const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
145 constexpr int32_t FOLDABLE_DEVICE { 2 };
146 constexpr float DEFAULT_PIVOT = 0.5f;
147 constexpr float DEFAULT_SCALE = 1.0f;
148 constexpr float SECONDARY_ROTATION_90 = 90.0F;
149 constexpr float SECONDARY_ROTATION_270 = 270.0F;
150 static const constexpr char* SET_SETTING_DPI_KEY {"default_display_dpi"};
151 const std::vector<std::string> ROTATION_DEFAULT = {"0", "1", "2", "3"};
152 const std::vector<std::string> ORIENTATION_DEFAULT = {"0", "1", "2", "3"};
153 const uint32_t MAX_INTERVAL_US = 1800000000; // 30分钟
154 const int32_t MAP_SIZE = 300;
155 const std::string NO_EXIST_BUNDLE_MANE = "null";
156 ScreenCache<int32_t, std::string> g_uidVersionMap(MAP_SIZE, NO_EXIST_BUNDLE_MANE);
157
158 const std::string SCREEN_UNKNOWN = "unknown";
159
160 const int32_t SCREEN_SCAN_TYPE = system::GetIntParameter<int32_t>("const.window.screen.scan_type", 0);
161 constexpr int32_t SCAN_TYPE_VERTICAL = 1;
162 constexpr uint32_t ROTATION_MOD = 4;
163 // F state offset
164 constexpr uint32_t FULL_STATUS_OFFSET_X = 1136;
165
166 #ifdef WM_MULTI_SCREEN_ENABLE
167 const ScreenId SCREEN_ID_OUTER_ONLY = 0;
168 const std::string SCREEN_EXTEND = "extend";
169 const std::string SCREEN_MIRROR = "mirror";
170 const std::string MULTI_SCREEN_EXIT_STR = "exit";
171 const std::string MULTI_SCREEN_ENTER_STR = "enter";
172 const int32_t CV_WAIT_SCREEN_MASK_MS = 1500;
173 #endif
174 const bool IS_COORDINATION_SUPPORT =
175 OHOS::system::GetBoolParameter("const.window.foldabledevice.is_coordination_support", false);
176
177 const std::string FAULT_DESCRIPTION = "842003014";
178 const std::string FAULT_SUGGESTION = "542003014";
179 constexpr uint32_t COMMON_EVENT_SERVICE_ID = 3299;
180 const long GET_HDR_PIXELMAP_TIMEOUT = 2000;
181 const int32_t CV_WAIT_UPDATE_AVAILABLE_MS = 300;
182
183 const static uint32_t PIXMAP_VECTOR_SIZE = 2;
184 static const uint32_t SDR_PIXMAP = 0;
185 const bool IS_SUPPORT_PC_MODE = system::GetBoolParameter("const.window.support_window_pcmode_switch", false);
186 const ScreenId SCREEN_GROUP_ID_DEFAULT = 1;
187 const std::string SCREEN_NAME_EXTEND = "ExtendedDisplay";
188 const std::string SCREEN_NAME_CAST = "CastEngine";
189 const std::set<std::string> INDIVIDUAL_SCREEN_GROUP_SET = {"CeliaView", "DevEcoViewer"};
190
191 constexpr int32_t MAIN_STATUS_WIDTH_INDEX = 0;
192 constexpr int32_t FULL_STATUS_WIDTH_INDEX = 1;
193 constexpr int32_t GLOBAL_FULL_STATUS_WIDTH_INDEX = 2;
194 constexpr int32_t SCREEN_HEIGHT_INDEX = 3;
195 constexpr int32_t STATUS_PARAM_VALID_INDEX = 4;
196 constexpr uint32_t MAIN_STATUS_DEFAULT_WIDTH = 1008;
197 constexpr uint32_t SCREEN_DEFAULT_HEIGHT = 2232;
198 constexpr int32_t SECONDARY_FULL_OFFSET = 1136;
199 constexpr int32_t SECONDARY_FULL_STATUS_WIDTH = 2048;
200
201 // based on the bundle_util
202 // LCOV_EXCL_START
GetUserIdByCallingUid()203 inline int32_t GetUserIdByCallingUid()
204 {
205 int32_t uid = IPCSkeleton::GetCallingUid();
206 TLOGD(WmsLogTag::WMS_MULTI_USER, "get calling uid(%{public}d)", uid);
207 if (uid <= INVALID_UID) {
208 TLOGE(WmsLogTag::WMS_MULTI_USER, "uid is illegal: %{public}d", uid);
209 return INVALID_USER_ID;
210 }
211 return uid / BASE_USER_RANGE;
212 }
213 // LCOV_EXCL_STOP
214 } // namespace
215
216 WM_IMPLEMENT_SINGLE_INSTANCE(ScreenSessionManager)
217
218 const bool REGISTER_RESULT = !SceneBoardJudgement::IsSceneBoardEnabled() ? false :
219 SystemAbility::MakeAndRegisterAbility(&ScreenSessionManager::GetInstance());
220
ScreenSessionManager()221 ScreenSessionManager::ScreenSessionManager()
222 : SystemAbility(DISPLAY_MANAGER_SERVICE_SA_ID, true), rsInterface_(RSInterfaces::GetInstance())
223 {
224 screenEventTracker_.RecordEvent("Dms construct.");
225 LoadScreenSceneXml();
226 screenOffDelay_ = CV_WAIT_SCREENOFF_MS;
227 screenOnDelay_ = CV_WAIT_SCREENON_MS;
228 taskScheduler_ = std::make_shared<TaskScheduler>(SCREEN_SESSION_MANAGER_THREAD);
229 screenPowerTaskScheduler_ = std::make_shared<TaskScheduler>(SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD);
230 screenCutoutController_ = new (std::nothrow) ScreenCutoutController();
231 if (!screenCutoutController_) {
232 TLOGE(WmsLogTag::DMS, "screenCutoutController_ is nullptr");
233 return;
234 }
235 sessionDisplayPowerController_ = new SessionDisplayPowerController(
236 std::bind(&ScreenSessionManager::NotifyDisplayStateChange, this,
237 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
238 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
239 g_foldScreenFlag = false;
240 }
241 if (g_foldScreenFlag) {
242 HandleFoldScreenPowerInit();
243 }
244 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
245 InitSecondaryDisplayPhysicalParams();
246 }
247 WatchParameter(BOOTEVENT_BOOT_COMPLETED.c_str(), BootFinishedCallback, this);
248 }
249
SortByScreenId(const ScreenId & screenIdA,const ScreenId & screenIdB)250 bool SortByScreenId(const ScreenId& screenIdA, const ScreenId& screenIdB)
251 {
252 return static_cast<int32_t>(screenIdA) < static_cast<int32_t>(screenIdB);
253 }
254
GetPcStatus() const255 bool ScreenSessionManager::GetPcStatus() const
256 {
257 std::lock_guard<std::mutex> lock(setPcStatusMutex_);
258 return g_isPcDevice;
259 }
260
SetPcStatus(bool isPc)261 void ScreenSessionManager::SetPcStatus(bool isPc) {
262 std::lock_guard<std::mutex> lock(setPcStatusMutex_);
263 g_isPcDevice = isPc;
264 }
265
266 // LCOV_EXCL_START
ConvertOffsetToCorrectRotation(int32_t phyOffset)267 ScreenRotation ScreenSessionManager::ConvertOffsetToCorrectRotation(int32_t phyOffset)
268 {
269 ScreenRotation offsetRotation = ScreenRotation::ROTATION_0;
270 switch (phyOffset) {
271 case 90: // Rotation 90 degree
272 offsetRotation = ScreenRotation::ROTATION_270;
273 break;
274 case 180: // Rotation 180 degree
275 offsetRotation = ScreenRotation::ROTATION_180;
276 break;
277 case 270: // Rotation 270 degree
278 offsetRotation = ScreenRotation::ROTATION_90;
279 break;
280 default:
281 offsetRotation = ScreenRotation::ROTATION_0;
282 break;
283 }
284 return offsetRotation;
285 }
286
ConvertIntToRotation(int32_t rotation)287 Rotation ScreenSessionManager::ConvertIntToRotation(int32_t rotation)
288 {
289 Rotation targetRotation = Rotation::ROTATION_0;
290 switch (rotation) {
291 case 90:
292 targetRotation = Rotation::ROTATION_90;
293 break;
294 case 180:
295 targetRotation = Rotation::ROTATION_180;
296 break;
297 case 270:
298 targetRotation = Rotation::ROTATION_270;
299 break;
300 default:
301 targetRotation = Rotation::ROTATION_0;
302 break;
303 }
304 return targetRotation;
305 }
306
HandleFoldScreenPowerInit()307 void ScreenSessionManager::HandleFoldScreenPowerInit()
308 {
309 #ifdef FOLD_ABILITY_ENABLE
310 TLOGI(WmsLogTag::DMS, "Enter");
311 foldScreenController_ = new (std::nothrow) FoldScreenController(displayInfoMutex_, screenPowerTaskScheduler_);
312 if (!foldScreenController_) {
313 TLOGE(WmsLogTag::DMS, "foldScreenController_ is nullptr");
314 return;
315 }
316 foldScreenController_->SetOnBootAnimation(true);
317 if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
318 SetFoldScreenPowerInit([&]() {
319 foldScreenController_->BootAnimationFinishPowerInit();
320 FixPowerStatus();
321 foldScreenController_->SetOnBootAnimation(false);
322 RegisterApplicationStateObserver();
323 });
324 } else {
325 // 后续其他设备rs上电规格将陆续迁移到BootAnimationFinishPowerInit中
326 FoldScreenPowerInit();
327 }
328 #endif
329 }
330
IsSupportCoordination()331 bool ScreenSessionManager::IsSupportCoordination()
332 {
333 return !FoldScreenStateInternel::IsDualDisplayFoldDevice() || IS_COORDINATION_SUPPORT;
334 }
335
FoldScreenPowerInit()336 void ScreenSessionManager::FoldScreenPowerInit()
337 {
338 #ifdef FOLD_ABILITY_ENABLE
339 SetFoldScreenPowerInit([&]() {
340 int64_t timeStamp = 50;
341 #ifdef TP_FEATURE_ENABLE
342 int32_t tpType = 12;
343 std::string fullTpChange = "0";
344 std::string mainTpChange = "1";
345 #endif
346 if (!foldScreenController_) {
347 TLOGE(WmsLogTag::DMS, "foldScreenController_ is nullptr");
348 return;
349 }
350 foldScreenController_->SetIsClearingBootAnimation(true);
351 ScreenId currentScreenId = foldScreenController_->GetCurrentScreenId();
352 if (currentScreenId == SCREEN_ID_FULL) {
353 TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Full animation Init 1.");
354 SetRSScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF_FAKE);
355 if (IsSupportCoordination()) {
356 SetRSScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
357 }
358 std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
359 TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Full animation Init 2.");
360 #ifdef TP_FEATURE_ENABLE
361 rsInterface_.SetTpFeatureConfig(tpType, fullTpChange.c_str());
362 #endif
363 SetRSScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
364 foldScreenController_->AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, REMOVE_DISPLAY_MODE);
365 SetRSScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
366 } else if (currentScreenId == SCREEN_ID_MAIN) {
367 TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Main animation Init 3.");
368 SetRSScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF_FAKE);
369 if (IsSupportCoordination()) {
370 SetRSScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
371 }
372 std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
373 TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Main animation Init 4.");
374 #ifdef TP_FEATURE_ENABLE
375 rsInterface_.SetTpFeatureConfig(tpType, mainTpChange.c_str());
376 #endif
377 SetRSScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
378 foldScreenController_->AddOrRemoveDisplayNodeToTree(SCREEN_ID_FULL, REMOVE_DISPLAY_MODE);
379 SetRSScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
380 } else {
381 TLOGI(WmsLogTag::DMS, "ScreenSessionManager Fold Screen Power Init, invalid active screen id");
382 }
383 FixPowerStatus();
384 foldScreenController_->SetIsClearingBootAnimation(false);
385 foldScreenController_->SetOnBootAnimation(false);
386 RegisterApplicationStateObserver();
387 });
388 #endif
389 }
390
FixPowerStatus()391 void ScreenSessionManager::FixPowerStatus()
392 {
393 if (!PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
394 PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
395 TLOGI(WmsLogTag::DMS, "Fix Screen Power State");
396 }
397 }
398
Init()399 void ScreenSessionManager::Init()
400 {
401 if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none" ||
402 system::GetBoolParameter(IS_PC_MODE_KEY, false)) {
403 g_isPcDevice = true;
404 }
405 if (system::GetParameter("soc.boot.mode", "") != "rescue") {
406 uint64_t interval = g_isPcDevice ? 10 * 1000 : 5 * 1000; // 10 second for PC
407 if (HiviewDFX::Watchdog::GetInstance().AddThread(
408 SCREEN_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
409 TLOGW(WmsLogTag::DMS, "Add thread %{public}s to watchdog failed.", SCREEN_SESSION_MANAGER_THREAD.c_str());
410 }
411
412 if (HiviewDFX::Watchdog::GetInstance().AddThread(
413 SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD, screenPowerTaskScheduler_->GetEventHandler(), interval)) {
414 TLOGW(WmsLogTag::DMS, "Add thread %{public}s to watchdog failed.",
415 SCREEN_SESSION_MANAGER_SCREEN_POWER_THREAD.c_str());
416 }
417 } else {
418 TLOGI(WmsLogTag::DMS, "Dms in rescue mode, not need watchdog.");
419 screenEventTracker_.RecordEvent("Dms in rescue mode, not need watchdog.");
420 }
421
422 auto stringConfig = ScreenSceneConfig::GetStringConfig();
423 if (stringConfig.count("defaultDisplayCutoutPath") != 0) {
424 std::string defaultDisplayCutoutPath = static_cast<std::string>(stringConfig["defaultDisplayCutoutPath"]);
425 TLOGD(WmsLogTag::DMS, "defaultDisplayCutoutPath = %{public}s.", defaultDisplayCutoutPath.c_str());
426 ScreenSceneConfig::SetCutoutSvgPath(GetDefaultScreenId(), defaultDisplayCutoutPath);
427 }
428
429 if (!LoadMotionSensor()) {
430 screenEventTracker_.RecordEvent("Dms load motion plugin failed.");
431 TLOGW(WmsLogTag::DMS, "load motion plugin failed.");
432 }
433
434 if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() ||
435 FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
436 if (!LoadAodLib()) {
437 TLOGE(WmsLogTag::DMS, "load aod lib failed");
438 }
439 }
440
441 RegisterScreenChangeListener();
442 if(FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
443 RegisterFoldNotSwitchingListener();
444 }
445 if (!ScreenSceneConfig::IsSupportRotateWithSensor()) {
446 TLOGI(WmsLogTag::DMS, "Current type not support SetSensorSubscriptionEnabled.");
447 } else if (GetScreenPower(SCREEN_ID_FULL) == ScreenPowerState::POWER_ON) {
448 // 多屏设备只要有屏幕亮,GetScreenPower获取的任意一块屏幕状态均是ON
449 SetSensorSubscriptionEnabled();
450 screenEventTracker_.RecordEvent("Dms subscribed to sensor successfully.");
451 }
452
453 // publish init
454 ScreenSessionPublish::GetInstance().InitPublishEvents();
455 screenEventTracker_.RecordEvent("Dms init end.");
456 }
457
OnStart()458 void ScreenSessionManager::OnStart()
459 {
460 TLOGI(WmsLogTag::DMS, "start");
461 DmsXcollie dmsXcollie("DMS:OnStart", XCOLLIE_TIMEOUT_10S,
462 [this](void *) { screenEventTracker_.LogWarningAllInfos(); });
463 Init();
464 sptr<ScreenSessionManager> dms(this);
465 dms->IncStrongRef(nullptr);
466 if (!Publish(dms)) {
467 TLOGE(WmsLogTag::DMS, "Publish DMS failed");
468 return;
469 }
470 TLOGI(WmsLogTag::DMS, "DMS SA AddSystemAbilityListener");
471 (void)AddSystemAbilityListener(SENSOR_SERVICE_ABILITY_ID);
472 (void)AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
473 (void)AddSystemAbilityListener(MULTIMODAL_INPUT_SERVICE_ID);
474 screenEventTracker_.RecordEvent("Dms AddSystemAbilityListener finished.");
475 TLOGI(WmsLogTag::DMS, "end");
476 screenEventTracker_.RecordEvent("Dms onstart end.");
477 }
478
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)479 void ScreenSessionManager::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
480 {
481 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "OnAddSystemAbility: %d", systemAbilityId);
482 TLOGI(WmsLogTag::DMS, "receive sa add:%{public}d", systemAbilityId);
483 if (systemAbilityId == MULTIMODAL_INPUT_SERVICE_ID) {
484 if (!g_isPcDevice) {
485 TLOGI(WmsLogTag::DMS, "current device is not pc");
486 return;
487 }
488 SwitchSubscriberInit();
489 TLOGI(WmsLogTag::DMS, " SwitchSubscriber finished.");
490 }
491 if (systemAbilityId == SENSOR_SERVICE_ABILITY_ID) {
492 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
493 if (!g_foldScreenFlag) {
494 TLOGI(WmsLogTag::DMS, "current device is not fold phone.");
495 return;
496 }
497 if (!foldScreenController_ || isFoldScreenOuterScreenReady_) {
498 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null or outer screen is not ready.");
499 return;
500 }
501 if (GetDisplayState(foldScreenController_->GetCurrentScreenId()) == DisplayState::ON) {
502 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
503 SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
504 } else {
505 FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
506 }
507 TLOGI(WmsLogTag::DMS, "Recover Posture sensor finished");
508 }
509
510 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
511 SecondaryFoldSensorManager::GetInstance().RegisterHallCallback();
512 } else {
513 FoldScreenSensorManager::GetInstance().RegisterHallCallback();
514 }
515 TLOGI(WmsLogTag::DMS, "Recover Hall sensor finished");
516 screenEventTracker_.RecordEvent("Dms recover Posture and Hall sensor finished.");
517 #endif
518 } else if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
519 auto task = []() {
520 ScreenSessionPublish::GetInstance().RegisterLowTempSubscriber();
521 ScreenSessionPublish::GetInstance().RegisterUserSwitchedSubscriber();
522 };
523 taskScheduler_->PostAsyncTask(task, "RegisterCommonEventSubscriber");
524 }
525 }
526
CheckDisplayMangerAgentTypeAndPermission(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)527 DMError ScreenSessionManager::CheckDisplayMangerAgentTypeAndPermission(
528 const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
529 {
530 if ((type == DisplayManagerAgentType::SCREEN_EVENT_LISTENER ||
531 type == DisplayManagerAgentType::PRIVATE_WINDOW_LISTENER) &&
532 !SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
533 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
534 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
535 return DMError::DM_ERROR_NOT_SYSTEM_APP;
536 }
537
538 if ((displayManagerAgent == nullptr) || (displayManagerAgent->AsObject() == nullptr)) {
539 TLOGE(WmsLogTag::DMS, "displayManagerAgent invalid");
540 return DMError::DM_ERROR_NULLPTR;
541 }
542 return DMError::DM_OK;
543 }
544
RegisterDisplayManagerAgent(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)545 DMError ScreenSessionManager::RegisterDisplayManagerAgent(
546 const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
547 {
548 TLOGI(WmsLogTag::DMS, " called type: %{public}u", type);
549 DmsXcollie dmsXcollie("DMS:RegisterDisplayManagerAgent", XCOLLIE_TIMEOUT_10S);
550 DMError ret;
551
552 ret = CheckDisplayMangerAgentTypeAndPermission(displayManagerAgent, type);
553 if (ret != DMError::DM_OK) {
554 TLOGE(WmsLogTag::DMS, "call CheckDisplayMangerAgentTypeAndPermission fail!");
555 return ret;
556 }
557
558 if (type < DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER
559 || type >= DisplayManagerAgentType::DISPLAY_MANAGER_MAX_AGENT_TYPE) {
560 TLOGE(WmsLogTag::DMS, "DisplayManagerAgentType: %{public}u", static_cast<uint32_t>(type));
561 return DMError::DM_ERROR_INVALID_PARAM;
562 }
563 return dmAgentContainer_.RegisterAgent(displayManagerAgent, type) ? DMError::DM_OK :DMError::DM_ERROR_NULLPTR;
564 }
565
UnregisterDisplayManagerAgent(const sptr<IDisplayManagerAgent> & displayManagerAgent,DisplayManagerAgentType type)566 DMError ScreenSessionManager::UnregisterDisplayManagerAgent(
567 const sptr<IDisplayManagerAgent>& displayManagerAgent, DisplayManagerAgentType type)
568 {
569 TLOGI(WmsLogTag::DMS, " called type: %{public}u", type);
570 DMError ret;
571
572 ret = CheckDisplayMangerAgentTypeAndPermission(displayManagerAgent, type);
573 if (ret != DMError::DM_OK) {
574 TLOGE(WmsLogTag::DMS, "call CheckDisplayMangerAgentTypeAndPermission fail!");
575 return ret;
576 }
577 return dmAgentContainer_.UnregisterAgent(displayManagerAgent, type) ? DMError::DM_OK :DMError::DM_ERROR_NULLPTR;
578 }
579 // LCOV_EXCL_STOP
580
LoadScreenSceneXml()581 void ScreenSessionManager::LoadScreenSceneXml()
582 {
583 if (ScreenSceneConfig::LoadConfigXml()) {
584 ScreenSceneConfig::DumpConfig();
585 ConfigureScreenScene();
586 }
587 }
588
ConfigureScreenScene()589 void ScreenSessionManager::ConfigureScreenScene()
590 {
591 auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
592 auto enableConfig = ScreenSceneConfig::GetEnableConfig();
593 auto stringConfig = ScreenSceneConfig::GetStringConfig();
594 ConfigureDpi();
595 if (numbersConfig.count("defaultDeviceRotationOffset") != 0) {
596 defaultDeviceRotationOffset_ = static_cast<uint32_t>(numbersConfig["defaultDeviceRotationOffset"][0]);
597 TLOGD(WmsLogTag::DMS, "defaultDeviceRotationOffset = %{public}u", defaultDeviceRotationOffset_);
598 }
599 if (enableConfig.count("isWaterfallDisplay") != 0) {
600 bool isWaterfallDisplay = static_cast<bool>(enableConfig["isWaterfallDisplay"]);
601 TLOGD(WmsLogTag::DMS, "isWaterfallDisplay = %{public}d", isWaterfallDisplay);
602 }
603 if (numbersConfig.count("curvedScreenBoundary") != 0) {
604 std::vector<int> vtBoundary = static_cast<std::vector<int>>(numbersConfig["curvedScreenBoundary"]);
605 TLOGD(WmsLogTag::DMS, "vtBoundary.size=%{public}u", static_cast<uint32_t>(vtBoundary.size()));
606 }
607 if (stringConfig.count("subDisplayCutoutPath") != 0) {
608 std::string subDisplayCutoutPath = stringConfig["subDisplayCutoutPath"];
609 TLOGD(WmsLogTag::DMS, "subDisplayCutoutPath = %{public}s.", subDisplayCutoutPath.c_str());
610 ScreenSceneConfig::SetSubCutoutSvgPath(subDisplayCutoutPath);
611 }
612 if (stringConfig.count("rotationPolicy") != 0) {
613 std::string rotationPolicy = stringConfig["rotationPolicy"];
614 TLOGD(WmsLogTag::DMS, "rotationPolicy = %{public}s.", rotationPolicy.c_str());
615 deviceScreenConfig_.rotationPolicy_ = rotationPolicy;
616 }
617 if (stringConfig.count("defaultRotationPolicy") != 0) {
618 std::string defaultRotationPolicy = stringConfig["defaultRotationPolicy"];
619 TLOGD(WmsLogTag::DMS, "defaultRotationPolicy = %{public}s.", defaultRotationPolicy.c_str());
620 deviceScreenConfig_.defaultRotationPolicy_ = defaultRotationPolicy;
621 }
622 if (enableConfig.count("isRightPowerButton") != 0) {
623 bool isRightPowerButton = static_cast<bool>(enableConfig["isRightPowerButton"]);
624 TLOGD(WmsLogTag::DMS, "isRightPowerButton = %{public}d", isRightPowerButton);
625 deviceScreenConfig_.isRightPowerButton_ = isRightPowerButton;
626 }
627 ConfigureWaterfallDisplayCompressionParams();
628 ConfigureCastParams();
629
630 if (numbersConfig.count("buildInDefaultOrientation") != 0) {
631 Orientation orientation = static_cast<Orientation>(numbersConfig["buildInDefaultOrientation"][0]);
632 TLOGD(WmsLogTag::DMS, "orientation = %{public}d", orientation);
633 }
634 {
635 std::lock_guard<std::mutex> lock(allDisplayPhysicalResolutionMutex_);
636 allDisplayPhysicalResolution_ = ScreenSceneConfig::GetAllDisplayPhysicalConfig();
637 }
638 }
639
ConfigureDpi()640 void ScreenSessionManager::ConfigureDpi()
641 {
642 auto numbersConfig = ScreenSceneConfig::GetIntNumbersConfig();
643 if (numbersConfig.count("dpi") != 0) {
644 uint32_t densityDpi = static_cast<uint32_t>(numbersConfig["dpi"][0]);
645 TLOGI(WmsLogTag::DMS, "densityDpi = %{public}u", densityDpi);
646 if (densityDpi >= DOT_PER_INCH_MINIMUM_VALUE && densityDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
647 isDensityDpiLoad_ = true;
648 defaultDpi = densityDpi;
649 cachedSettingDpi_ = defaultDpi;
650 densityDpi_ = static_cast<float>(densityDpi) / BASELINE_DENSITY;
651 }
652 }
653 if (numbersConfig.count("subDpi") != 0) {
654 uint32_t subDensityDpi = static_cast<uint32_t>(numbersConfig["subDpi"][0]);
655 TLOGI(WmsLogTag::DMS, "subDensityDpi = %{public}u", subDensityDpi);
656 if (subDensityDpi >= DOT_PER_INCH_MINIMUM_VALUE && subDensityDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
657 isDensityDpiLoad_ = true;
658 subDensityDpi_ = static_cast<float>(subDensityDpi) / BASELINE_DENSITY;
659 }
660 }
661 const bool isPcMode = system::GetBoolParameter(IS_PC_MODE_KEY, false);
662 if (isPcMode && numbersConfig.count(PC_MODE_DPI_KEY) != 0 && numbersConfig[PC_MODE_DPI_KEY].size() > 0) {
663 uint32_t pcModeDpi = static_cast<uint32_t>(numbersConfig[PC_MODE_DPI_KEY][0]);
664 if (pcModeDpi >= DOT_PER_INCH_MINIMUM_VALUE && pcModeDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
665 pcModeDpi_ = pcModeDpi;
666 isDensityDpiLoad_ = true;
667 defaultDpi = pcModeDpi_;
668 cachedSettingDpi_ = defaultDpi;
669 densityDpi_ = static_cast<float>(pcModeDpi_) / BASELINE_DENSITY;
670 }
671 TLOGI(WmsLogTag::DMS, "config pcmode densityDpi: %{public}f", densityDpi_);
672 }
673 }
674
ConfigureCastParams()675 void ScreenSessionManager::ConfigureCastParams()
676 {
677 auto stringConfig = ScreenSceneConfig::GetStringConfig();
678 if (stringConfig.count("castBundleName") == 0) {
679 TLOGE(WmsLogTag::DMS, "not find cast bundleName in config xml");
680 return;
681 }
682 std::string castBundleName = static_cast<std::string>(stringConfig["castBundleName"]);
683 TLOGD(WmsLogTag::DMS, "castBundleName = %{public}s", castBundleName.c_str());
684 ScreenCastConnection::GetInstance().SetBundleName(castBundleName);
685 if (stringConfig.count("castAbilityName") == 0) {
686 TLOGE(WmsLogTag::DMS, "not find cast ability in config xml");
687 return;
688 }
689 std::string castAbilityName = static_cast<std::string>(stringConfig["castAbilityName"]);
690 TLOGD(WmsLogTag::DMS, "castAbilityName = %{public}s", castAbilityName.c_str());
691 ScreenCastConnection::GetInstance().SetAbilityName(castAbilityName);
692 }
693
ConfigureWaterfallDisplayCompressionParams()694 void ScreenSessionManager::ConfigureWaterfallDisplayCompressionParams()
695 {
696 auto enableConfig = ScreenSceneConfig::GetEnableConfig();
697 if (enableConfig.count("isWaterfallAreaCompressionEnableWhenHorizontal") != 0) {
698 bool enable = static_cast<bool>(enableConfig["isWaterfallAreaCompressionEnableWhenHorizontal"]);
699 TLOGD(WmsLogTag::DMS, "isWaterfallAreaCompressionEnableWhenHorizontal=%{public}d.", enable);
700 }
701 ScreenSceneConfig::SetCurvedCompressionAreaInLandscape();
702 }
703
704 // LCOV_EXCL_START
ConfigureScreenSnapshotParams()705 void ScreenSessionManager::ConfigureScreenSnapshotParams()
706 {
707 auto stringConfig = ScreenSceneConfig::GetStringConfig();
708 if (stringConfig.count("screenSnapshotBundleName") == 0) {
709 TLOGE(WmsLogTag::DMS, "not find screen snapshot bundleName in config xml");
710 return;
711 }
712 std::string screenSnapshotBundleName = static_cast<std::string>(stringConfig["screenSnapshotBundleName"]);
713 TLOGD(WmsLogTag::DMS, "screenSnapshotBundleName = %{public}s.", screenSnapshotBundleName.c_str());
714 ScreenSnapshotPickerConnection::GetInstance().SetBundleName(screenSnapshotBundleName);
715 if (stringConfig.count("screenSnapshotAbilityName") == 0) {
716 TLOGE(WmsLogTag::DMS, "not find screen snapshot ability in config xml");
717 return;
718 }
719 std::string screenSnapshotAbilityName = static_cast<std::string>(stringConfig["screenSnapshotAbilityName"]);
720 TLOGD(WmsLogTag::DMS, "screenSnapshotAbilityName = %{public}s.", screenSnapshotAbilityName.c_str());
721 ScreenSnapshotPickerConnection::GetInstance().SetAbilityName(screenSnapshotAbilityName);
722 }
723 // LCOV_EXCL_STOP
724
RegisterScreenChangeListener()725 void ScreenSessionManager::RegisterScreenChangeListener()
726 {
727 TLOGI(WmsLogTag::DMS, "start");
728 auto res = rsInterface_.SetScreenChangeCallback(
729 [this](ScreenId screenId, ScreenEvent screenEvent, ScreenChangeReason reason) {
730 OnScreenChange(screenId, screenEvent, reason);
731 });
732 if (res != StatusCode::SUCCESS) {
733 auto task = [this]() { RegisterScreenChangeListener(); };
734 taskScheduler_->PostAsyncTask(task, "RegisterScreenChangeListener", 50); // Retry after 50 ms.
735 screenEventTracker_.RecordEvent("Dms OnScreenChange register failed.");
736 } else {
737 screenEventTracker_.RecordEvent("Dms OnScreenChange register success.");
738 }
739 }
740
RegisterFoldNotSwitchingListener()741 void ScreenSessionManager::RegisterFoldNotSwitchingListener()
742 {
743 TLOGI(WmsLogTag::DMS, "start");
744 auto res = rsInterface_.SetScreenSwitchingNotifyCallback(
745 [this](bool isSwitching) {
746 OnFoldStatusChange(isSwitching);
747 });
748 if (res != StatusCode::SUCCESS) {
749 auto task = [this]() { RegisterFoldNotSwitchingListener(); };
750 taskScheduler_->PostAsyncTask(task, "RegisterFoldNotSwitchingListener", 50); // Retry after 50 ms.
751 screenEventTracker_.RecordEvent("Dms fold not switching register failed.");
752 } else {
753 screenEventTracker_.RecordEvent("Dms fold not switching register success.");
754 }
755 }
756
ReportFoldDisplayTime(uint64_t screenId,int64_t rsFirstFrameTime)757 void ScreenSessionManager::ReportFoldDisplayTime(uint64_t screenId, int64_t rsFirstFrameTime)
758 {
759 #ifdef FOLD_ABILITY_ENABLE
760 TLOGI(WmsLogTag::DMS, "[UL_FOLD]ReportFoldDisplayTime rsFirstFrameTime: %{public}" PRId64
761 ", screenId: %{public}" PRIu64, rsFirstFrameTime, screenId);
762 if (foldScreenController_ != nullptr && foldScreenController_->GetIsFirstFrameCommitReported() == false) {
763 int64_t foldStartTime = foldScreenController_->GetStartTimePoint().time_since_epoch().count();
764 int32_t ret = HiSysEventWrite(
765 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
766 "DISPLAY_MODE",
767 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
768 "FOLD_TIME", rsFirstFrameTime - foldStartTime);
769 foldScreenController_->SetIsFirstFrameCommitReported(true);
770 if (ret != 0) {
771 TLOGE(WmsLogTag::DMS, "[UL_FOLD]ReportFoldDisplayTime Write HiSysEvent error, ret: %{public}d", ret);
772 }
773 }
774 #endif
775 }
776
RegisterFirstFrameCommitCallback()777 void ScreenSessionManager::RegisterFirstFrameCommitCallback()
778 {
779 TLOGI(WmsLogTag::DMS, "[UL_FOLD]RegisterFirstFrameCommitCallback start");
780 auto callback = [=](uint64_t screenId, int64_t rsFirstFrameTime) {
781 ReportFoldDisplayTime(screenId, rsFirstFrameTime);
782 };
783 RSInterfaces::GetInstance().RegisterFirstFrameCommitCallback(callback);
784 }
785
RegisterRefreshRateChangeListener()786 void ScreenSessionManager::RegisterRefreshRateChangeListener()
787 {
788 static bool isRegisterRefreshRateListener = false;
789 // LCOV_EXCL_START
790 if (!isRegisterRefreshRateListener) {
791 TLOGW(WmsLogTag::DMS, "call rsInterface_ RegisterHgmRefreshRateUpdateCallback");
792 auto res = rsInterface_.RegisterHgmRefreshRateUpdateCallback(
793 [this](uint32_t refreshRate) { OnHgmRefreshRateChange(refreshRate); });
794 TLOGW(WmsLogTag::DMS, "call rsInterface_ RegisterHgmRefreshRateUpdateCallback end");
795 if (res != StatusCode::SUCCESS) {
796 TLOGE(WmsLogTag::DMS, "failed");
797 screenEventTracker_.RecordEvent("Dms RefreshRateChange register failed.");
798 } else {
799 isRegisterRefreshRateListener = true;
800 screenEventTracker_.RecordEvent("Dms RefreshRateChange register success.");
801 }
802 }
803 // LCOV_EXCL_STOP
804 }
805
OnVirtualScreenChange(ScreenId screenId,ScreenEvent screenEvent)806 void ScreenSessionManager::OnVirtualScreenChange(ScreenId screenId, ScreenEvent screenEvent)
807 {
808 TLOGI(WmsLogTag::DMS, "Notify scb virtual screen change, ScreenId: %{public}" PRIu64 ", ScreenEvent: %{public}d",
809 screenId, static_cast<int>(screenEvent));
810 auto screenSession = GetScreenSession(screenId);
811 if (!screenSession) {
812 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
813 return;
814 }
815 if (screenEvent == ScreenEvent::CONNECTED) {
816 auto clientProxy = GetClientProxy();
817 TLOGI(WmsLogTag::DMS, "screenCombination:%{public}d, screenName:%{public}s",
818 screenSession->GetScreenCombination(), screenSession->GetName().c_str());
819 if(screenSession->GetScreenCombination() == ScreenCombination::SCREEN_UNIQUE &&
820 INDIVIDUAL_SCREEN_GROUP_SET.find(screenSession->GetName()) != INDIVIDUAL_SCREEN_GROUP_SET.end()) {
821 screenSession->SetDisplayGroupId(displayGroupNum_++);
822 screenSession->SetMainDisplayIdOfGroup(screenId);
823 } else {
824 // Unique screens outside of INDIVIDUAL_SCREEN_GROUP_SET are placed in the default group.
825 screenSession->SetDisplayGroupId(DISPLAY_GROUP_ID_DEFAULT);
826 screenSession->SetMainDisplayIdOfGroup(MAIN_SCREEN_ID_DEFAULT);
827 }
828 if (clientProxy) {
829 clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId),
830 ScreenEvent::CONNECTED);
831 }
832 return;
833 }
834 if (screenEvent == ScreenEvent::DISCONNECTED) {
835 std::map<int32_t, sptr<IScreenSessionManagerClient>> clientProxyMap;
836 {
837 std::lock_guard<std::mutex> lock(clientProxyMutex_);
838 clientProxyMap = clientProxyMap_;
839 }
840 for (const auto& [userId, clientProxy] : clientProxyMap) {
841 if (clientProxy) {
842 clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId),
843 ScreenEvent::DISCONNECTED);
844 }
845 }
846 }
847 }
848
849 // LCOV_EXCL_START
IsDefaultMirrorMode(ScreenId screenId)850 bool ScreenSessionManager::IsDefaultMirrorMode(ScreenId screenId)
851 {
852 if (screenId != SCREEN_ID_MAIN && screenId != SCREEN_ID_FULL && screenId != SCREEN_ID_PC_MAIN) {
853 return true;
854 }
855 return false;
856 }
857
FreeDisplayMirrorNodeInner(const sptr<ScreenSession> mirrorSession)858 void ScreenSessionManager::FreeDisplayMirrorNodeInner(const sptr<ScreenSession> mirrorSession)
859 {
860 if (mirrorSession == nullptr) {
861 return;
862 }
863 {
864 std::shared_ptr<RSDisplayNode> displayNode = mirrorSession->GetDisplayNode();
865 if (displayNode == nullptr) {
866 return;
867 }
868 if (!g_isPcDevice) {
869 hdmiScreenCount_ = hdmiScreenCount_ > 0 ? hdmiScreenCount_ - 1 : 0;
870 NotifyCaptureStatusChanged();
871 }
872 displayNode->RemoveFromTree();
873 mirrorSession->ReleaseDisplayNode();
874 displayNode = nullptr;
875 }
876 TLOGI(WmsLogTag::DMS, "free displayNode");
877 RSTransactionAdapter::FlushImplicitTransaction(mirrorSession->GetRSUIContext());
878 }
879
SetScreenCorrection()880 void ScreenSessionManager::SetScreenCorrection()
881 {
882 std::ostringstream oss;
883 if (g_foldScreenFlag) {
884 if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
885 auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_MAIN,
886 static_cast<ScreenRotation>(ROTATION_90));
887 oss << "main screenRotationOffSet: " << g_screenRotationOffSet << " ret value: " << ret;
888 } else {
889 auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_FULL,
890 static_cast<ScreenRotation>(g_screenRotationOffSet));
891 oss << "full screenRotationOffSet: " << g_screenRotationOffSet << " ret value: " << ret;
892 }
893 } else {
894 std::vector<std::string> phyOffsets = FoldScreenStateInternel::GetPhyRotationOffset();
895 int32_t phyOffset = static_cast<int32_t>(std::stoi(phyOffsets[0]));
896 ScreenRotation correctRotation = ConvertOffsetToCorrectRotation(phyOffset);
897 auto ret = rsInterface_.SetScreenCorrection(SCREEN_ID_DEFAULT, correctRotation);
898 oss << "phyOffset: " << phyOffset << " correctRotation value: " <<
899 static_cast<int32_t>(correctRotation) << " ret value: " << ret;
900 }
901 TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
902 screenEventTracker_.RecordEvent(oss.str());
903 }
904
AdaptSuperHorizonalBoot(sptr<ScreenSession> screenSession,ScreenId screenId)905 void ScreenSessionManager::AdaptSuperHorizonalBoot(sptr<ScreenSession> screenSession, ScreenId screenId)
906 {
907 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && screenSession->isInternal_) {
908 auto screenMode = rsInterface_.GetScreenActiveMode(screenId);
909 int32_t screenWidth = screenMode.GetScreenWidth();
910 int32_t screenHeight = screenMode.GetScreenHeight();
911 RRect screenBounds = RRect({ 0, 0, screenHeight, screenWidth }, 0.0f, 0.0f);
912 screenSession->SetBounds(screenBounds);
913 screenSession->SetHorizontalRotation();
914 screenSession->SetValidWidth(screenHeight);
915 screenSession->SetValidHeight(screenWidth);
916 }
917 }
918
OnScreenChange(ScreenId screenId,ScreenEvent screenEvent,ScreenChangeReason reason)919 void ScreenSessionManager::OnScreenChange(ScreenId screenId, ScreenEvent screenEvent, ScreenChangeReason reason)
920 {
921 if (reason == ScreenChangeReason::HWCDEAD) {
922 NotifyAbnormalScreenConnectChange(screenId);
923 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " ScreenChangeReason: %{public}d",
924 screenId, static_cast<int>(reason));
925 return;
926 }
927 if (g_isPcDevice) {
928 OnScreenChangeForPC(screenId, screenEvent, reason);
929 } else {
930 OnScreenChangeDefault(screenId, screenEvent, reason);
931 }
932 }
933
OnScreenChangeForPC(ScreenId screenId,ScreenEvent screenEvent,ScreenChangeReason reason)934 void ScreenSessionManager::OnScreenChangeForPC(ScreenId screenId, ScreenEvent screenEvent, ScreenChangeReason reason)
935 {
936 std::lock_guard<std::mutex> lock(screenChangeMutex_);
937 std::ostringstream oss;
938 oss << "OnScreenChange triggered. screenId: " << static_cast<int32_t>(screenId)
939 << " screenEvent: " << static_cast<int32_t>(screenEvent);
940 screenEventTracker_.RecordEvent(oss.str());
941 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " screenEvent: %{public}d",
942 screenId, static_cast<int>(screenEvent));
943 SetScreenCorrection();
944 auto screenSession = GetOrCreateScreenSession(screenId);
945 if (!screenSession) {
946 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
947 return;
948 }
949 AdaptSuperHorizonalBoot(screenSession, screenId);
950 if (g_isPcDevice) {
951 auto physicalScreenSession = GetOrCreatePhysicalScreenSession(screenId);
952 if (!physicalScreenSession) {
953 TLOGE(WmsLogTag::DMS, "physicalScreenSession is nullptr");
954 return;
955 }
956 AdaptSuperHorizonalBoot(physicalScreenSession, screenId);
957 }
958 OnFoldScreenChange(screenSession);
959 if (screenEvent == ScreenEvent::CONNECTED) {
960 connectScreenNumber_ ++;
961 DestroyExtendVirtualScreen();
962 HandleScreenConnectEvent(screenSession, screenId, screenEvent);
963 } else if (screenEvent == ScreenEvent::DISCONNECTED) {
964 connectScreenNumber_ --;
965 HandleScreenDisconnectEvent(screenSession, screenId, screenEvent);
966 } else {
967 TLOGE(WmsLogTag::DMS, "screenEvent error!");
968 }
969 NotifyScreenModeChange();
970 }
971
OnScreenChangeDefault(ScreenId screenId,ScreenEvent screenEvent,ScreenChangeReason reason)972 void ScreenSessionManager::OnScreenChangeDefault(ScreenId screenId, ScreenEvent screenEvent, ScreenChangeReason reason)
973 {
974 std::ostringstream oss;
975 oss << "OnScreenChange triggered. screenId: " << static_cast<int32_t>(screenId)
976 << " screenEvent: " << static_cast<int32_t>(screenEvent);
977 screenEventTracker_.RecordEvent(oss.str());
978 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " screenEvent: %{public}d",
979 screenId, static_cast<int>(screenEvent));
980 SetScreenCorrection();
981 auto screenSession = GetOrCreateScreenSession(screenId);
982 if (!screenSession) {
983 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
984 return;
985 }
986 if (g_isPcDevice) {
987 auto physicalScreenSession = GetOrCreatePhysicalScreenSession(screenId);
988 if (!physicalScreenSession) {
989 TLOGE(WmsLogTag::DMS, "physicalScreenSession is nullptr");
990 return;
991 }
992 }
993 OnFoldScreenChange(screenSession);
994 if (screenEvent == ScreenEvent::CONNECTED) {
995 connectScreenNumber_ ++;
996 HandleScreenConnectEvent(screenSession, screenId, screenEvent);
997 } else if (screenEvent == ScreenEvent::DISCONNECTED) {
998 connectScreenNumber_ --;
999 HandleScreenDisconnectEvent(screenSession, screenId, screenEvent);
1000 } else {
1001 TLOGE(WmsLogTag::DMS, "screenEvent error!");
1002 }
1003 NotifyScreenModeChange();
1004 }
1005
OnFoldScreenChange(sptr<ScreenSession> & screenSession)1006 void ScreenSessionManager::OnFoldScreenChange(sptr<ScreenSession>& screenSession)
1007 {
1008 #ifdef FOLD_ABILITY_ENABLE
1009 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1010 SuperFoldSensorManager::GetInstance().SetTaskScheduler(screenPowerTaskScheduler_);
1011 SuperFoldSensorManager::GetInstance().RegisterPostureCallback();
1012 SuperFoldSensorManager::GetInstance().RegisterHallCallback();
1013 SetSensorSubscriptionEnabled();
1014 screenEventTracker_.RecordEvent("Dms subscribed to sensor successfully.");
1015 }
1016
1017 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
1018 SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
1019 SecondaryFoldSensorManager::GetInstance().RegisterHallCallback();
1020 SetSensorSubscriptionEnabled();
1021 screenEventTracker_.RecordEvent("secondary device: Dms subscribed to sensor successfully.");
1022 }
1023
1024 if (foldScreenController_ != nullptr) {
1025 RegisterFirstFrameCommitCallback();
1026 screenSession->SetFoldScreen(true);
1027 }
1028 #endif
1029 }
1030
OnFoldStatusChange(bool isSwitching)1031 void ScreenSessionManager::OnFoldStatusChange(bool isSwitching)
1032 {
1033 #ifdef FOLD_ABILITY_ENABLE
1034 if (foldScreenController_ == nullptr) {
1035 TLOGE(WmsLogTag::DMS, "fold screen controller is not initialized.");
1036 return;
1037 }
1038 if (!isSwitching) {
1039 TLOGI(WmsLogTag::DMS, "receive switching end.");
1040 foldScreenController_->SetdisplayModeChangeStatus(false);
1041 }
1042 #endif
1043 }
1044
DestroyExtendVirtualScreen()1045 void ScreenSessionManager::DestroyExtendVirtualScreen()
1046 {
1047 TLOGI(WmsLogTag::DMS, "start");
1048 std::map<ScreenId, sptr<ScreenSession>> screenSessionMap;
1049 {
1050 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1051 screenSessionMap = screenSessionMap_;
1052 }
1053 for (auto sessionIt : screenSessionMap) {
1054 sptr<ScreenSession> screenSession = sessionIt.second;
1055 if (screenSession == nullptr) {
1056 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64,
1057 sessionIt.first);
1058 continue;
1059 }
1060 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL &&
1061 screenSession->GetIsExtendVirtual()) {
1062 DestroyVirtualScreen(screenSession->GetScreenId());
1063 TLOGI(WmsLogTag::DMS, "destory screenId: %{public}" PRIu64, screenSession->GetScreenId());
1064 }
1065 }
1066 }
1067
NotifyScreenModeChange(ScreenId disconnectedScreenId)1068 void ScreenSessionManager::NotifyScreenModeChange(ScreenId disconnectedScreenId)
1069 {
1070 TLOGI(WmsLogTag::DMS, "NotifyScreenModeChange start");
1071 auto task = [=] {
1072 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER);
1073 if (agents.empty()) {
1074 TLOGNE(WmsLogTag::DMS, "NotifyScreenModeChange agent is null");
1075 return;
1076 }
1077 std::vector<sptr<ScreenInfo>> screenInfos;
1078 std::vector<ScreenId> screenIds = GetAllScreenIds();
1079 for (auto screenId : screenIds) {
1080 if (disconnectedScreenId == screenId) {
1081 continue;
1082 }
1083 TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64, screenId);
1084 auto screenSession = GetScreenSession(screenId);
1085 screenInfos.emplace_back(screenSession->ConvertToScreenInfo());
1086 }
1087 for (auto& agent : agents) {
1088 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
1089 if (!IsFreezed(agentPid, DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER)) {
1090 agent->NotifyScreenModeChange(screenInfos);
1091 }
1092 }
1093 };
1094 taskScheduler_->PostAsyncTask(task, "NotifyScreenModeChange");
1095 }
1096
NotifyAbnormalScreenConnectChange(ScreenId screenId)1097 void ScreenSessionManager::NotifyAbnormalScreenConnectChange(ScreenId screenId)
1098 {
1099 auto agents = dmAgentContainer_.GetAgentsByType(
1100 DisplayManagerAgentType::ABNORMAL_SCREEN_CONNECT_CHANGE_LISTENER);
1101 if (agents.empty()) {
1102 TLOGE(WmsLogTag::DMS, "agents is empty");
1103 return;
1104 }
1105 for (auto& agent : agents) {
1106 agent->NotifyAbnormalScreenConnectChange(screenId);
1107 }
1108 }
1109
SendCastEvent(const bool & isPlugIn)1110 void ScreenSessionManager::SendCastEvent(const bool &isPlugIn)
1111 {
1112 TLOGI(WmsLogTag::DMS, "isPlugIn:%{public}d", isPlugIn);
1113 if (!ScreenCastConnection::GetInstance().CastConnectExtension(static_cast<int32_t>(isPlugIn))) {
1114 TLOGE(WmsLogTag::DMS, "CastConnectionExtension failed");
1115 return;
1116 }
1117 if (!ScreenCastConnection::GetInstance().IsConnectedSync()) {
1118 TLOGE(WmsLogTag::DMS, "CastConnectionExtension connected failed");
1119 ScreenCastConnection::GetInstance().CastDisconnectExtension();
1120 return;
1121 }
1122 MessageParcel data;
1123 MessageParcel reply;
1124 if (isPlugIn) {
1125 ScreenCastConnection::GetInstance().SendMessageToCastService(CAST_WIRED_PROJECTION_START, data, reply);
1126 } else {
1127 ScreenCastConnection::GetInstance().SendMessageToCastService(CAST_WIRED_PROJECTION_STOP, data, reply);
1128 }
1129 ScreenCastConnection::GetInstance().CastDisconnectExtension();
1130 }
1131
NotifyCastWhenScreenConnectChange(bool isConnected)1132 void ScreenSessionManager::NotifyCastWhenScreenConnectChange(bool isConnected)
1133 {
1134 if (g_isPcDevice) {
1135 TLOGI(WmsLogTag::DMS, "pc device");
1136 return;
1137 }
1138 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1139 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
1140 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
1141 return;
1142 }
1143 if (isConnected) {
1144 auto task = [this]() {
1145 SendCastEvent(true);
1146 ScreenSessionPublish::GetInstance().PublishCastPlugInEvent();
1147 };
1148 taskScheduler_->PostAsyncTask(task, "SendCastEventTrue");
1149 TLOGI(WmsLogTag::DMS, "PostAsyncTask SendCastEventTrue");
1150 } else {
1151 auto task = [this]() {
1152 SendCastEvent(false);
1153 ScreenSessionPublish::GetInstance().PublishCastPlugOutEvent();
1154 };
1155 taskScheduler_->PostAsyncTask(task, "SendCastEventFalse");
1156 TLOGI(WmsLogTag::DMS, "PostAsyncTask SendCastEventFalse");
1157 }
1158 }
1159
PhyMirrorConnectWakeupScreen()1160 void ScreenSessionManager::PhyMirrorConnectWakeupScreen()
1161 {
1162 #ifdef WM_MULTI_SCREEN_ENABLE
1163 if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "mirror") {
1164 TLOGI(WmsLogTag::DMS, "Connect to an external screen to wakeup the phone screen");
1165 FixPowerStatus();
1166 }
1167 #endif
1168 }
1169
GetIsCurrentInUseById(ScreenId screenId)1170 bool ScreenSessionManager::GetIsCurrentInUseById(ScreenId screenId)
1171 {
1172 auto session = GetScreenSession(screenId);
1173 if (session == nullptr) {
1174 TLOGE(WmsLogTag::DMS, "session not found");
1175 return false;
1176 }
1177 if (!session->GetIsCurrentInUse()) {
1178 TLOGE(WmsLogTag::DMS, "session not in use");
1179 return false;
1180 }
1181 return true;
1182 }
1183
SetMultiScreenDefaultRelativePosition()1184 void ScreenSessionManager::SetMultiScreenDefaultRelativePosition()
1185 {
1186 #ifdef WM_MULTI_SCREEN_ENABLE
1187 MultiScreenPositionOptions mainOptions;
1188 MultiScreenPositionOptions extendOptions;
1189 sptr<ScreenSession> mainSession = nullptr;
1190 sptr<ScreenSession> extendSession = nullptr;
1191 {
1192 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1193 for (auto sessionIt : screenSessionMap_) {
1194 auto screenSession = sessionIt.second;
1195 if (screenSession == nullptr) {
1196 TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64,
1197 sessionIt.first);
1198 continue;
1199 }
1200 if (screenSession->GetIsRealScreen()) {
1201 if (screenSession->GetIsExtend() && extendSession == nullptr) {
1202 extendSession = screenSession;
1203 } else {
1204 mainSession = screenSession;
1205 }
1206 }
1207 }
1208 }
1209 if (extendSession != nullptr && mainSession != nullptr) {
1210 ScreenProperty mainProperty = mainSession->GetScreenProperty();
1211 int32_t mainWidth = mainProperty.GetBounds().rect_.GetWidth();
1212 if (g_isPcDevice) {
1213 mainOptions = { mainSession->GetRSScreenId(), 0, 0 };
1214 extendOptions = { extendSession->GetRSScreenId(), mainWidth, 0 };
1215 } else {
1216 mainOptions = { mainSession->GetScreenId(), 0, 0 };
1217 extendOptions = { extendSession->GetScreenId(), mainWidth, 0 };
1218 }
1219 auto ret = SetMultiScreenRelativePosition(mainOptions, extendOptions);
1220 if (ret != DMError::DM_OK) {
1221 TLOGE(WmsLogTag::DMS, "set Relative Position failed, DMError:%{public}d", static_cast<int32_t>(ret));
1222 }
1223 }
1224 #endif
1225 }
1226
GetAndMergeEdidInfo(sptr<ScreenSession> screenSession)1227 void ScreenSessionManager::GetAndMergeEdidInfo(sptr<ScreenSession> screenSession)
1228 {
1229 ScreenId screenId = screenSession->GetScreenId();
1230 struct BaseEdid edid;
1231 int32_t fillInfo = 4;
1232 if (!GetEdid(screenId, edid)) {
1233 TLOGE(WmsLogTag::DMS, "get EDID failed.");
1234 return;
1235 }
1236 std::string serialNumber = ConvertEdidToString(edid);
1237 TLOGI(WmsLogTag::DMS, "serialNumber: %{public}s", serialNumber.c_str());
1238 screenSession->SetSerialNumber(serialNumber);
1239 if (g_isPcDevice) {
1240 if (!edid.displayProductName_.empty()) {
1241 screenSession->SetName(edid.displayProductName_);
1242 } else {
1243 std::string productCodeStr;
1244 std::string connector = "-";
1245 std::ostringstream oss;
1246 oss << std::hex << std::uppercase << std::setw(fillInfo) << std::setfill('0') << edid.productCode_;
1247 productCodeStr = oss.str();
1248 screenSession->SetName(edid.manufacturerName_ + connector + productCodeStr);
1249 }
1250 }
1251 }
1252
ConvertEdidToString(const struct BaseEdid edid)1253 std::string ScreenSessionManager::ConvertEdidToString(const struct BaseEdid edid)
1254 {
1255 std::string edidInfo = edid.manufacturerName_ + std::to_string(edid.productCode_)
1256 + std::to_string(edid.serialNumber_) + std::to_string(edid.weekOfManufactureOrModelYearFlag_)
1257 + std::to_string(edid.yearOfManufactureOrModelYear_);
1258 TLOGI(WmsLogTag::DMS, "edidInfo: %{public}s", edidInfo.c_str());
1259 std::hash<std::string> hasher;
1260 std::size_t hashValue = hasher(edidInfo);
1261 std::ostringstream oss;
1262 oss << std::hex << std::uppercase << hashValue;
1263 return oss.str();
1264 }
1265
DisconnectScreenIfScreenInfoNull(sptr<ScreenSession> & screenSession)1266 void ScreenSessionManager::DisconnectScreenIfScreenInfoNull(sptr<ScreenSession>& screenSession)
1267 {
1268 #ifdef FOLD_ABILITY_ENABLE
1269 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1270 TLOGI(WmsLogTag::DMS, "not superFoldDisplayDevice");
1271 return;
1272 }
1273 auto clientProxy = GetClientProxy();
1274 if (!clientProxy) {
1275 TLOGE(WmsLogTag::DMS, "clientProxy is null");
1276 return;
1277 }
1278 if (screenSession == nullptr) {
1279 TLOGE(WmsLogTag::DMS, "screenSession is null");
1280 return;
1281 }
1282 if (IsDefaultMirrorMode(screenSession->GetRSScreenId()) &&
1283 screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
1284 clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenSession->GetRSScreenId()),
1285 ScreenEvent::DISCONNECTED);
1286 }
1287 #endif
1288 }
1289
RecoverRestoredMultiScreenMode(sptr<ScreenSession> screenSession)1290 bool ScreenSessionManager::RecoverRestoredMultiScreenMode(sptr<ScreenSession> screenSession)
1291 {
1292 #ifdef WM_MULTI_SCREEN_ENABLE
1293 if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL) {
1294 TLOGI(WmsLogTag::DMS, "not real screen, return before recover.");
1295 return true;
1296 }
1297 std::map<std::string, MultiScreenInfo> multiScreenInfoMap = ScreenSettingHelper::GetMultiScreenInfo();
1298 std::string serialNumber = screenSession->GetSerialNumber();
1299 if (!CheckMultiScreenInfoMap(multiScreenInfoMap, serialNumber)) {
1300 DisconnectScreenIfScreenInfoNull(screenSession);
1301 return false;
1302 }
1303 auto info = multiScreenInfoMap[serialNumber];
1304 if (info.outerOnly) {
1305 SetIsOuterOnlyMode(true);
1306 MultiScreenModeChange(SCREEN_ID_OUTER_ONLY, SCREEN_ID_OUTER_ONLY, "off");
1307 return true;
1308 }
1309 sptr<ScreenSession> internalSession = GetInternalScreenSession();
1310 if (internalSession == nullptr) {
1311 TLOGE(WmsLogTag::DMS, "internalSession is nullptr");
1312 return false;
1313 }
1314 if (info.isExtendMain) {
1315 TLOGI(WmsLogTag::DMS, "extend screen is main");
1316 info.mainScreenOption.screenId_ = screenSession->GetRSScreenId();
1317 info.secondaryScreenOption.screenId_ = internalSession->GetRSScreenId();
1318 } else {
1319 TLOGI(WmsLogTag::DMS, "extend screen is not main");
1320 info.mainScreenOption.screenId_ = internalSession->GetRSScreenId();
1321 info.secondaryScreenOption.screenId_ = screenSession->GetRSScreenId();
1322 }
1323 if (info.multiScreenMode == MultiScreenMode::SCREEN_MIRROR) {
1324 SetMultiScreenMode(info.mainScreenOption.screenId_, info.secondaryScreenOption.screenId_, info.multiScreenMode);
1325 TLOGW(WmsLogTag::DMS, "mirror, return befor OnScreenConnectionChanged");
1326 ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_MIRROR);
1327 return true;
1328 }
1329 SetMultiScreenMode(info.mainScreenOption.screenId_, info.secondaryScreenOption.screenId_, info.multiScreenMode);
1330 auto ret = SetMultiScreenRelativePosition(info.mainScreenOption, info.secondaryScreenOption);
1331 if (ret != DMError::DM_OK) {
1332 SetMultiScreenDefaultRelativePosition();
1333 }
1334 ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_EXTEND);
1335 return true;
1336 #else
1337 return false;
1338 #endif
1339 }
1340
CheckMultiScreenInfoMap(std::map<std::string,MultiScreenInfo> multiScreenInfoMap,const std::string & serialNumber)1341 bool ScreenSessionManager::CheckMultiScreenInfoMap(std::map<std::string, MultiScreenInfo> multiScreenInfoMap,
1342 const std::string& serialNumber)
1343 {
1344 if (multiScreenInfoMap.empty()) {
1345 TLOGE(WmsLogTag::DMS, "no restored screen, use default mode!");
1346 return false;
1347 }
1348 if (serialNumber.size() == 0) {
1349 TLOGE(WmsLogTag::DMS, "serialNumber empty!");
1350 return false;
1351 }
1352 if (multiScreenInfoMap.find(serialNumber) == multiScreenInfoMap.end()) {
1353 TLOGE(WmsLogTag::DMS, "screen not found, use default mode!");
1354 return false;
1355 }
1356 return true;
1357 }
1358
ReportHandleScreenEvent(ScreenEvent screenEvent,ScreenCombination screenCombination)1359 void ScreenSessionManager::ReportHandleScreenEvent(ScreenEvent screenEvent, ScreenCombination screenCombination)
1360 {
1361 MultiScreenMode multiScreenMode;
1362 if (screenCombination == ScreenCombination::SCREEN_EXTEND) {
1363 multiScreenMode = MultiScreenMode::SCREEN_EXTEND;
1364 } else {
1365 multiScreenMode = MultiScreenMode::SCREEN_MIRROR;
1366 }
1367 int32_t ret = HiSysEventWrite(
1368 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
1369 "EXTEND_DISPLAY_PLUG_IN_AND_OUT",
1370 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
1371 "PLUG_IN_AND_OUT", static_cast<int32_t>(screenEvent),
1372 "DISPLAY_CONNECT_NUM", connectScreenNumber_,
1373 "DISPLAY_INUSED_NUM", GetCurrentInUseScreenNumber(),
1374 "EXTENSION_DISPLAY_MODE_STATUS", static_cast<int32_t>(multiScreenMode),
1375 "MAIN_DISPLAY_ID", GetInternalScreenId());
1376 if (ret != 0) {
1377 TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d", ret);
1378 }
1379 }
1380
GetCurrentInUseScreenNumber()1381 int32_t ScreenSessionManager::GetCurrentInUseScreenNumber()
1382 {
1383 int32_t inUseScreenNumber_ = 0;
1384 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1385 for (auto sessionIt : screenSessionMap_) {
1386 auto screenSession = sessionIt.second;
1387 if (screenSession == nullptr) {
1388 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
1389 continue;
1390 }
1391 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
1392 screenSession->GetIsCurrentInUse()) {
1393 TLOGI(WmsLogTag::DMS, "found screenId = %{public}" PRIu64, sessionIt.first);
1394 inUseScreenNumber_++;
1395 }
1396 }
1397 return inUseScreenNumber_;
1398 }
1399
SetCastPrivacyToRS(sptr<ScreenSession> screenSession,bool enable)1400 bool ScreenSessionManager::SetCastPrivacyToRS(sptr<ScreenSession> screenSession, bool enable)
1401 {
1402 bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId());
1403 if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL || !phyMirrorEnable) {
1404 TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"",
1405 screenSession->GetScreenId());
1406 return false;
1407 }
1408 ScreenId rsScreenId = INVALID_SCREEN_ID;
1409 if (!screenIdManager_.ConvertToRsScreenId(screenSession->GetScreenId(), rsScreenId) ||
1410 rsScreenId == INVALID_SCREEN_ID) {
1411 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
1412 return false;
1413 }
1414 rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, enable);
1415 return true;
1416 }
1417
SetCastPrivacyFromSettingData()1418 void ScreenSessionManager::SetCastPrivacyFromSettingData()
1419 {
1420 bool enable = true;
1421 bool isOK = ScreenSettingHelper::GetSettingCast(enable);
1422 TLOGI(WmsLogTag::DMS, "get setting cast done, isOK: %{public}u, enable: %{public}u", isOK, enable);
1423 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1424 for (const auto& sessionIt : screenSessionMap_) {
1425 auto screenSession = sessionIt.second;
1426 if (screenSession == nullptr) {
1427 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first);
1428 continue;
1429 }
1430 bool isSuc = SetCastPrivacyToRS(screenSession, enable);
1431 TLOGI(WmsLogTag::DMS, "set cast privacy done, isSuc:%{public}d, enable:%{public}d, screenId:%{public}" PRIu64"",
1432 isSuc, enable, sessionIt.first);
1433 }
1434 }
1435
RegisterSettingWireCastObserver(sptr<ScreenSession> & screenSession)1436 void ScreenSessionManager::RegisterSettingWireCastObserver(sptr<ScreenSession>& screenSession)
1437 {
1438 if (screenSession == nullptr) {
1439 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
1440 return;
1441 }
1442 bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId());
1443 if (!g_isPcDevice && phyMirrorEnable && screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL) {
1444 TLOGI(WmsLogTag::DMS, "Register Setting wire cast Observer");
1445 SettingObserver::UpdateFunc updateFunc = [this](const std::string& key) { SetCastPrivacyFromSettingData(); };
1446 ScreenSettingHelper::RegisterSettingWireCastObserver(updateFunc);
1447 }
1448 }
1449
UnregisterSettingWireCastObserver(ScreenId screenId)1450 void ScreenSessionManager::UnregisterSettingWireCastObserver(ScreenId screenId)
1451 {
1452 if (g_isPcDevice) {
1453 return;
1454 }
1455 {
1456 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1457 for (const auto& sessionIt : screenSessionMap_) {
1458 auto screenSession = sessionIt.second;
1459 if (screenSession == nullptr) {
1460 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first);
1461 continue;
1462 }
1463 bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId());
1464 if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL || !phyMirrorEnable) {
1465 TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"", sessionIt.first);
1466 continue;
1467 }
1468 if (screenSession ->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR &&
1469 screenSession->GetScreenId() != screenId) {
1470 return;
1471 }
1472 }
1473 }
1474 ScreenSettingHelper::UnregisterSettingWireCastObserver();
1475 TLOGI(WmsLogTag::DMS, "unregister Setting wire cast Observer");
1476 }
1477
SwitchSubscriberInit()1478 void ScreenSessionManager::SwitchSubscriberInit()
1479 {
1480 switchId_ = MMI::InputManager::GetInstance()->SubscribeSwitchEvent(
1481 [this](std::shared_ptr<OHOS::MMI::SwitchEvent> switchEvent) {
1482 if (switchEvent->GetSwitchValue() == MMI::SwitchEvent::SWITCH_OFF) {
1483 SetLapTopLidOpenStatus(false);
1484 } else {
1485 SetLapTopLidOpenStatus(true);
1486 }
1487 }
1488 );
1489 TLOGD(WmsLogTag::DMS, "switchId is: %{public}d", switchId_);
1490 }
1491
IsLapTopLidOpen() const1492 bool ScreenSessionManager::IsLapTopLidOpen() const
1493 {
1494 return isLapTopLidOpen_.load();
1495 }
1496
SetLapTopLidOpenStatus(bool isLapTopLidOpen)1497 void ScreenSessionManager::SetLapTopLidOpenStatus(bool isLapTopLidOpen)
1498 {
1499 isLapTopLidOpen_.store(isLapTopLidOpen);
1500 TLOGI(WmsLogTag::DMS, "isLapTopLidOpen is: %{public}d", static_cast<int32_t>(isLapTopLidOpen));
1501 }
1502
HandleScreenConnectEvent(sptr<ScreenSession> screenSession,ScreenId screenId,ScreenEvent screenEvent)1503 void ScreenSessionManager::HandleScreenConnectEvent(sptr<ScreenSession> screenSession,
1504 ScreenId screenId, ScreenEvent screenEvent)
1505 {
1506 bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
1507 HandlePhysicalMirrorConnect(screenSession, phyMirrorEnable);
1508 auto clientProxy = GetClientProxy();
1509 #ifdef FOLD_ABILITY_ENABLE
1510 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1511 SuperFoldStateManager::GetInstance().RefreshExternalRegion();
1512 }
1513 if (foldScreenController_ != nullptr) {
1514 if ((screenId == 0 || (screenId == SCREEN_ID_MAIN && isCoordinationFlag_ == true)) && clientProxy) {
1515 TLOGW(WmsLogTag::DMS, "event: connect %{public}" PRIu64 ", %{public}" PRIu64 ", "
1516 "name=%{public}s", screenId, screenSession->GetRSScreenId(), screenSession->GetName().c_str());
1517 clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1518 }
1519 return;
1520 }
1521 #endif
1522 if (clientProxy && g_isPcDevice) {
1523 {
1524 std::unique_lock<std::mutex> lock(displayAddMutex_);
1525 needWaitAvailableArea_ = true;
1526 }
1527 clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1528 sptr<ScreenSession> internalSession = GetInternalScreenSession();
1529 if (!RecoverRestoredMultiScreenMode(screenSession)) {
1530 SetMultiScreenDefaultRelativePosition();
1531 ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_EXTEND);
1532 }
1533 sptr<ScreenSession> newInternalSession = GetInternalScreenSession();
1534 if (newInternalSession != nullptr && internalSession != nullptr &&
1535 internalSession->GetScreenId() != newInternalSession->GetScreenId()) {
1536 TLOGW(WmsLogTag::DMS, "main screen changed, reset screenSession.");
1537 screenSession = internalSession;
1538 }
1539 SetExtendedScreenFallbackPlan(screenSession->GetScreenId());
1540 }
1541 if (clientProxy && !g_isPcDevice && !phyMirrorEnable) {
1542 TLOGW(WmsLogTag::DMS, "screen connect and notify to scb.");
1543 clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), screenEvent);
1544 }
1545 if (phyMirrorEnable) {
1546 NotifyScreenConnected(screenSession->ConvertToScreenInfo());
1547 // when display add, need wait update available area, ensure display info is accurate
1548 WaitUpdateAvailableAreaForPc();
1549 NotifyDisplayCreate(screenSession->ConvertToDisplayInfo());
1550 }
1551 TLOGW(WmsLogTag::DMS, "connect end. ScreenId: %{public}" PRIu64, screenId);
1552 }
1553
WaitUpdateAvailableAreaForPc()1554 void ScreenSessionManager::WaitUpdateAvailableAreaForPc()
1555 {
1556 std::unique_lock<std::mutex> lock(displayAddMutex_);
1557 TLOGI(WmsLogTag::DMS, "begin wait notify display. need wait: %{public}d", needWaitAvailableArea_);
1558 if (g_isPcDevice && needWaitAvailableArea_) {
1559 TLOGI(WmsLogTag::DMS, "need wait update available area");
1560 if (displayAddCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_UPDATE_AVAILABLE_MS)) ==
1561 std::cv_status::timeout) {
1562 TLOGE(WmsLogTag::DMS, "wait update available area timeout");
1563 needWaitAvailableArea_ = false;
1564 }
1565 }
1566 }
1567
HandleScreenDisconnectEvent(sptr<ScreenSession> screenSession,ScreenId screenId,ScreenEvent screenEvent)1568 void ScreenSessionManager::HandleScreenDisconnectEvent(sptr<ScreenSession> screenSession,
1569 ScreenId screenId, ScreenEvent screenEvent)
1570 {
1571 if (!screenSession) {
1572 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
1573 return;
1574 }
1575 RemoveScreenCastInfo(screenId);
1576 if (g_isPcDevice) {
1577 ScreenId rsId = screenSession->GetRSScreenId();
1578 if (screenId != rsId && screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL) {
1579 screenSession = GetScreenSessionByRsId(screenId);
1580 if (!screenSession) {
1581 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, rsid: %{public}" PRIu64, rsId);
1582 return;
1583 }
1584 }
1585 }
1586 HandlePCScreenDisconnect(screenSession);
1587 bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
1588 HandlePhysicalMirrorDisconnect(screenSession, screenId, phyMirrorEnable);
1589 auto clientProxy = GetClientProxy();
1590 if (clientProxy) {
1591 TLOGW(WmsLogTag::DMS, "screen disconnect and notify to scb.");
1592 clientProxy->OnScreenConnectionChanged(GetSessionOption(screenSession, screenId), ScreenEvent::DISCONNECTED);
1593 }
1594 #ifdef WM_MULTI_SCREEN_ENABLE
1595 HandleExtendScreenDisconnect(screenId);
1596 #endif
1597 HandleMapWhenScreenDisconnect(screenId);
1598 if (g_isPcDevice) {
1599 ScreenCombination screenCombination = screenSession->GetScreenCombination();
1600 ReportHandleScreenEvent(ScreenEvent::DISCONNECTED, screenCombination);
1601 SetMultiScreenFrameControl();
1602 }
1603 if (!(screenId == SCREEN_ID_MAIN && isCoordinationFlag_ == true)) {
1604 std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
1605 phyScreenPropMap_.erase(screenId);
1606 }
1607 if (phyMirrorEnable) {
1608 NotifyScreenDisconnected(screenSession->GetScreenId());
1609 NotifyDisplayDestroy(screenSession->GetScreenId());
1610 isPhyScreenConnected_ = false;
1611 }
1612 if (!g_isPcDevice && phyMirrorEnable) {
1613 UnregisterSettingWireCastObserver(screenId);
1614 }
1615 TLOGW(WmsLogTag::DMS, "disconnect success. ScreenId: %{public}" PRIu64 "", screenId);
1616 }
1617
HandlePhysicalMirrorConnect(sptr<ScreenSession> screenSession,bool phyMirrorEnable)1618 void ScreenSessionManager::HandlePhysicalMirrorConnect(sptr<ScreenSession> screenSession, bool phyMirrorEnable)
1619 {
1620 if (phyMirrorEnable) {
1621 PhyMirrorConnectWakeupScreen();
1622 NotifyCastWhenScreenConnectChange(true);
1623 isPhyScreenConnected_ = true;
1624 RegisterSettingWireCastObserver(screenSession);
1625 if (!g_isPcDevice) {
1626 ScreenPowerUtils::EnablePowerForceTimingOut();
1627 DisablePowerOffRenderControl(0);
1628 }
1629 }
1630 }
1631
HandlePhysicalMirrorDisconnect(sptr<ScreenSession> screenSession,ScreenId screenId,bool phyMirrorEnable)1632 void ScreenSessionManager::HandlePhysicalMirrorDisconnect(sptr<ScreenSession> screenSession, ScreenId screenId,
1633 bool phyMirrorEnable)
1634 {
1635 if (phyMirrorEnable) {
1636 NotifyCastWhenScreenConnectChange(false);
1637 FreeDisplayMirrorNodeInner(screenSession);
1638 isPhyScreenConnected_ = false;
1639 if (!g_isPcDevice) {
1640 std::vector<ScreenId> screenIdsToExclude = { screenId };
1641 if (!HasCastEngineOrPhyMirror(screenIdsToExclude)) {
1642 ScreenPowerUtils::DisablePowerForceTimingOut();
1643 ScreenPowerUtils::LightAndLockScreen("light and lock screen");
1644 }
1645 }
1646 }
1647 }
1648
HandleMapWhenScreenDisconnect(ScreenId screenId)1649 void ScreenSessionManager::HandleMapWhenScreenDisconnect(ScreenId screenId)
1650 {
1651 {
1652 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1653 screenSessionMap_.erase(screenId);
1654 }
1655 {
1656 std::lock_guard<std::recursive_mutex> lock(physicalScreenSessionMapMutex_);
1657 physicalScreenSessionMap_.erase(screenId);
1658 }
1659 }
1660
HandlePCScreenDisconnect(sptr<ScreenSession> & screenSession)1661 void ScreenSessionManager::HandlePCScreenDisconnect(sptr<ScreenSession>& screenSession)
1662 {
1663 #ifdef WM_MULTI_SCREEN_ENABLE
1664 ScreenCombination screenCombination = screenSession->GetScreenCombination();
1665 if (!g_isPcDevice) {
1666 TLOGE(WmsLogTag::DMS, "not PC device, return before process.");
1667 return;
1668 }
1669 if (screenCombination == ScreenCombination::SCREEN_MAIN) {
1670 TLOGW(WmsLogTag::DMS, "reset to inner screen to main.");
1671 HandleMainScreenDisconnect(screenSession);
1672 }
1673 screenCombination = screenSession->GetScreenCombination();
1674 if (screenCombination == ScreenCombination::SCREEN_EXTEND) {
1675 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_EXIT_STR);
1676 } else {
1677 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_MIRROR, MULTI_SCREEN_EXIT_STR);
1678 NotifyCaptureStatusChanged(false);
1679 }
1680 MultiScreenPositionOptions defaultOptions = { GetDefaultScreenId(), 0, 0 };
1681 SetRelativePositionForDisconnect(defaultOptions);
1682 #endif
1683 }
1684
HandleMainScreenDisconnect(sptr<ScreenSession> & screenSession)1685 void ScreenSessionManager::HandleMainScreenDisconnect(sptr<ScreenSession>& screenSession)
1686 {
1687 #ifdef WM_MULTI_SCREEN_ENABLE
1688 if (!g_isPcDevice) {
1689 TLOGE(WmsLogTag::DMS, "not PC device, return before process.");
1690 return;
1691 }
1692 sptr<ScreenSession> internalSession = GetInternalScreenSession();
1693 if (internalSession == nullptr) {
1694 TLOGE(WmsLogTag::DMS, "internalSession is nullptr");
1695 return;
1696 }
1697 if (GetIsOuterOnlyMode()) {
1698 TLOGI(WmsLogTag::DMS, "exit outer only mode.");
1699 SetIsOuterOnlyMode(false);
1700 ExitOuterOnlyMode(internalSession->GetRSScreenId(), screenSession->GetRSScreenId(),
1701 MultiScreenMode::SCREEN_MIRROR);
1702 } else {
1703 SetIsOuterOnlyMode(false);
1704 MultiScreenModeChange(internalSession->GetRSScreenId(), screenSession->GetRSScreenId(),
1705 SCREEN_MIRROR);
1706 }
1707 if (screenSession->GetScreenId() == screenSession->GetRSScreenId()) {
1708 TLOGW(WmsLogTag::DMS, "main screen changed, reset screenSession.");
1709 screenSession = internalSession;
1710 } else {
1711 if (!screenSession->GetIsInternal() && screenSession->GetIsCurrentInUse()) {
1712 TLOGW(WmsLogTag::DMS, "main screen not changed, reset internal session.");
1713 sptr<ScreenSession> newInternalSession = GetInternalScreenSession();
1714 ResetInternalScreenSession(newInternalSession, screenSession);
1715 screenSession = newInternalSession;
1716 }
1717 }
1718 #endif
1719 }
1720
ResetInternalScreenSession(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)1721 void ScreenSessionManager::ResetInternalScreenSession(sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
1722 {
1723 #ifdef WM_MULTI_SCREEN_ENABLE
1724 if (innerScreen == nullptr || externalScreen == nullptr) {
1725 TLOGE(WmsLogTag::DMS, "screen sessions null.");
1726 return;
1727 }
1728 std::ostringstream oss;
1729 oss << "innerScreen screenId: " << innerScreen->GetScreenId()
1730 << ", rsId: " << innerScreen->GetRSScreenId()
1731 << ", externalScreen screenId: " << externalScreen->GetScreenId()
1732 << ", rsId: " << externalScreen->GetRSScreenId();
1733 oss << std::endl;
1734 TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
1735
1736 /* reset display node */
1737 auto mainNode = innerScreen->GetDisplayNode();
1738 auto extendNode = externalScreen->GetDisplayNode();
1739 ScreenId innerRSId = innerScreen->GetRSScreenId();
1740 ScreenId externalRSId = externalScreen->GetRSScreenId();
1741 if (mainNode != nullptr) {
1742 mainNode->SetScreenId(externalRSId);
1743 RSInterfaces::GetInstance().SetScreenOffset(externalRSId, 0, 0);
1744 }
1745 if (extendNode != nullptr) {
1746 extendNode->SetScreenId(innerRSId);
1747 RSInterfaces::GetInstance().SetScreenOffset(innerRSId, 0, 0);
1748 }
1749 RSTransactionAdapter::FlushImplicitTransaction(
1750 {innerScreen->GetRSUIContext(), externalScreen->GetRSUIContext()});
1751
1752 /* reset physical info */
1753 MultiScreenChangeUtils::ScreenPhysicalInfoChange(innerScreen, externalScreen);
1754
1755 /* reset relative position */
1756 innerScreen->SetStartPosition(0, 0);
1757 externalScreen->SetStartPosition(0, 0);
1758
1759 /* reset combination */
1760 innerScreen->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
1761 externalScreen->SetScreenCombination(ScreenCombination::SCREEN_MAIN);
1762 innerScreen->SetIsExtend(true);
1763 externalScreen->SetIsExtend(false);
1764
1765 /* set screen available */
1766 innerScreen->SetScreenAvailableStatus(true);
1767 externalScreen->SetScreenAvailableStatus(true);
1768 #endif
1769 }
1770
OnHgmRefreshRateChange(uint32_t refreshRate)1771 void ScreenSessionManager::OnHgmRefreshRateChange(uint32_t refreshRate)
1772 {
1773 GetDefaultScreenId();
1774 TLOGD(WmsLogTag::DMS, "Set refreshRate: %{public}u, defaultScreenId: %{public}" PRIu64"",
1775 refreshRate, defaultScreenId_);
1776 sptr<ScreenSession> screenSession = GetScreenSession(defaultScreenId_);
1777 if (screenSession) {
1778 screenSession->UpdateRefreshRate(refreshRate);
1779 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
1780 DisplayChangeEvent::UPDATE_REFRESHRATE);
1781 UpdateCoordinationRefreshRate(refreshRate);
1782 std::map<ScreenId, sptr<ScreenSession>> screenSessionMap;
1783 {
1784 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1785 screenSessionMap = screenSessionMap_;
1786 }
1787 for (const auto &sessionItem : screenSessionMap) {
1788 const auto &screenSessionItem = sessionItem.second;
1789 const auto &screenType = screenSessionItem->GetScreenProperty().GetScreenType();
1790 if (screenType == ScreenType::VIRTUAL) {
1791 screenSessionItem->UpdateRefreshRate(refreshRate);
1792 screenSessionItem->SetSupportedRefreshRate({refreshRate});
1793 NotifyDisplayChanged(screenSessionItem->ConvertToDisplayInfo(),
1794 DisplayChangeEvent::UPDATE_REFRESHRATE);
1795 }
1796 }
1797 } else {
1798 TLOGE(WmsLogTag::DMS, "Get default screen session failed.");
1799 }
1800 return;
1801 }
1802
IsPhysicalScreenAndInUse(sptr<ScreenSession> screenSession) const1803 bool ScreenSessionManager::IsPhysicalScreenAndInUse(sptr<ScreenSession> screenSession) const
1804 {
1805 if (!screenSession) {
1806 return false;
1807 }
1808 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
1809 screenSession->GetIsCurrentInUse()) {
1810 return true;
1811 }
1812 return false;
1813 }
1814
SetMultiScreenFrameControl(void)1815 void ScreenSessionManager::SetMultiScreenFrameControl(void)
1816 {
1817 #ifdef WM_MULTI_SCREEN_CTL_ABILITY_ENABLE
1818 uint32_t count = 0;
1819 {
1820 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1821 for (auto sessionIt : screenSessionMap_) {
1822 if (IsPhysicalScreenAndInUse(sessionIt.second)) {
1823 count++;
1824 }
1825 }
1826 }
1827 if (count >= NUMBER_OF_PHYSICAL_SCREEN) {
1828 TLOGW(WmsLogTag::DMS, "MultiScreen control frame rate to 60");
1829 EventInfo event = { "VOTER_MUTIPHSICALSCREEN", ADD_VOTE, OLED_60_HZ, OLED_60_HZ };
1830 rsInterface_.NotifyRefreshRateEvent(event);
1831 } else {
1832 TLOGW(WmsLogTag::DMS, "Disabling frame rate control");
1833 EventInfo event = { "VOTER_MUTIPHSICALSCREEN", REMOVE_VOTE };
1834 rsInterface_.NotifyRefreshRateEvent(event);
1835 }
1836 #endif
1837 }
1838
GetScreenSession(ScreenId screenId) const1839 sptr<ScreenSession> ScreenSessionManager::GetScreenSession(ScreenId screenId) const
1840 {
1841 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1842 if (screenSessionMap_.empty()) {
1843 screenEventTracker_.LogWarningAllInfos();
1844 }
1845 auto iter = screenSessionMap_.find(screenId);
1846 if (iter == screenSessionMap_.end()) {
1847 TLOGW(WmsLogTag::DMS, "not found screen session id: %{public}" PRIu64".", screenId);
1848 return nullptr;
1849 }
1850 return iter->second;
1851 }
1852
GetDefaultScreenSession()1853 sptr<ScreenSession> ScreenSessionManager::GetDefaultScreenSession()
1854 {
1855 GetDefaultScreenId();
1856 return GetScreenSession(defaultScreenId_);
1857 }
1858
HookDisplayInfoByUid(sptr<DisplayInfo> displayInfo,const sptr<ScreenSession> & screenSession)1859 sptr<DisplayInfo> ScreenSessionManager::HookDisplayInfoByUid(sptr<DisplayInfo> displayInfo,
1860 const sptr<ScreenSession>& screenSession)
1861 {
1862 if (displayInfo == nullptr) {
1863 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1864 return nullptr;
1865 }
1866 auto uid = IPCSkeleton::GetCallingUid();
1867 std::shared_lock<std::shared_mutex> lock(hookInfoMutex_);
1868 if (displayHookMap_.find(uid) != displayHookMap_.end()) {
1869 auto info = displayHookMap_[uid];
1870 std::ostringstream oss;
1871 oss << "hW: " << info.width_ << ", hH: " << info.height_ << ", hD: " << info.density_
1872 << ", hR: " << info.rotation_ << ", hER: " << info.enableHookRotation_
1873 << " hO: " << info.displayOrientation_ << ", hEO: " << info.enableHookDisplayOrientation_
1874 << ", dW: " << displayInfo->GetHeight() << ", dH: " << displayInfo->GetHeight()
1875 << ", dR: " << static_cast<uint32_t>(displayInfo->GetRotation())
1876 << ", dO: " << static_cast<uint32_t>(displayInfo->GetDisplayOrientation());
1877 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
1878
1879 displayInfo->SetWidth(info.width_);
1880 displayInfo->SetHeight(info.height_);
1881 displayInfo->SetVirtualPixelRatio(info.density_);
1882 if (info.enableHookRotation_) {
1883 if (screenSession) {
1884 Rotation targetRotation = screenSession->ConvertIntToRotation(static_cast<int32_t>(info.rotation_));
1885 displayInfo->SetRotation(targetRotation);
1886 DisplayOrientation targetOrientation = screenSession->CalcDisplayOrientation(targetRotation,
1887 FoldDisplayMode::UNKNOWN);
1888 TLOGI(WmsLogTag::DMS, "tR: %{public}u, tO: %{public}u", targetRotation, targetOrientation);
1889 displayInfo->SetDisplayOrientation(targetOrientation);
1890 } else {
1891 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, screenSession is nullptr.");
1892 return nullptr;
1893 }
1894 }
1895 if (info.enableHookDisplayOrientation_ &&
1896 info.displayOrientation_ < static_cast<uint32_t>(DisplayOrientation::UNKNOWN)) {
1897 displayInfo->SetDisplayOrientation(static_cast<DisplayOrientation>(info.displayOrientation_));
1898 }
1899 }
1900 return displayInfo;
1901 }
1902
GetDefaultDisplayInfo()1903 sptr<DisplayInfo> ScreenSessionManager::GetDefaultDisplayInfo()
1904 {
1905 GetDefaultScreenId();
1906 sptr<ScreenSession> screenSession = GetScreenSession(defaultScreenId_);
1907 std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
1908 if (screenSession) {
1909 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1910 if (displayInfo == nullptr) {
1911 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1912 return nullptr;
1913 }
1914 // 在PC/PAD上安装的竖屏应用以及白名单中的应用在显示状态非全屏时需要hook displayinfo
1915 displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
1916 return displayInfo;
1917 } else {
1918 TLOGE(WmsLogTag::DMS, "failed");
1919 return nullptr;
1920 }
1921 }
1922
GetDisplayInfoById(DisplayId displayId)1923 sptr<DisplayInfo> ScreenSessionManager::GetDisplayInfoById(DisplayId displayId)
1924 {
1925 TLOGD(WmsLogTag::DMS, "enter, displayId: %{public}" PRIu64" ", displayId);
1926 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1927 for (auto sessionIt : screenSessionMap_) {
1928 auto screenSession = sessionIt.second;
1929 if (screenSession == nullptr) {
1930 TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64 "",
1931 sessionIt.first);
1932 continue;
1933 }
1934 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
1935 if (displayInfo == nullptr) {
1936 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1937 continue;
1938 }
1939 if (displayId == displayInfo->GetDisplayId()) {
1940 TLOGD(WmsLogTag::DMS, "success");
1941 displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
1942 return displayInfo;
1943 }
1944 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1945 continue;
1946 }
1947 if (!screenSession->GetScreenProperty().GetIsFakeInUse()) {
1948 continue;
1949 }
1950 sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
1951 if (fakeScreenSession == nullptr) {
1952 TLOGE(WmsLogTag::DMS, "error, fakeScreenSession is nullptr.");
1953 continue;
1954 }
1955 sptr<DisplayInfo> fakeDisplayInfo = fakeScreenSession->ConvertToDisplayInfo();
1956 if (fakeDisplayInfo == nullptr) {
1957 TLOGE(WmsLogTag::DMS, "error, fakeDisplayInfo is nullptr.");
1958 continue;
1959 }
1960 fakeDisplayInfo = HookDisplayInfoByUid(fakeDisplayInfo, fakeScreenSession);
1961 DisplayId fakeDisplayId = fakeDisplayInfo->GetDisplayId();
1962 if (displayId == fakeDisplayId) {
1963 TLOGD(WmsLogTag::DMS, "find fake success");
1964 return fakeDisplayInfo;
1965 }
1966 }
1967 TLOGE(WmsLogTag::DMS, "failed. displayId: %{public}" PRIu64" ", displayId);
1968 return nullptr;
1969 }
1970
GetVisibleAreaDisplayInfoById(DisplayId displayId)1971 sptr<DisplayInfo> ScreenSessionManager::GetVisibleAreaDisplayInfoById(DisplayId displayId)
1972 {
1973 TLOGD(WmsLogTag::DMS, "enter, displayId: %{public}" PRIu64" ", displayId);
1974 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
1975 for (auto sessionIt : screenSessionMap_) {
1976 auto screenSession = sessionIt.second;
1977 if (screenSession == nullptr) {
1978 TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64 "",
1979 sessionIt.first);
1980 continue;
1981 }
1982 sptr<DisplayInfo> displayInfo = screenSession->ConvertToRealDisplayInfo();
1983 if (displayInfo == nullptr) {
1984 TLOGI(WmsLogTag::DMS, "ConvertToDisplayInfo error, displayInfo is nullptr.");
1985 continue;
1986 }
1987 if (displayId != displayInfo->GetDisplayId()) {
1988 continue;
1989 }
1990 TLOGD(WmsLogTag::DMS, "success");
1991 displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
1992 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
1993 return displayInfo;
1994 }
1995 #ifdef FOLD_ABILITY_ENABLE
1996 SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
1997 bool isSystemKeyboardOn = SuperFoldStateManager::GetInstance().GetSystemKeyboardStatus();
1998 RRect bounds = screenSession->GetScreenProperty().GetBounds();
1999 auto screenWdith = bounds.rect_.GetWidth();
2000 auto screenHeight = bounds.rect_.GetHeight();
2001 // Adjust screen height when physical keyboard attach or touchPad virtual Keyboard on
2002 if (status == SuperFoldStatus::KEYBOARD || isSystemKeyboardOn) {
2003 if (screenWdith > screenHeight) {
2004 std::swap(screenWdith, screenHeight);
2005 }
2006 DMRect creaseRect = screenSession->GetScreenProperty().GetCreaseRect();
2007 if (creaseRect.posY_ > 0) {
2008 displayInfo->SetHeight(creaseRect.posY_);
2009 } else {
2010 displayInfo->SetHeight(screenHeight / HALF_SCREEN_PARAM);
2011 }
2012 displayInfo->SetWidth(screenWdith);
2013 } else {
2014 displayInfo->SetWidth(screenWdith);
2015 displayInfo->SetHeight(screenHeight);
2016 }
2017 return displayInfo;
2018 #endif
2019 }
2020 TLOGE(WmsLogTag::DMS, "GetVisibleAreaDisplayInfoById failed. displayId: %{public}" PRIu64" ", displayId);
2021 return nullptr;
2022 }
2023
GetDisplayInfoByScreen(ScreenId screenId)2024 sptr<DisplayInfo> ScreenSessionManager::GetDisplayInfoByScreen(ScreenId screenId)
2025 {
2026 TLOGD(WmsLogTag::DMS, "enter, screenId: %{public}" PRIu64"", screenId);
2027 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2028 for (auto sessionIt : screenSessionMap_) {
2029 auto screenSession = sessionIt.second;
2030 if (screenSession == nullptr) {
2031 TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId:%{public}" PRIu64"",
2032 sessionIt.first);
2033 continue;
2034 }
2035 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
2036 if (displayInfo == nullptr) {
2037 TLOGI(WmsLogTag::DMS, "error, displayInfo is nullptr.");
2038 continue;
2039 }
2040 if (screenId == displayInfo->GetScreenId()) {
2041 return displayInfo;
2042 }
2043 }
2044 TLOGE(WmsLogTag::DMS, "failed. screenId: %{public}" PRIu64" ", screenId);
2045 return nullptr;
2046 }
2047
GetFakeDisplayId(sptr<ScreenSession> screenSession)2048 DisplayId ScreenSessionManager::GetFakeDisplayId(sptr<ScreenSession> screenSession)
2049 {
2050 sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
2051 if (fakeScreenSession == nullptr) {
2052 TLOGE(WmsLogTag::DMS, "error, fakeScreenSession is nullptr.");
2053 return DISPLAY_ID_INVALID;
2054 }
2055 sptr<DisplayInfo> fakeDisplayInfo = fakeScreenSession->ConvertToDisplayInfo();
2056 if (fakeDisplayInfo == nullptr) {
2057 TLOGE(WmsLogTag::DMS, "error, fakeDisplayInfo is nullptr.");
2058 return DISPLAY_ID_INVALID;
2059 }
2060 DisplayId fakeDisplayId = fakeDisplayInfo->GetDisplayId();
2061 return fakeDisplayId;
2062 }
2063
GetAllDisplayIds()2064 std::vector<DisplayId> ScreenSessionManager::GetAllDisplayIds()
2065 {
2066 TLOGD(WmsLogTag::DMS, "enter");
2067 std::vector<DisplayId> res;
2068 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2069 for (auto sessionIt : screenSessionMap_) {
2070 auto screenSession = sessionIt.second;
2071 if (screenSession == nullptr) {
2072 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, ScreenId:%{public}" PRIu64"",
2073 sessionIt.first);
2074 continue;
2075 }
2076 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
2077 if (displayInfo == nullptr) {
2078 TLOGE(WmsLogTag::DMS, "error, displayInfo is nullptr.");
2079 continue;
2080 }
2081 DisplayId displayId = displayInfo->GetDisplayId();
2082 res.push_back(displayId);
2083 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
2084 continue;
2085 }
2086 if (!screenSession->GetScreenProperty().GetIsFakeInUse()) {
2087 continue;
2088 }
2089 DisplayId fakeDisplayId = GetFakeDisplayId(screenSession);
2090 if (fakeDisplayId == DISPLAY_ID_FAKE) {
2091 res.push_back(fakeDisplayId);
2092 TLOGI(WmsLogTag::DMS, "add fakeDisplayId: %{public}" PRIu64 "", fakeDisplayId);
2093 }
2094 }
2095 return res;
2096 }
2097
CalculateXYPosition(sptr<ScreenSession> firstScreenSession,sptr<ScreenSession> secondaryScreenSession)2098 void ScreenSessionManager::CalculateXYPosition(sptr<ScreenSession> firstScreenSession,
2099 sptr<ScreenSession> secondaryScreenSession)
2100 {
2101 if (firstScreenSession != nullptr &&
2102 firstScreenSession->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
2103 firstScreenSession->SetXYPosition(0, 0);
2104 NotifyDisplayChanged(firstScreenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
2105 CalculateSecondryXYPosition(firstScreenSession, secondaryScreenSession);
2106 } else if (secondaryScreenSession != nullptr &&
2107 secondaryScreenSession->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
2108 secondaryScreenSession->SetXYPosition(0, 0);
2109 NotifyDisplayChanged(secondaryScreenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
2110 CalculateSecondryXYPosition(secondaryScreenSession, firstScreenSession);
2111 } else {
2112 TLOGE(WmsLogTag::DMS, "CalculateXYPosition error!");
2113 }
2114 }
2115
CalculateSecondryXYPosition(sptr<ScreenSession> firstScreenSession,sptr<ScreenSession> secondaryScreenSession)2116 void ScreenSessionManager::CalculateSecondryXYPosition(sptr<ScreenSession> firstScreenSession,
2117 sptr<ScreenSession> secondaryScreenSession)
2118 {
2119 if (firstScreenSession == nullptr || secondaryScreenSession == nullptr) {
2120 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
2121 return;
2122 }
2123 ScreenProperty firstScreenProperty = firstScreenSession->GetScreenProperty();
2124 ScreenProperty secondaryScreenProperty = secondaryScreenSession->GetScreenProperty();
2125 int32_t firstStartX = static_cast<int32_t>(firstScreenProperty.GetStartX());
2126 int32_t firstStartY = static_cast<int32_t>(firstScreenProperty.GetStartY());
2127 int32_t secondaryStartX = static_cast<int32_t>(secondaryScreenProperty.GetStartX());
2128 int32_t secondaryStartY = static_cast<int32_t>(secondaryScreenProperty.GetStartY());
2129 int32_t secondaryX = -firstStartX + secondaryStartX;
2130 int32_t secondaryY = -firstStartY + secondaryStartY;
2131 secondaryScreenSession->SetXYPosition(secondaryX, secondaryY);
2132 NotifyDisplayChanged(secondaryScreenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
2133 }
2134
GetScreenInfoById(ScreenId screenId)2135 sptr<ScreenInfo> ScreenSessionManager::GetScreenInfoById(ScreenId screenId)
2136 {
2137 if (!SessionPermission::IsSystemCalling() &&
2138 !Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION)) {
2139 TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
2140 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2141 return nullptr;
2142 }
2143 auto screenSession = GetScreenSession(screenId);
2144 if (screenSession == nullptr) {
2145 TLOGE(WmsLogTag::DMS, "cannot find screenInfo: %{public}" PRIu64"", screenId);
2146 return nullptr;
2147 }
2148 return screenSession->ConvertToScreenInfo();
2149 }
2150
SetScreenActiveMode(ScreenId screenId,uint32_t modeId)2151 DMError ScreenSessionManager::SetScreenActiveMode(ScreenId screenId, uint32_t modeId)
2152 {
2153 #ifdef WM_SCREEN_ACTIVE_MODE_ENABLE
2154 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", modeId: %{public}u", screenId, modeId);
2155 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2156 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, calling pid: %{public}d",
2157 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2158 return DMError::DM_ERROR_NOT_SYSTEM_APP;
2159 }
2160 if (screenId == SCREEN_ID_INVALID) {
2161 TLOGE(WmsLogTag::DMS, "invalid screenId");
2162 return DMError::DM_ERROR_NULLPTR;
2163 }
2164 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2165 if (screenSession == nullptr) {
2166 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2167 return DMError::DM_ERROR_NULLPTR;
2168 }
2169 ScreenId rsScreenId = SCREEN_ID_INVALID;
2170 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
2171 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
2172 return DMError::DM_ERROR_NULLPTR;
2173 }
2174 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetScreenActiveMode(%" PRIu64", %u)", screenId, modeId);
2175 rsInterface_.SetScreenActiveMode(rsScreenId, modeId);
2176 screenSession->activeIdx_ = static_cast<int32_t>(modeId);
2177 screenSession->UpdatePropertyByActiveMode();
2178 ScreenProperty property = screenSession->GetScreenProperty();
2179 property.SetPropertyChangeReason("active mode change");
2180 screenSession->PropertyChange(property, ScreenPropertyChangeReason::CHANGE_MODE);
2181 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
2182 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
2183 #endif
2184 return DMError::DM_OK;
2185 }
2186
ConvertScreenIdToRsScreenId(ScreenId screenId,ScreenId & rsScreenId)2187 bool ScreenSessionManager::ConvertScreenIdToRsScreenId(ScreenId screenId, ScreenId& rsScreenId)
2188 {
2189 return screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
2190 }
2191
UpdateDisplayHookInfo(int32_t uid,bool enable,const DMHookInfo & hookInfo)2192 void ScreenSessionManager::UpdateDisplayHookInfo(int32_t uid, bool enable, const DMHookInfo& hookInfo)
2193 {
2194 TLOGD(WmsLogTag::DMS, "DisplayHookInfo will update");
2195 if (!SessionPermission::IsSystemCalling()) {
2196 TLOGE(WmsLogTag::DMS, "permission denied!");
2197 return;
2198 }
2199
2200 std::unique_lock<std::shared_mutex> lock(hookInfoMutex_);
2201 if (enable) {
2202 if (uid != 0) {
2203 displayHookMap_[uid] = hookInfo;
2204 }
2205 } else {
2206 displayHookMap_.erase(uid);
2207 }
2208 }
2209
GetDisplayHookInfo(int32_t uid,DMHookInfo & hookInfo)2210 void ScreenSessionManager::GetDisplayHookInfo(int32_t uid, DMHookInfo& hookInfo)
2211 {
2212 std::shared_lock<std::shared_mutex> lock(hookInfoMutex_);
2213 if (displayHookMap_.find(uid) != displayHookMap_.end()) {
2214 hookInfo = displayHookMap_[uid];
2215 }
2216 }
2217
IsFreezed(const int32_t & agentPid,const DisplayManagerAgentType & agentType)2218 bool ScreenSessionManager::IsFreezed(const int32_t& agentPid, const DisplayManagerAgentType& agentType)
2219 {
2220 std::lock_guard<std::mutex> lock(freezedPidListMutex_);
2221 if (freezedPidList_.count(agentPid) == 0) {
2222 return false;
2223 }
2224 // 冻结的应用记录应用 pid 和注册的 agentType
2225 if (pidAgentTypeMap_.count(agentPid) == 0) {
2226 std::set agentTypes = { agentType };
2227 pidAgentTypeMap_[agentPid] = agentTypes;
2228 } else {
2229 pidAgentTypeMap_[agentPid].insert(agentType);
2230 }
2231 TLOGD(WmsLogTag::DMS, "Agent is freezed, no need notify. PID: %{public}d.", agentPid);
2232 return true;
2233 }
2234
NotifyScreenChanged(sptr<ScreenInfo> screenInfo,ScreenChangeEvent event)2235 void ScreenSessionManager::NotifyScreenChanged(sptr<ScreenInfo> screenInfo, ScreenChangeEvent event)
2236 {
2237 if (screenInfo == nullptr) {
2238 TLOGE(WmsLogTag::DMS, "error, screenInfo is nullptr.");
2239 return;
2240 }
2241 {
2242 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
2243 lastScreenChangeEvent_ = event;
2244 }
2245 auto task = [=] {
2246 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
2247 TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", agent size: %{public}u",
2248 screenInfo->GetScreenId(), static_cast<uint32_t>(agents.size()));
2249 if (agents.empty()) {
2250 return;
2251 }
2252 for (auto& agent : agents) {
2253 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
2254 if (!IsFreezed(agentPid, DisplayManagerAgentType::SCREEN_EVENT_LISTENER)) {
2255 agent->OnScreenChange(screenInfo, event);
2256 }
2257 }
2258 };
2259 taskScheduler_->PostAsyncTask(task, "NotifyScreenChanged:SID:" + std::to_string(screenInfo->GetScreenId()));
2260 }
2261
SetVirtualPixelRatio(ScreenId screenId,float virtualPixelRatio)2262 DMError ScreenSessionManager::SetVirtualPixelRatio(ScreenId screenId, float virtualPixelRatio)
2263 {
2264 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2265 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
2266 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2267 return DMError::DM_ERROR_NOT_SYSTEM_APP;
2268 }
2269
2270 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2271 if (!screenSession) {
2272 TLOGE(WmsLogTag::DMS, "screen session is nullptr");
2273 return DMError::DM_ERROR_UNKNOWN;
2274 }
2275 if (screenSession->isScreenGroup_) {
2276 TLOGE(WmsLogTag::DMS, "cannot set virtual pixel ratio to the combination. screen: %{public}" PRIu64"",
2277 screenId);
2278 return DMError::DM_ERROR_NULLPTR;
2279 }
2280 // less to 1e-6 mean equal
2281 if (fabs(screenSession->GetScreenProperty().GetVirtualPixelRatio() - virtualPixelRatio) < 1e-6) {
2282 TLOGE(WmsLogTag::DMS,
2283 "The density is equivalent to the original value, no update operation is required, aborted.");
2284 return DMError::DM_OK;
2285 }
2286 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetVirtualPixelRatio(%" PRIu64", %f)", screenId,
2287 virtualPixelRatio);
2288 screenSession->SetVirtualPixelRatio(virtualPixelRatio);
2289 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
2290 sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
2291 if (fakeScreenSession != nullptr) {
2292 fakeScreenSession->SetVirtualPixelRatio(virtualPixelRatio);
2293 NotifyDisplayChanged(fakeScreenSession->ConvertToDisplayInfo(),
2294 DisplayChangeEvent::DISPLAY_VIRTUAL_PIXEL_RATIO_CHANGED);
2295 }
2296 }
2297 std::map<DisplayId, sptr<DisplayInfo>> emptyMap;
2298 OnPropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::VIRTUAL_PIXEL_RATIO_CHANGE,
2299 screenId);
2300 NotifyDisplayStateChange(screenId, screenSession->ConvertToDisplayInfo(),
2301 emptyMap, DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE);
2302 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::VIRTUAL_PIXEL_RATIO_CHANGED);
2303 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
2304 DisplayChangeEvent::DISPLAY_VIRTUAL_PIXEL_RATIO_CHANGED);
2305 if (g_isPcDevice) {
2306 sptr<ScreenSession> physicalScreen = GetPhysicalScreenSession(screenSession->GetRSScreenId());
2307 if (physicalScreen) {
2308 physicalScreen->SetVirtualPixelRatio(virtualPixelRatio);
2309 }
2310 }
2311 return DMError::DM_OK;
2312 }
2313
SetVirtualPixelRatioSystem(ScreenId screenId,float virtualPixelRatio)2314 DMError ScreenSessionManager::SetVirtualPixelRatioSystem(ScreenId screenId, float virtualPixelRatio)
2315 {
2316 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2317 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
2318 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2319 return DMError::DM_ERROR_NOT_SYSTEM_APP;
2320 }
2321
2322 auto clientProxy = GetClientProxy();
2323 if (clientProxy) {
2324 clientProxy->SetVirtualPixelRatioSystem(screenId, virtualPixelRatio);
2325 }
2326 return DMError::DM_OK;
2327 }
2328
SetDefaultDensityDpi(ScreenId screenId,float virtualPixelRatio)2329 DMError ScreenSessionManager::SetDefaultDensityDpi(ScreenId screenId, float virtualPixelRatio)
2330 {
2331 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2332 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
2333 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2334 return DMError::DM_ERROR_NOT_SYSTEM_APP;
2335 }
2336
2337 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2338 if (!screenSession) {
2339 TLOGE(WmsLogTag::DMS, "screen session is nullptr");
2340 return DMError::DM_ERROR_UNKNOWN;
2341 }
2342 if (screenSession->isScreenGroup_) {
2343 TLOGE(WmsLogTag::DMS, "cannot set virtual pixel ratio to the combination. screen: %{public}" PRIu64"",
2344 screenId);
2345 return DMError::DM_ERROR_NULLPTR;
2346 }
2347 // less to 1e-6 mean equal
2348 if (fabs(screenSession->GetScreenProperty().GetDefaultDensity() - virtualPixelRatio) < 1e-6) {
2349 TLOGE(WmsLogTag::DMS,
2350 "The density is equivalent to the original value, no update operation is required, aborted.");
2351 return DMError::DM_OK;
2352 }
2353 screenSession->SetDefaultDensity(virtualPixelRatio);
2354 return DMError::DM_OK;
2355 }
2356
SetResolution(ScreenId screenId,uint32_t width,uint32_t height,float virtualPixelRatio)2357 DMError ScreenSessionManager::SetResolution(ScreenId screenId, uint32_t width, uint32_t height, float virtualPixelRatio)
2358 {
2359 TLOGI(WmsLogTag::DMS,
2360 "ScreenId: %{public}" PRIu64 ", w: %{public}u, h: %{public}u, virtualPixelRatio: %{public}f",
2361 screenId, width, height, virtualPixelRatio);
2362 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2363 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
2364 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
2365 return DMError::DM_ERROR_NOT_SYSTEM_APP;
2366 }
2367 if (screenId == SCREEN_ID_INVALID) {
2368 TLOGE(WmsLogTag::DMS, "invalid screenId");
2369 return DMError::DM_ERROR_NULLPTR;
2370 }
2371 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2372 if (screenSession == nullptr) {
2373 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2374 return DMError::DM_ERROR_NULLPTR;
2375 }
2376 sptr<SupportedScreenModes> screenSessionModes = screenSession->GetActiveScreenMode();
2377 if (screenSessionModes == nullptr) {
2378 return DMError::DM_ERROR_NULLPTR;
2379 }
2380 if (width <= 0 || width > screenSessionModes->width_ ||
2381 height <= 0 || height > screenSessionModes->height_ ||
2382 virtualPixelRatio < (static_cast<float>(DOT_PER_INCH_MINIMUM_VALUE) / DOT_PER_INCH) ||
2383 virtualPixelRatio > (static_cast<float>(DOT_PER_INCH_MAXIMUM_VALUE) / DOT_PER_INCH)) {
2384 TLOGE(WmsLogTag::DMS, "invalid param! w:%{public}u h:%{public}u min:%{public}f max:%{public}f",
2385 screenSessionModes->width_, screenSessionModes->height_,
2386 static_cast<float>(DOT_PER_INCH_MINIMUM_VALUE) / DOT_PER_INCH,
2387 static_cast<float>(DOT_PER_INCH_MAXIMUM_VALUE) / DOT_PER_INCH);
2388 return DMError::DM_ERROR_INVALID_PARAM;
2389 }
2390 screenSession->SetDensityInCurResolution(virtualPixelRatio);
2391 DMError ret = SetVirtualPixelRatio(screenId, virtualPixelRatio);
2392 if (ret != DMError::DM_OK) {
2393 TLOGE(WmsLogTag::DMS, "Failed to setVirtualPixelRatio when settingResolution");
2394 screenSession->SetDensityInCurResolution(screenSession->GetScreenProperty().GetVirtualPixelRatio());
2395 return ret;
2396 }
2397 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetResolution(%" PRIu64", %u, %u, %f)",
2398 screenId, width, height, virtualPixelRatio);
2399 screenSession->UpdatePropertyByResolution(width, height);
2400 screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::CHANGE_MODE);
2401 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
2402 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
2403 return DMError::DM_OK;
2404 }
2405
GetDensityInCurResolution(ScreenId screenId,float & virtualPixelRatio)2406 DMError ScreenSessionManager::GetDensityInCurResolution(ScreenId screenId, float& virtualPixelRatio)
2407 {
2408 DmsXcollie dmsXcollie("DMS:GetDensityInCurResolution", XCOLLIE_TIMEOUT_10S);
2409 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2410 if (screenSession == nullptr) {
2411 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2412 return DMError::DM_ERROR_NULLPTR;
2413 }
2414
2415 virtualPixelRatio = screenSession->GetScreenProperty().GetDensityInCurResolution();
2416 return DMError::DM_OK;
2417 }
2418
GetScreenColorGamut(ScreenId screenId,ScreenColorGamut & colorGamut)2419 DMError ScreenSessionManager::GetScreenColorGamut(ScreenId screenId, ScreenColorGamut& colorGamut)
2420 {
2421 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
2422 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 "", screenId);
2423 if (screenId == SCREEN_ID_INVALID) {
2424 TLOGE(WmsLogTag::DMS, "screenId invalid");
2425 return DMError::DM_ERROR_INVALID_PARAM;
2426 }
2427 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2428 if (screenSession == nullptr) {
2429 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2430 return DMError::DM_ERROR_INVALID_PARAM;
2431 }
2432 return screenSession->GetScreenColorGamut(colorGamut);
2433 #else
2434 return DMError::DM_OK;
2435 #endif
2436 }
2437
SetScreenColorGamut(ScreenId screenId,int32_t colorGamutIdx)2438 DMError ScreenSessionManager::SetScreenColorGamut(ScreenId screenId, int32_t colorGamutIdx)
2439 {
2440 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
2441 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2442 TLOGE(WmsLogTag::DMS, "permission denied!");
2443 return DMError::DM_ERROR_NOT_SYSTEM_APP;
2444 }
2445
2446 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", colorGamutIdx %{public}d",
2447 screenId, colorGamutIdx);
2448 if (screenId == SCREEN_ID_INVALID) {
2449 TLOGE(WmsLogTag::DMS, "screenId invalid");
2450 return DMError::DM_ERROR_INVALID_PARAM;
2451 }
2452 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2453 if (screenSession == nullptr) {
2454 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2455 return DMError::DM_ERROR_INVALID_PARAM;
2456 }
2457 return screenSession->SetScreenColorGamut(colorGamutIdx);
2458 #else
2459 return DMError::DM_OK;
2460 #endif
2461 }
2462
GetScreenGamutMap(ScreenId screenId,ScreenGamutMap & gamutMap)2463 DMError ScreenSessionManager::GetScreenGamutMap(ScreenId screenId, ScreenGamutMap& gamutMap)
2464 {
2465 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
2466 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 "", screenId);
2467 if (screenId == SCREEN_ID_INVALID) {
2468 TLOGE(WmsLogTag::DMS, "screenId invalid");
2469 return DMError::DM_ERROR_INVALID_PARAM;
2470 }
2471 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2472 if (screenSession == nullptr) {
2473 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2474 return DMError::DM_ERROR_INVALID_PARAM;
2475 }
2476 return screenSession->GetScreenGamutMap(gamutMap);
2477 #else
2478 return DMError::DM_OK;
2479 #endif
2480 }
2481
SetScreenGamutMap(ScreenId screenId,ScreenGamutMap gamutMap)2482 DMError ScreenSessionManager::SetScreenGamutMap(ScreenId screenId, ScreenGamutMap gamutMap)
2483 {
2484 #ifdef WM_SCREEN_COLOR_GAMUT_ENABLE
2485 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2486 TLOGE(WmsLogTag::DMS, "permission denied!");
2487 return DMError::DM_ERROR_NOT_SYSTEM_APP;
2488 }
2489
2490 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", ScreenGamutMap %{public}u",
2491 screenId, static_cast<uint32_t>(gamutMap));
2492 if (screenId == SCREEN_ID_INVALID) {
2493 TLOGE(WmsLogTag::DMS, "screenId invalid");
2494 return DMError::DM_ERROR_INVALID_PARAM;
2495 }
2496 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2497 if (screenSession == nullptr) {
2498 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2499 return DMError::DM_ERROR_INVALID_PARAM;
2500 }
2501 return screenSession->SetScreenGamutMap(gamutMap);
2502 #else
2503 return DMError::DM_OK;
2504 #endif
2505 }
2506
SetScreenColorTransform(ScreenId screenId)2507 DMError ScreenSessionManager::SetScreenColorTransform(ScreenId screenId)
2508 {
2509 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2510 TLOGE(WmsLogTag::DMS, "permission denied!");
2511 return DMError::DM_ERROR_NOT_SYSTEM_APP;
2512 }
2513
2514 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 "", screenId);
2515 if (screenId == SCREEN_ID_INVALID) {
2516 TLOGE(WmsLogTag::DMS, "screenId invalid");
2517 return DMError::DM_ERROR_INVALID_PARAM;
2518 }
2519 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2520 if (screenSession == nullptr) {
2521 TLOGE(WmsLogTag::DMS, "Get ScreenSession failed");
2522 return DMError::DM_ERROR_INVALID_PARAM;
2523 }
2524 return screenSession->SetScreenColorTransform();
2525 }
2526
GetPhysicalScreenSession(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)2527 sptr<ScreenSession> ScreenSessionManager::GetPhysicalScreenSession(ScreenId screenId, ScreenId defScreenId,
2528 ScreenProperty property)
2529 {
2530 sptr<ScreenSession> screenSession = nullptr;
2531 ScreenSessionConfig config;
2532 if (g_isPcDevice) {
2533 config = {
2534 .screenId = screenId,
2535 .rsId = screenId,
2536 .defaultScreenId = defScreenId,
2537 .property = property,
2538 };
2539 screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_REAL);
2540 } else {
2541 sptr<ScreenSession> defaultScreen = GetDefaultScreenSession();
2542 if (defaultScreen == nullptr || defaultScreen->GetDisplayNode() == nullptr) {
2543 TLOGE(WmsLogTag::DMS, "default screen null");
2544 return screenSession;
2545 }
2546 NodeId nodeId = defaultScreen->GetDisplayNode()->GetId();
2547 TLOGI(WmsLogTag::DMS, "physical mirror screen nodeId: %{public}" PRIu64, nodeId);
2548 config = {
2549 .screenId = screenId,
2550 .rsId = screenId,
2551 .defaultScreenId = defScreenId,
2552 .mirrorNodeId = nodeId,
2553 .property = property,
2554 };
2555 screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_MIRROR);
2556 screenSession->SetIsPhysicalMirrorSwitch(true);
2557 #ifdef FOLD_ABILITY_ENABLE
2558 if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
2559 DMRect mainScreenRegion = {0, 0, 0, 0};
2560 foldScreenController_->SetMainScreenRegion(mainScreenRegion);
2561 screenSession->SetMirrorScreenRegion(screenId, mainScreenRegion);
2562 screenSession->SetIsEnableRegionRotation(true);
2563 screenSession->EnableMirrorScreenRegion();
2564 }
2565 #endif
2566 }
2567 return screenSession;
2568 }
2569
SetDefaultScreenModeWhenCreateMirror(sptr<ScreenSession> & screenSession)2570 void ScreenSessionManager::SetDefaultScreenModeWhenCreateMirror(sptr<ScreenSession>& screenSession)
2571 {
2572 if (screenSession == nullptr) {
2573 TLOGE(WmsLogTag::DMS, "screenSession is null");
2574 return;
2575 }
2576 #ifdef FOLD_ABILITY_ENABLE
2577 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
2578 SuperFoldStateManager::GetInstance().GetCurrentStatus() != SuperFoldStatus::EXPANDED) {
2579 screenSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
2580 } else {
2581 #endif
2582 screenSession->SetScreenCombination(ScreenCombination::SCREEN_EXTEND);
2583 #ifdef FOLD_ABILITY_ENABLE
2584 }
2585 #endif
2586 }
2587
CreatePhysicalMirrorSessionInner(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)2588 sptr<ScreenSession> ScreenSessionManager::CreatePhysicalMirrorSessionInner(ScreenId screenId, ScreenId defScreenId,
2589 ScreenProperty property)
2590 {
2591 #ifdef WM_MULTI_SCREEN_ENABLE
2592 sptr<ScreenSession> screenSession = nullptr;
2593 if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
2594 TLOGW(WmsLogTag::DMS, "mirror disabled by edm!");
2595 return screenSession;
2596 }
2597 screenSession = GetPhysicalScreenSession(screenId, defScreenId, property);
2598 if (!screenSession) {
2599 TLOGE(WmsLogTag::DMS, "screenSession is null");
2600 return nullptr;
2601 }
2602 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_ENTER_STR);
2603 HandleExtendScreenConnect(screenId);
2604 if (g_isPcDevice) {
2605 // pc is none, pad&&phone is mirror
2606 InitExtendScreenProperty(screenId, screenSession, property);
2607 screenSession->SetName(SCREEN_NAME_EXTEND);
2608 screenSession->SetIsExtend(true);
2609 SetDefaultScreenModeWhenCreateMirror(screenSession);
2610 } else {
2611 screenSession->SetIsExtend(true);
2612 screenSession->SetName(SCREEN_NAME_CAST);
2613 screenSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
2614 screenSession->SetVirtualScreenFlag(VirtualScreenFlag::CAST);
2615 }
2616 GetAndMergeEdidInfo(screenSession);
2617 screenSession->SetMirrorScreenType(MirrorScreenType::PHYSICAL_MIRROR);
2618 screenSession->SetIsPcUse(g_isPcDevice ? true : false);
2619 screenSession->SetIsInternal(false);
2620 screenSession->SetIsRealScreen(true);
2621 screenSession->SetIsCurrentInUse(true);
2622 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE);
2623 if (!g_isPcDevice) {
2624 hdmiScreenCount_ = hdmiScreenCount_ + 1;
2625 NotifyCaptureStatusChanged();
2626 }
2627 return screenSession;
2628 #else
2629 return nullptr;
2630 #endif
2631 }
2632
GetScreenSessionInner(ScreenId screenId,ScreenProperty property)2633 sptr<ScreenSession> ScreenSessionManager::GetScreenSessionInner(ScreenId screenId, ScreenProperty property)
2634 {
2635 ScreenId defScreenId = GetDefaultScreenId();
2636 TLOGW(WmsLogTag::DMS, "screenId:%{public}" PRIu64 "", screenId);
2637 if (IsDefaultMirrorMode(screenId)) {
2638 #ifdef WM_MULTI_SCREEN_ENABLE
2639 return CreatePhysicalMirrorSessionInner(screenId, defScreenId, property);
2640 #else
2641 return nullptr;
2642 #endif
2643 }
2644 std::string screenName = "UNKNOWN";
2645 if (screenId == SCREEN_ID_MAIN) {
2646 screenName = "SubScreen";
2647 }
2648 ScreenSessionConfig config = {
2649 .screenId = screenId,
2650 .rsId = screenId,
2651 .defaultScreenId = defScreenId,
2652 .name = screenName,
2653 .property = property,
2654 };
2655 sptr<ScreenSession> screenSession = nullptr;
2656 screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_REAL);
2657 screenSession->SetIsExtend(false);
2658 screenSession->SetScreenCombination(ScreenCombination::SCREEN_MAIN);
2659 screenSession->SetIsInternal(true);
2660 screenSession->SetIsRealScreen(true);
2661 screenSession->SetIsCurrentInUse(true);
2662 screenSession->SetIsPcUse(g_isPcDevice ? true : false);
2663 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
2664 InitFakeScreenSession(screenSession);
2665 }
2666 return screenSession;
2667 }
2668
CreateScreenProperty(ScreenId screenId,ScreenProperty & property)2669 void ScreenSessionManager::CreateScreenProperty(ScreenId screenId, ScreenProperty& property)
2670 {
2671 int id = HiviewDFX::XCollie::GetInstance().SetTimer("CreateScreenPropertyCallRS", XCOLLIE_TIMEOUT_10S, nullptr,
2672 nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
2673 TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenActiveMode ScreenId: %{public}" PRIu64, screenId);
2674 ScreenId phyScreenId = GetPhyScreenId(screenId);
2675 auto screenMode = rsInterface_.GetScreenActiveMode(phyScreenId);
2676 TLOGW(WmsLogTag::DMS, "get screenWidth: %{public}d, screenHeight: %{public}d",
2677 static_cast<uint32_t>(screenMode.GetScreenWidth()), static_cast<uint32_t>(screenMode.GetScreenHeight()));
2678 auto screenBounds = GetScreenBounds(screenId, screenMode);
2679 auto screenRefreshRate = screenMode.GetScreenRefreshRate();
2680 TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenCapability ScreenId: %{public}" PRIu64, phyScreenId);
2681 auto screenCapability = rsInterface_.GetScreenCapability(phyScreenId);
2682 HiviewDFX::XCollie::GetInstance().CancelTimer(id);
2683 TLOGW(WmsLogTag::DMS, "Call RS interface end, create ScreenProperty begin");
2684 InitScreenProperty(screenId, screenMode, screenCapability, property);
2685
2686 if (isDensityDpiLoad_) {
2687 if (phyScreenId == SCREEN_ID_MAIN) {
2688 TLOGW(WmsLogTag::DMS, "subDensityDpi_ = %{public}f", subDensityDpi_);
2689 property.SetVirtualPixelRatio(subDensityDpi_);
2690 property.SetDefaultDensity(subDensityDpi_);
2691 property.SetDensityInCurResolution(subDensityDpi_);
2692 } else {
2693 TLOGW(WmsLogTag::DMS, "densityDpi_ = %{public}f", densityDpi_);
2694 property.SetVirtualPixelRatio(densityDpi_);
2695 property.SetDefaultDensity(densityDpi_);
2696 property.SetDensityInCurResolution(densityDpi_);
2697 }
2698 } else {
2699 property.UpdateVirtualPixelRatio(screenBounds);
2700 }
2701 property.SetRefreshRate(screenRefreshRate);
2702 property.SetDefaultDeviceRotationOffset(defaultDeviceRotationOffset_);
2703 #ifdef FOLD_ABILITY_ENABLE
2704 if (foldScreenController_ != nullptr && screenId == 0
2705 && (g_screenRotationOffSet == ROTATION_90 || g_screenRotationOffSet == ROTATION_270)) {
2706 screenBounds = RRect({ 0, 0, screenMode.GetScreenHeight(), screenMode.GetScreenWidth() }, 0.0f, 0.0f);
2707 property.SetBounds(screenBounds);
2708 }
2709 sptr<FoldCreaseRegion> creaseRegion = GetCurrentFoldCreaseRegion();
2710 if (creaseRegion != nullptr) {
2711 std::vector<DMRect> creaseRects = creaseRegion->GetCreaseRects();
2712 if (creaseRects.size() > 0) {
2713 property.SetCreaseRect(creaseRects[0]);
2714 }
2715 }
2716 #endif
2717 property.CalcDefaultDisplayOrientation();
2718 property.SetScreenShape(ScreenSettingHelper::GetScreenShape(screenId));
2719 if (property.GetDisplayGroupId() == DISPLAY_GROUP_ID_INVALID) {
2720 property.SetDisplayGroupId(DISPLAY_GROUP_ID_DEFAULT);
2721 }
2722 if (property.GetMainDisplayIdOfGroup() == SCREEN_ID_INVALID) {
2723 property.SetMainDisplayIdOfGroup(MAIN_SCREEN_ID_DEFAULT);
2724 }
2725 }
2726
InitScreenProperty(ScreenId screenId,RSScreenModeInfo & screenMode,RSScreenCapability & screenCapability,ScreenProperty & property)2727 void ScreenSessionManager::InitScreenProperty(ScreenId screenId, RSScreenModeInfo& screenMode,
2728 RSScreenCapability& screenCapability, ScreenProperty& property)
2729 {
2730 auto screenBounds = GetScreenBounds(screenId, screenMode);
2731 property.SetRotation(0.0f);
2732 property.SetPhyWidth(screenCapability.GetPhyWidth());
2733 property.SetPhyHeight(screenCapability.GetPhyHeight());
2734 property.SetValidWidth(screenBounds.rect_.width_);
2735 property.SetValidHeight(screenBounds.rect_.height_);
2736 property.SetDpiPhyBounds(screenCapability.GetPhyWidth(), screenCapability.GetPhyHeight());
2737 property.SetPhyBounds(screenBounds);
2738 property.SetBounds(screenBounds);
2739 property.SetAvailableArea({0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight()});
2740 property.SetPhysicalTouchBounds();
2741 property.SetInputOffsetY();
2742 property.SetCurrentOffScreenRendering(false);
2743 property.SetScreenRealWidth(property.GetBounds().rect_.GetWidth());
2744 property.SetScreenRealHeight(property.GetBounds().rect_.GetHeight());
2745 property.SetMirrorWidth(property.GetBounds().rect_.GetWidth());
2746 property.SetMirrorHeight(property.GetBounds().rect_.GetHeight());
2747 property.SetScreenRealPPI();
2748 property.SetScreenRealDPI();
2749 property.SetScreenAreaOffsetX(property.GetPhyBounds().rect_.GetLeft());
2750 property.SetScreenAreaOffsetY(property.GetPhyBounds().rect_.GetTop());
2751 property.SetScreenAreaWidth(property.GetPhyBounds().rect_.GetWidth());
2752 property.SetScreenAreaHeight(property.GetPhyBounds().rect_.GetHeight());
2753 }
2754
GetScreenBounds(ScreenId screenId,RSScreenModeInfo & screenMode)2755 RRect ScreenSessionManager::GetScreenBounds(ScreenId screenId, RSScreenModeInfo& screenMode)
2756 {
2757 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice() &&
2758 GetCoordinationFlag() && screenId == SCREEN_ID_MAIN) {
2759 if (screenParams_.size() < STATUS_PARAM_VALID_INDEX) {
2760 TLOGE(WmsLogTag::DMS, "invalid param num, use default");
2761 return RRect({ 0, 0, MAIN_STATUS_DEFAULT_WIDTH, SCREEN_DEFAULT_HEIGHT }, 0.0f, 0.0f);
2762 }
2763 return RRect({ 0, 0, screenParams_[MAIN_STATUS_WIDTH_INDEX], screenParams_[SCREEN_HEIGHT_INDEX] }, 0.0f, 0.0f);
2764 }
2765 return RRect({ 0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight() }, 0.0f, 0.0f);
2766 }
2767
GetInternalWidth()2768 void ScreenSessionManager::GetInternalWidth()
2769 {
2770 ScreenId screenId = GetInternalScreenId();
2771 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2772 if (screenSession == nullptr) {
2773 TLOGE(WmsLogTag::DMS, "screen session is null");
2774 return;
2775 }
2776 ScreenProperty screenProperty = screenSession->GetScreenProperty();
2777 uint32_t screenWidth = screenProperty.GetScreenRealWidth();
2778 uint32_t screenHeight = screenProperty.GetScreenRealHeight();
2779 g_internalWidth = (screenWidth > screenHeight) ? screenWidth : screenHeight;
2780 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", g_internalWidth is:%{public}u",
2781 screenId, static_cast<uint32_t>(g_internalWidth));
2782 return;
2783 }
2784
InitExtendScreenProperty(ScreenId screenId,sptr<ScreenSession> session,ScreenProperty property)2785 void ScreenSessionManager::InitExtendScreenProperty(ScreenId screenId, sptr<ScreenSession> session,
2786 ScreenProperty property)
2787 {
2788 if (!g_isPcDevice) {
2789 TLOGW(WmsLogTag::DMS, "not PC device");
2790 return;
2791 }
2792 bool isSupportOffScreenRendering = ScreenSceneConfig::IsSupportOffScreenRendering();
2793 if (!isSupportOffScreenRendering) {
2794 TLOGW(WmsLogTag::DMS, "xml isSupportOffScreenRendering is fasle");
2795 return;
2796 }
2797 GetInternalWidth();
2798 TLOGD(WmsLogTag::DMS, "g_internalWidth: %{public}u", static_cast<uint32_t>(g_internalWidth));
2799 float offScreenPPIThreshold = static_cast<float>(ScreenSceneConfig::GetOffScreenPPIThreshold());
2800 uint32_t screenWidth = property.GetBounds().rect_.GetWidth();
2801 uint32_t screenHeight = property.GetBounds().rect_.GetHeight();
2802 float screenPPI = property.GetScreenRealPPI();
2803 if (screenWidth == 0) {
2804 TLOGE(WmsLogTag::DMS, "screenWidth is zero");
2805 return;
2806 }
2807 if (screenWidth > FOUR_K_WIDTH) {
2808 float scale = static_cast<float>(FOUR_K_WIDTH) / screenWidth;
2809 uint32_t screenAdjustHeight = static_cast<uint32_t>(std::round(screenHeight * scale));
2810 auto screenBounds = RRect({ 0, 0, FOUR_K_WIDTH, screenAdjustHeight }, 0.0f, 0.0f);
2811 session->SetExtendProperty(screenBounds, false);
2812 session->SetAvailableArea({0, 0, FOUR_K_WIDTH, screenAdjustHeight});
2813 session->SetValidWidth(FOUR_K_WIDTH);
2814 session->SetValidHeight(screenAdjustHeight);
2815 TLOGD(WmsLogTag::DMS, "screenWidth > 4K, screenId:%{public}" PRIu64"", screenId);
2816 } else if (screenWidth < THREE_K_WIDTH && screenPPI < offScreenPPIThreshold) {
2817 float scale = static_cast<float>(g_internalWidth) / screenWidth;
2818 uint32_t screenAdjustHeight = static_cast<uint32_t>(std::round(screenHeight * scale));
2819 auto screenBounds = RRect({ 0, 0, g_internalWidth, screenAdjustHeight }, 0.0f, 0.0f);
2820 session->SetExtendProperty(screenBounds, true);
2821 session->SetAvailableArea({0, 0, g_internalWidth, screenAdjustHeight});
2822 session->SetValidWidth(g_internalWidth);
2823 session->SetValidHeight(screenAdjustHeight);
2824 TLOGD(WmsLogTag::DMS, "screenWidth < g_internalWidth, screenId:%{public}" PRIu64"", screenId);
2825 } else {
2826 TLOGW(WmsLogTag::DMS, "no need adjust, screenId:%{public}" PRIu64"", screenId);
2827 return;
2828 }
2829 std::ostringstream oss;
2830 oss << "screenId:" << screenId
2831 << ", screenWidth: " << session->GetScreenProperty().GetBounds().rect_.GetWidth()
2832 << ", screenHeight: " << session->GetScreenProperty().GetBounds().rect_.GetHeight()
2833 << ", propertyCurrentOffScreenRendering: " << session->GetScreenProperty().GetCurrentOffScreenRendering()
2834 << ", screenPPI: " << screenPPI;
2835 TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
2836 }
2837
SetExtendedScreenFallbackPlan(ScreenId screenId)2838 void ScreenSessionManager::SetExtendedScreenFallbackPlan(ScreenId screenId)
2839 {
2840 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2841 if (screenSession == nullptr) {
2842 TLOGE(WmsLogTag::DMS, "screen session is null");
2843 return;
2844 }
2845 if (screenSession->GetIsInternal()) {
2846 TLOGW(WmsLogTag::DMS, "screen is internal");
2847 SetInnerScreenFallbackPlan(screenSession);
2848 return;
2849 }
2850 ScreenProperty screenProperty = screenSession->GetScreenProperty();
2851 if (!screenProperty.GetCurrentOffScreenRendering()) {
2852 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", propertyCurrentOffScreenRendering is false", screenId);
2853 return;
2854 }
2855 uint32_t screenAdjustWidth = 0;
2856 uint32_t screenAdjustHeight = 0;
2857 if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
2858 TLOGD(WmsLogTag::DMS, "Screen is mirror");
2859 screenAdjustWidth = screenProperty.GetScreenRealWidth();
2860 screenAdjustHeight = screenProperty.GetScreenRealHeight();
2861 } else {
2862 TLOGD(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64", setPhysicalScreenResolution", screenId);
2863 screenAdjustWidth = screenProperty.GetBounds().rect_.GetWidth();
2864 screenAdjustHeight = screenProperty.GetBounds().rect_.GetHeight();
2865 }
2866 ScreenId rsScreenId;
2867 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
2868 TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
2869 return;
2870 }
2871 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetPhysicalScreenResolution(%" PRIu64")", screenId);
2872 int32_t res = rsInterface_.SetPhysicalScreenResolution(rsScreenId, screenAdjustWidth, screenAdjustHeight);
2873 if ((screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND ||
2874 screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) && !screenSession->GetIsInternal()) {
2875 screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::UNDEFINED);
2876 screenSession->SetFrameGravity(Rosen::Gravity::RESIZE);
2877 } else {
2878 screenSession->SetFrameGravity(Rosen::Gravity::TOP_LEFT);
2879 }
2880 SetExtendedScreenFallbackPlanEvent(res);
2881 TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 ", screenAdjustWidth:%{public}u, screenAdjustHeight:%{public}u",
2882 screenId, screenAdjustWidth, screenAdjustHeight);
2883 }
2884
SetExtendedScreenFallbackPlanEvent(int32_t res)2885 void ScreenSessionManager::SetExtendedScreenFallbackPlanEvent(int32_t res)
2886 {
2887 if (res != StatusCode::SUCCESS) {
2888 TLOGE(WmsLogTag::DMS, "RS SetPhysicalScreenResolution failed.");
2889 screenEventTracker_.RecordEvent("SetPhysicalScreenResolution failed.");
2890 } else {
2891 TLOGI(WmsLogTag::DMS, "RS SetPhysicalScreenResolution success.");
2892 screenEventTracker_.RecordEvent("SetPhysicalScreenResolution success.");
2893 }
2894 }
2895
2896
SetInnerScreenFallbackPlan(sptr<ScreenSession> screenSession)2897 void ScreenSessionManager::SetInnerScreenFallbackPlan(sptr<ScreenSession> screenSession)
2898 {
2899 ScreenProperty screenProperty = screenSession->GetScreenProperty();
2900 uint32_t screenAdjustWidth = screenProperty.GetScreenRealWidth();
2901 uint32_t screenAdjustHeight = screenProperty.GetScreenRealHeight();
2902 ScreenId screenId = screenSession->GetScreenId();
2903 ScreenId rsScreenId;
2904 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
2905 TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
2906 return;
2907 }
2908 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetPhysicalScreenResolution(%" PRIu64")", screenId);
2909 int32_t res = rsInterface_.SetPhysicalScreenResolution(rsScreenId, screenAdjustWidth, screenAdjustHeight);
2910 if (res != StatusCode::SUCCESS) {
2911 TLOGE(WmsLogTag::DMS, "RS SetPhysicalScreenResolution failed.");
2912 screenEventTracker_.RecordEvent("SetPhysicalScreenResolution failed.");
2913 } else {
2914 TLOGI(WmsLogTag::DMS, "RS SetPhysicalScreenResolution success.");
2915 screenEventTracker_.RecordEvent("SetPhysicalScreenResolution success.");
2916 }
2917 TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 ", screenAdjustWidth:%{public}u, screenAdjustHeight:%{public}u",
2918 screenId, screenAdjustWidth, screenAdjustHeight);
2919 }
2920
InitExtendScreenDensity(sptr<ScreenSession> session,ScreenProperty property)2921 void ScreenSessionManager::InitExtendScreenDensity(sptr<ScreenSession> session, ScreenProperty property)
2922 {
2923 if (session->GetScreenProperty().GetScreenType() != ScreenType::REAL || session->isInternal_) {
2924 // 表示非拓展屏
2925 TLOGW(WmsLogTag::DMS, "Not expandable screen, no need to set dpi");
2926 return;
2927 }
2928 ScreenId mainScreenId = GetDefaultScreenId();
2929 sptr<ScreenSession> screenSession = GetScreenSession(mainScreenId);
2930 if (screenSession == nullptr) {
2931 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
2932 return;
2933 }
2934 float extendDensity = screenSession->GetScreenProperty().GetDensity();
2935 float curResolution = screenSession->GetScreenProperty().GetDensityInCurResolution();
2936 float defaultDensity = screenSession->GetScreenProperty().GetDefaultDensity();
2937 TLOGW(WmsLogTag::DMS, "extendDensity = %{public}f", extendDensity);
2938 session->SetVirtualPixelRatio(extendDensity * g_extendScreenDpiCoef);
2939 session->SetDefaultDensity(defaultDensity * g_extendScreenDpiCoef);
2940 session->SetDensityInCurResolution(curResolution);
2941 ScreenId screenId = session->GetScreenId();
2942 property.SetVirtualPixelRatio(extendDensity * g_extendScreenDpiCoef);
2943 property.SetDefaultDensity(defaultDensity * g_extendScreenDpiCoef);
2944 property.SetDensityInCurResolution(curResolution);
2945 {
2946 std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
2947 phyScreenPropMap_[screenId] = property;
2948 }
2949 return;
2950 }
2951
GetOrCreateScreenSession(ScreenId screenId)2952 sptr<ScreenSession> ScreenSessionManager::GetOrCreateScreenSession(ScreenId screenId)
2953 {
2954 TLOGW(WmsLogTag::DMS, "ENTER. ScreenId: %{public}" PRIu64 "", screenId);
2955 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
2956 if (screenSession) {
2957 TLOGW(WmsLogTag::DMS, "screenSession Exist ScreenId: %{public}" PRIu64, screenId);
2958 return screenSession;
2959 }
2960
2961 if (g_isPcDevice) {
2962 std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
2963 if (phyScreenPropMap_.size() > 1) {
2964 // pc is none, pad&&phone is mirror
2965 TLOGW(WmsLogTag::DMS, "Only Support one External screen.");
2966 return nullptr;
2967 }
2968 }
2969 screenIdManager_.UpdateScreenId(screenId, screenId);
2970
2971 ScreenProperty property;
2972 CreateScreenProperty(screenId, property);
2973 TLOGW(WmsLogTag::DMS, "call create screen property end");
2974 screenEventTracker_.RecordEvent("CreateScreenProperty by rsInterface success.");
2975 {
2976 std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
2977 phyScreenPropMap_[screenId] = property;
2978 }
2979
2980 if (HandleFoldScreenSessionCreate(screenId) == false) {
2981 return nullptr;
2982 }
2983
2984 sptr<ScreenSession> session = GetScreenSessionInner(screenId, property);
2985 if (session == nullptr) {
2986 TLOGE(WmsLogTag::DMS, "get screen session fail ScreenId: %{public}" PRIu64, screenId);
2987 return session;
2988 }
2989 session->RegisterScreenChangeListener(this);
2990 InitExtendScreenDensity(session, property);
2991 InitAbstractScreenModesInfo(session);
2992 session->groupSmsId_ = 1;
2993 {
2994 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
2995 screenSessionMap_[screenId] = session;
2996 }
2997 if (g_isPcDevice) {
2998 SetMultiScreenFrameControl();
2999 }
3000 screenEventTracker_.RecordEvent("create screen session success.");
3001 SetHdrFormats(GetPhyScreenId(screenId), session);
3002 SetColorSpaces(GetPhyScreenId(screenId), session);
3003 SetSupportedRefreshRate(session);
3004 if (session->GetFakeScreenSession() != nullptr) {
3005 std::vector<uint32_t> supportedRefreshRateFake = session->GetSupportedRefreshRate();
3006 sptr<ScreenSession> screenSessionFake = session->GetFakeScreenSession();
3007 screenSessionFake->SetSupportedRefreshRate(std::move(supportedRefreshRateFake));
3008 }
3009 RegisterRefreshRateChangeListener();
3010 TLOGW(WmsLogTag::DMS, "CreateScreenSession success. ScreenId: %{public}" PRIu64 "", screenId);
3011 return session;
3012 }
3013
HandleFoldScreenSessionCreate(ScreenId screenId)3014 bool ScreenSessionManager::HandleFoldScreenSessionCreate(ScreenId screenId)
3015 {
3016 #ifdef FOLD_ABILITY_ENABLE
3017 if (foldScreenController_ != nullptr) {
3018 // sensor may earlier than screen connect, when physical screen property changed, update
3019 foldScreenController_->UpdateForPhyScreenPropertyChange();
3020 /* folder screen outer screenId is 5 */
3021 if (screenId == SCREEN_ID_MAIN) {
3022 SetPostureAndHallSensorEnabled();
3023 if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()
3024 || FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
3025 ScreenSensorConnector::SubscribeTentSensor();
3026 }
3027 isFoldScreenOuterScreenReady_ = true;
3028 if (!FoldScreenStateInternel::IsDualDisplayFoldDevice() && isCoordinationFlag_ == false) {
3029 return false;
3030 }
3031 }
3032 }
3033 #endif
3034 return true;
3035 }
3036
SetHdrFormats(ScreenId screenId,sptr<ScreenSession> & session)3037 void ScreenSessionManager::SetHdrFormats(ScreenId screenId, sptr<ScreenSession>& session)
3038 {
3039 TLOGI(WmsLogTag::DMS, "SetHdrFormats %{public}" PRIu64, screenId);
3040 std::vector<ScreenHDRFormat> rsHdrFormat;
3041 auto status = rsInterface_.GetScreenSupportedHDRFormats(screenId, rsHdrFormat);
3042 if (static_cast<StatusCode>(status) != StatusCode::SUCCESS) {
3043 TLOGE(WmsLogTag::DMS, "get hdr format failed! status code: %{public}d", status);
3044 } else {
3045 std::vector<uint32_t> hdrFormat(rsHdrFormat.size());
3046 std::transform(rsHdrFormat.begin(), rsHdrFormat.end(), hdrFormat.begin(), [](int val) {
3047 return static_cast<uint32_t>(val);
3048 });
3049 session->SetHdrFormats(std::move(hdrFormat));
3050 }
3051 }
3052
SetColorSpaces(ScreenId screenId,sptr<ScreenSession> & session)3053 void ScreenSessionManager::SetColorSpaces(ScreenId screenId, sptr<ScreenSession>& session)
3054 {
3055 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3056 TLOGE(WmsLogTag::DMS, "spaces permission denied!");
3057 return;
3058 }
3059
3060 TLOGI(WmsLogTag::DMS, "SetColorSpaces %{public}" PRIu64, screenId);
3061 std::vector<GraphicCM_ColorSpaceType> rsColorSpace;
3062 auto status = rsInterface_.GetScreenSupportedColorSpaces(screenId, rsColorSpace);
3063 if (static_cast<StatusCode>(status) != StatusCode::SUCCESS) {
3064 TLOGE(WmsLogTag::DMS, "get color space failed! status code: %{public}d", status);
3065 } else {
3066 std::vector<uint32_t> colorSpace(rsColorSpace.size());
3067 std::transform(rsColorSpace.begin(), rsColorSpace.end(), colorSpace.begin(), [](int val) {
3068 return static_cast<uint32_t>(val);
3069 });
3070 session->SetColorSpaces(std::move(colorSpace));
3071 }
3072 }
3073
SetSupportedRefreshRate(sptr<ScreenSession> & session)3074 void ScreenSessionManager::SetSupportedRefreshRate(sptr<ScreenSession>& session)
3075 {
3076 std::vector<RSScreenModeInfo> allModes = rsInterface_.GetScreenSupportedModes(
3077 screenIdManager_.ConvertToRsScreenId(GetPhyScreenId(session->screenId_)));
3078 if (allModes.size() == 0) {
3079 TLOGE(WmsLogTag::DMS, "allModes.size() == 0, screenId=%{public}" PRIu64"", session->rsId_);
3080 return;
3081 }
3082 std::set<uint32_t> uniqueRefreshRates;
3083 for (const RSScreenModeInfo& rsScreenModeInfo : allModes) {
3084 uniqueRefreshRates.insert(rsScreenModeInfo.GetScreenRefreshRate());
3085 }
3086 std::vector<uint32_t> supportedRefreshRate(uniqueRefreshRates.begin(), uniqueRefreshRates.end());
3087 session->SetSupportedRefreshRate(std::move(supportedRefreshRate));
3088 }
3089
GetDefaultScreenId()3090 ScreenId ScreenSessionManager::GetDefaultScreenId()
3091 {
3092 if (defaultScreenId_ == INVALID_SCREEN_ID) {
3093 defaultScreenId_ = rsInterface_.GetDefaultScreenId();
3094 std::ostringstream oss;
3095 oss << "Default screen id : " << defaultScreenId_;
3096 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
3097 screenEventTracker_.RecordEvent(oss.str());
3098 }
3099 return defaultScreenId_;
3100 }
3101
WakeUpBegin(PowerStateChangeReason reason)3102 bool ScreenSessionManager::WakeUpBegin(PowerStateChangeReason reason)
3103 {
3104 // 该接口当前只有Power调用
3105 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:WakeUpBegin(%u)", reason);
3106 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3107 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3108 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3109 return false;
3110 }
3111 TLOGI(WmsLogTag::DMS, "[UL_POWER]WakeUpBegin reason: %{public}u", reason);
3112 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_START_DREAM) {
3113 TLOGI(WmsLogTag::DMS, "[UL_POWER]wakeup cannot start dream");
3114 return false;
3115 }
3116 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_END_DREAM) {
3117 NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_END_DREAM, EventStatus::BEGIN, reason);
3118 return BlockScreenWaitPictureFrameByCV(false);
3119 }
3120 currentWakeUpReason_ = reason;
3121 // 多屏协作灭屏不通知锁屏
3122 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3123 isMultiScreenCollaboration_ = true;
3124 return true;
3125 }
3126 lastWakeUpReason_ = reason;
3127 return NotifyDisplayPowerEvent(DisplayPowerEvent::WAKE_UP, EventStatus::BEGIN, reason);
3128 }
3129
WakeUpEnd()3130 bool ScreenSessionManager::WakeUpEnd()
3131 {
3132 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:WakeUpEnd");
3133 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3134 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3135 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3136 return false;
3137 }
3138 TLOGI(WmsLogTag::DMS, "[UL_POWER]WakeUpEnd enter");
3139 // 多屏协作灭屏不通知锁屏
3140 if (isMultiScreenCollaboration_) {
3141 isMultiScreenCollaboration_ = false;
3142 return true;
3143 }
3144 return NotifyDisplayPowerEvent(DisplayPowerEvent::WAKE_UP, EventStatus::END,
3145 PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
3146 }
3147
SuspendBegin(PowerStateChangeReason reason)3148 bool ScreenSessionManager::SuspendBegin(PowerStateChangeReason reason)
3149 {
3150 // only power use
3151 powerStateChangeReason_ = reason;
3152 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:SuspendBegin(%u)", reason);
3153 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3154 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3155 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3156 return false;
3157 }
3158 TLOGI(WmsLogTag::DMS, "[UL_POWER]Reason: %{public}u", static_cast<uint32_t>(reason));
3159 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_END_DREAM) {
3160 TLOGI(WmsLogTag::DMS, "[UL_POWER]suspend cannot end dream");
3161 return false;
3162 }
3163 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_START_DREAM) {
3164 NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_START_DREAM, EventStatus::BEGIN, reason);
3165 return BlockScreenWaitPictureFrameByCV(true);
3166 }
3167 gotScreenlockFingerprint_ = false;
3168 lastWakeUpReason_ = PowerStateChangeReason::STATE_CHANGE_REASON_INIT;
3169 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
3170 lastWakeUpReason_ = PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF;
3171 }
3172 // 多屏协作灭屏不通知锁屏
3173 gotScreenOffNotify_ = false;
3174 if (!g_isPcDevice && reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT &&
3175 reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_SUCCESS &&
3176 reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_ON &&
3177 reason != PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
3178 sessionDisplayPowerController_->canCancelSuspendNotify_ = true;
3179 }
3180 sessionDisplayPowerController_->isSuspendBegin_ = true;
3181 sessionDisplayPowerController_->SuspendBegin(reason);
3182 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3183 isMultiScreenCollaboration_ = true;
3184 return true;
3185 }
3186 return NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::BEGIN, reason);
3187 }
3188
IsSystemSleep()3189 bool ScreenSessionManager::IsSystemSleep()
3190 {
3191 return powerStateChangeReason_ == PowerStateChangeReason::STATE_CHANGE_REASON_SYSTEM ||
3192 powerStateChangeReason_ == PowerStateChangeReason::STATE_CHANGE_REASON_HARD_KEY;
3193 }
3194
SuspendEnd()3195 bool ScreenSessionManager::SuspendEnd()
3196 {
3197 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3198 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3199 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3200 return false;
3201 }
3202 TLOGI(WmsLogTag::DMS, "[UL_POWER] enter");
3203 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "[UL_POWER]ssm:SuspendEnd");
3204 // 多屏协作灭屏不通知锁屏
3205 if (isMultiScreenCollaboration_) {
3206 isMultiScreenCollaboration_ = false;
3207 return true;
3208 }
3209 return NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::END,
3210 PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
3211 }
3212
GetInternalScreenId()3213 ScreenId ScreenSessionManager::GetInternalScreenId()
3214 {
3215 ScreenId screenId = SCREEN_ID_INVALID;
3216 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3217 for (auto sessionIt : screenSessionMap_) {
3218 auto screenSession = sessionIt.second;
3219 if (screenSession == nullptr) {
3220 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
3221 continue;
3222 }
3223 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && screenSession->isInternal_) {
3224 TLOGI(WmsLogTag::DMS, "found screenId = %{public}" PRIu64, sessionIt.first);
3225 screenId = sessionIt.first;
3226 break;
3227 }
3228 }
3229 return screenId;
3230 }
3231
GetInternalScreenSession()3232 sptr<ScreenSession> ScreenSessionManager::GetInternalScreenSession()
3233 {
3234 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3235 for (auto sessionIt : screenSessionMap_) {
3236 sptr<ScreenSession> screenSession = sessionIt.second;
3237 if (screenSession == nullptr) {
3238 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
3239 continue;
3240 }
3241 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && screenSession->isInternal_) {
3242 TLOGI(WmsLogTag::DMS, "found screenSession, Id = %{public}" PRIu64, sessionIt.first);
3243 return screenSession;
3244 }
3245 }
3246 return nullptr;
3247 }
3248
GetInternalAndExternalSession(sptr<ScreenSession> & internalSession,sptr<ScreenSession> & externalSession)3249 void ScreenSessionManager::GetInternalAndExternalSession(sptr<ScreenSession>& internalSession,
3250 sptr<ScreenSession>& externalSession)
3251 {
3252 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3253 for (auto sessionIt : screenSessionMap_) {
3254 auto screenSession = sessionIt.second;
3255 if (screenSession == nullptr) {
3256 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
3257 continue;
3258 }
3259 if (!screenSession->GetIsCurrentInUse()) {
3260 TLOGE(WmsLogTag::DMS, "screenSession not in use!");
3261 continue;
3262 }
3263 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && screenSession->isInternal_) {
3264 TLOGI(WmsLogTag::DMS, "found internalSession, screenId = %{public}" PRIu64, sessionIt.first);
3265 internalSession = screenSession;
3266 } else {
3267 TLOGI(WmsLogTag::DMS, "found externalSession, screenId = %{public}" PRIu64, sessionIt.first);
3268 externalSession = screenSession;
3269 }
3270 }
3271 }
3272
SetScreenPowerById(ScreenId screenId,ScreenPowerState state,PowerStateChangeReason reason)3273 bool ScreenSessionManager::SetScreenPowerById(ScreenId screenId, ScreenPowerState state,
3274 PowerStateChangeReason reason)
3275 {
3276 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3277 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3278 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3279 return false;
3280 }
3281 TLOGI(WmsLogTag::DMS, "screen id:%{public}" PRIu64
3282 ", state:%{public}u, reason:%{public}u", screenId, state, static_cast<uint32_t>(reason));
3283
3284 bool isPowerSet = false;
3285 if (g_isPcDevice) {
3286 isPowerSet = SetScreenPowerByIdForPC(screenId, state);
3287 } else {
3288 isPowerSet = SetScreenPowerByIdDefault(screenId, state);
3289 }
3290 return isPowerSet;
3291 }
3292
SetScreenPowerByIdForPC(ScreenId screenId,ScreenPowerState state)3293 bool ScreenSessionManager::SetScreenPowerByIdForPC(ScreenId screenId, ScreenPowerState state)
3294 {
3295 std::lock_guard<std::mutex> lock(screenPowerMutex_);
3296 switch (state) {
3297 case ScreenPowerState::POWER_ON: {
3298 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_ON");
3299 #ifdef WM_MULTI_SCREEN_ENABLE
3300 if (GetIsOuterOnlyMode() && !GetIsOuterOnlyModeBeforePowerOff()) {
3301 MultiScreenModeChange(screenId, screenId, "on");
3302 }
3303 #endif
3304 break;
3305 }
3306 case ScreenPowerState::POWER_OFF: {
3307 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_OFF");
3308 #ifdef WM_MULTI_SCREEN_ENABLE
3309 if (!GetIsOuterOnlyMode() && !GetIsOuterOnlyModeBeforePowerOff()) {
3310 MultiScreenModeChange(screenId, screenId, "off");
3311 SetIsOuterOnlyModeBeforePowerOff(false);
3312 }
3313 #endif
3314 break;
3315 }
3316 default: {
3317 TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerById state not support");
3318 return false;
3319 }
3320 }
3321 return true;
3322 }
3323
SetScreenPowerByIdDefault(ScreenId screenId,ScreenPowerState state)3324 bool ScreenSessionManager::SetScreenPowerByIdDefault(ScreenId screenId, ScreenPowerState state)
3325 {
3326 ScreenPowerStatus status;
3327 switch (state) {
3328 case ScreenPowerState::POWER_ON: {
3329 status = ScreenPowerStatus::POWER_STATUS_ON;
3330 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_ON");
3331 break;
3332 }
3333 case ScreenPowerState::POWER_OFF: {
3334 status = ScreenPowerStatus::POWER_STATUS_OFF;
3335 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_OFF");
3336 break;
3337 }
3338 default: {
3339 TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerById state not support");
3340 return false;
3341 }
3342 }
3343 CallRsSetScreenPowerStatusSync(screenId, status);
3344 return true;
3345 }
3346
SetLastScreenMode(sptr<ScreenSession> firstSession,sptr<ScreenSession> secondarySession)3347 void ScreenSessionManager::SetLastScreenMode(sptr<ScreenSession> firstSession, sptr<ScreenSession> secondarySession)
3348 {
3349 #ifdef WM_MULTI_SCREEN_ENABLE
3350 if (firstSession == nullptr || secondarySession == nullptr) {
3351 TLOGE(WmsLogTag::DMS, "first or second screen is null");
3352 return;
3353 }
3354
3355 ScreenId mainScreenId = SCREEN_ID_INVALID;
3356 MultiScreenMode secondaryScreenMode = MultiScreenMode::SCREEN_MIRROR;
3357 {
3358 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
3359 for (auto sessionIt : screenSessionMap_) {
3360 auto screenSession = sessionIt.second;
3361 if (screenSession == nullptr) {
3362 TLOGW(WmsLogTag::DMS, "screenSession is nullptr!");
3363 continue;
3364 }
3365 if (screenSession != firstSession && screenSession != secondarySession) {
3366 continue;
3367 }
3368 if (!screenSession->GetIsCurrentInUse()) {
3369 TLOGE(WmsLogTag::DMS, "screenSession not in use!");
3370 continue;
3371 }
3372 ScreenCombination screenCombination = screenSession->GetScreenCombination();
3373 if (screenCombination == ScreenCombination::SCREEN_MAIN) {
3374 mainScreenId = sessionIt.first;
3375 TLOGI(WmsLogTag::DMS, "found main screen");
3376 } else if (screenCombination == ScreenCombination::SCREEN_MIRROR) {
3377 secondaryScreenMode = MultiScreenMode::SCREEN_MIRROR;
3378 TLOGI(WmsLogTag::DMS, "found mirror screen");
3379 } else if (screenCombination == ScreenCombination::SCREEN_EXTEND) {
3380 secondaryScreenMode = MultiScreenMode::SCREEN_EXTEND;
3381 TLOGI(WmsLogTag::DMS, "found extend screen");
3382 } else {
3383 TLOGE(WmsLogTag::DMS, "screen id or screen mode error");
3384 }
3385 }
3386 }
3387
3388 if (mainScreenId == SCREEN_ID_INVALID) {
3389 TLOGE(WmsLogTag::DMS, "param error!");
3390 return;
3391 }
3392 MultiScreenManager::GetInstance().SetLastScreenMode(mainScreenId, secondaryScreenMode);
3393 #endif
3394 }
3395
IsPreBrightAuthFail(void)3396 bool ScreenSessionManager::IsPreBrightAuthFail(void)
3397 {
3398 return lastWakeUpReason_ == PowerStateChangeReason::
3399 STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF;
3400 }
3401
BlockSetDisplayState(void)3402 bool ScreenSessionManager::BlockSetDisplayState(void)
3403 {
3404 return prePowerStateChangeReason_ == PowerStateChangeReason::POWER_BUTTON;
3405 }
3406
SetDisplayState(DisplayState state)3407 bool ScreenSessionManager::SetDisplayState(DisplayState state)
3408 {
3409 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3410 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3411 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3412 return false;
3413 }
3414 if (!sessionDisplayPowerController_) {
3415 TLOGE(WmsLogTag::DMS, "[UL_POWER]sessionDisplayPowerController_ is null");
3416 return false;
3417 }
3418 TLOGI(WmsLogTag::DMS, "[UL_POWER] enter");
3419 auto screenIds = GetAllScreenIds();
3420 if (screenIds.empty()) {
3421 TLOGI(WmsLogTag::DMS, "[UL_POWER]no screen info");
3422 return sessionDisplayPowerController_->SetDisplayState(state);
3423 }
3424
3425 UpdateDisplayState(screenIds, state);
3426 bool ret = sessionDisplayPowerController_->SetDisplayState(state);
3427 if (!ret && state == DisplayState::OFF) {
3428 state = lastDisplayState_;
3429 UpdateDisplayState(screenIds, state);
3430 }
3431 lastDisplayState_ = state;
3432 return ret;
3433 }
3434
UpdateDisplayState(std::vector<ScreenId> screenIds,DisplayState state)3435 void ScreenSessionManager::UpdateDisplayState(std::vector<ScreenId> screenIds, DisplayState state)
3436 {
3437 for (auto screenId : screenIds) {
3438 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
3439 if (screenSession == nullptr) {
3440 TLOGW(WmsLogTag::DMS, "[UL_POWER]screenId: %{public}" PRIu64, screenId);
3441 continue;
3442 }
3443 screenSession->UpdateDisplayState(state);
3444 TLOGI(WmsLogTag::DMS, "[UL_POWER]displayState: %{public}u",
3445 screenSession->GetScreenProperty().GetDisplayState());
3446 }
3447 }
3448
BlockScreenOnByCV(void)3449 void ScreenSessionManager::BlockScreenOnByCV(void)
3450 {
3451 if (keyguardDrawnDone_ == false) {
3452 TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOnCV_ set");
3453 needScreenOnWhenKeyguardNotify_ = true;
3454 std::unique_lock<std::mutex> lock(screenOnMutex_);
3455 if (screenOnCV_.wait_for(lock, std::chrono::milliseconds(screenOnDelay_)) == std::cv_status::timeout) {
3456 TLOGI(WmsLogTag::DMS, "[UL_POWER]wait ScreenOnCV_ timeout");
3457 }
3458 }
3459 }
3460
BlockScreenOffByCV(void)3461 void ScreenSessionManager::BlockScreenOffByCV(void)
3462 {
3463 if (gotScreenOffNotify_ == false) {
3464 TLOGI(WmsLogTag::DMS, "[UL_POWER]delay:%{public}d", screenOffDelay_);
3465 needScreenOffNotify_ = true;
3466 std::unique_lock<std::mutex> lock(screenOffMutex_);
3467 if (screenOffCV_.wait_for(lock, std::chrono::milliseconds(screenOffDelay_)) == std::cv_status::timeout) {
3468 isScreenLockSuspend_ = false;
3469 needScreenOffNotify_ = false;
3470 TLOGI(WmsLogTag::DMS, "[UL_POWER]wait ScreenOffCV_ timeout, isScreenLockSuspend_ is false");
3471 }
3472 }
3473 }
3474
TryToCancelScreenOff()3475 bool ScreenSessionManager::TryToCancelScreenOff()
3476 {
3477 std::lock_guard<std::mutex> notifyLock(sessionDisplayPowerController_->notifyMutex_);
3478 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3479 TLOGE(WmsLogTag::DMS, "Permission denied!");
3480 return false;
3481 }
3482 TLOGI(WmsLogTag::DMS, "[UL_POWER]about to cancel suspend, can:%{public}d, got:%{public}d, need:%{public}d",
3483 sessionDisplayPowerController_->canCancelSuspendNotify_, gotScreenOffNotify_, needScreenOffNotify_);
3484 if (sessionDisplayPowerController_->canCancelSuspendNotify_) {
3485 sessionDisplayPowerController_->needCancelNotify_ = true;
3486 TLOGI(WmsLogTag::DMS, "[UL_POWER]notify cancel screenoff");
3487 ScreenSessionManager::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_OFF_CANCELED,
3488 EventStatus::BEGIN, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
3489 return true;
3490 }
3491 if (gotScreenOffNotify_ == false && needScreenOffNotify_ == true) {
3492 std::unique_lock <std::mutex> lock(screenOffMutex_);
3493 sessionDisplayPowerController_->canceledSuspend_ = true;
3494 screenOffCV_.notify_all();
3495 needScreenOffNotify_ = false;
3496 TLOGI(WmsLogTag::DMS, "[UL_POWER]cancel wait and notify cancel screenoff");
3497 ScreenSessionManager::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_OFF_CANCELED,
3498 EventStatus::BEGIN, PowerStateChangeReason::STATE_CHANGE_REASON_INIT);
3499 return true;
3500 }
3501 TLOGW(WmsLogTag::DMS, "[UL_POWER]failed to cancel suspend");
3502 return false;
3503 }
3504
ForceSkipScreenOffAnimation()3505 void ScreenSessionManager::ForceSkipScreenOffAnimation()
3506 {
3507 std::lock_guard<std::mutex> notifyLock(sessionDisplayPowerController_->notifyMutex_);
3508 TLOGI(WmsLogTag::DMS, "[UL_POWER]about to skip animation, can:%{public}d, got:%{public}d, need:%{public}d",
3509 sessionDisplayPowerController_->canCancelSuspendNotify_, gotScreenOffNotify_, needScreenOffNotify_);
3510 if (sessionDisplayPowerController_->canCancelSuspendNotify_) {
3511 sessionDisplayPowerController_->skipScreenOffBlock_ = true;
3512 TLOGI(WmsLogTag::DMS, "[UL_POWER]skip screenoff animation");
3513 return;
3514 }
3515 if (gotScreenOffNotify_ == false && needScreenOffNotify_ == true) {
3516 std::unique_lock <std::mutex> lock(screenOffMutex_);
3517 screenOffCV_.notify_all();
3518 needScreenOffNotify_ = false;
3519 TLOGI(WmsLogTag::DMS, "[UL_POWER]skip wait");
3520 return;
3521 }
3522 }
3523
SetScreenBrightness(uint64_t screenId,uint32_t level)3524 bool ScreenSessionManager::SetScreenBrightness(uint64_t screenId, uint32_t level)
3525 {
3526 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3527 TLOGE(WmsLogTag::DMS, "set screen brightness permission denied!");
3528 return false;
3529 }
3530 TLOGD(WmsLogTag::DMS, "screenId:%{public}" PRIu64", level:%{public}u,", screenId, level);
3531 RSInterfaces::GetInstance().SetScreenBacklight(screenId, level);
3532 return true;
3533 }
3534
GetScreenBrightness(uint64_t screenId)3535 uint32_t ScreenSessionManager::GetScreenBrightness(uint64_t screenId)
3536 {
3537 uint32_t level = static_cast<uint32_t>(RSInterfaces::GetInstance().GetScreenBacklight(screenId));
3538 TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", level:%{public}u,", screenId, level);
3539 return level;
3540 }
3541
SetScreenOffDelayTime(int32_t delay)3542 int32_t ScreenSessionManager::SetScreenOffDelayTime(int32_t delay)
3543 {
3544 DmsXcollie dmsXcollie("DMS:SetScreenOffDelayTime", XCOLLIE_TIMEOUT_10S);
3545 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3546 TLOGE(WmsLogTag::DMS, "set screen off delay time permission denied!");
3547 return 0;
3548 }
3549
3550 if (delay > SCREEN_OFF_MIN_DELAY_TIME && delay < CV_WAIT_SCREENOFF_MS) {
3551 screenOffDelay_ = CV_WAIT_SCREENOFF_MS;
3552 } else if (delay > CV_WAIT_SCREENOFF_MS_MAX) {
3553 screenOffDelay_ = CV_WAIT_SCREENOFF_MS_MAX;
3554 } else {
3555 screenOffDelay_ = delay;
3556 }
3557 TLOGI(WmsLogTag::DMS, "delay:%{public}d, screenOffDelay_:%{public}d",
3558 delay, screenOffDelay_);
3559 return screenOffDelay_;
3560 }
3561
SetScreenOnDelayTime(int32_t delay)3562 int32_t ScreenSessionManager::SetScreenOnDelayTime(int32_t delay)
3563 {
3564 DmsXcollie dmsXcollie("DMS:SetScreenOnDelayTime", XCOLLIE_TIMEOUT_10S);
3565 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3566 TLOGE(WmsLogTag::DMS, "set screen on delay time permission denied!");
3567 return 0;
3568 }
3569
3570 if (delay > CV_WAIT_SCREENON_MS) {
3571 screenOnDelay_ = CV_WAIT_SCREENON_MS;
3572 } else {
3573 screenOnDelay_ = delay;
3574 }
3575 TLOGI(WmsLogTag::DMS, "delay:%{public}d, screenOnDelay_:%{public}d",
3576 delay, screenOnDelay_);
3577 return screenOnDelay_;
3578 }
3579
SetCameraStatus(int32_t cameraStatus,int32_t cameraPosition)3580 void ScreenSessionManager::SetCameraStatus(int32_t cameraStatus, int32_t cameraPosition)
3581 {
3582 #ifdef WM_CAM_MODE_ABILITY_ENABLE
3583 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3584 TLOGE(WmsLogTag::DMS, "set camera status permission denied!");
3585 return;
3586 }
3587
3588 if ((cameraStatus_ == cameraStatus) && (cameraPosition_ == cameraPosition)) {
3589 return; // no need to update
3590 }
3591 cameraStatus_ = cameraStatus;
3592 cameraPosition_ = cameraPosition;
3593 TLOGI(WmsLogTag::DMS, "SetCameraStatus, cameraStatus:%{public}d, cameraPosition:%{public}d",
3594 cameraStatus, cameraPosition);
3595 #endif
3596 }
3597
IsScreenLockSuspend(void)3598 bool ScreenSessionManager::IsScreenLockSuspend(void)
3599 {
3600 return isScreenLockSuspend_;
3601 }
3602
NotifyDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)3603 void ScreenSessionManager::NotifyDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
3604 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
3605 {
3606 auto clientProxy = GetClientProxy();
3607 if (clientProxy) {
3608 clientProxy->OnDisplayStateChanged(defaultDisplayId, displayInfo, displayInfoMap, type);
3609 }
3610 }
3611
NotifyScreenshot(DisplayId displayId)3612 void ScreenSessionManager::NotifyScreenshot(DisplayId displayId)
3613 {
3614 auto clientProxy = GetClientProxy();
3615 if (clientProxy) {
3616 clientProxy->OnScreenshot(displayId);
3617 }
3618 }
3619
SetSpecifiedScreenPower(ScreenId screenId,ScreenPowerState state,PowerStateChangeReason reason)3620 bool ScreenSessionManager::SetSpecifiedScreenPower(ScreenId screenId, ScreenPowerState state,
3621 PowerStateChangeReason reason)
3622 {
3623 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3624 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
3625 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3626 return false;
3627 }
3628 TLOGI(WmsLogTag::DMS, "screen id:%{public}" PRIu64 ", state:%{public}u",
3629 screenId, state);
3630
3631 ScreenPowerStatus status;
3632 switch (state) {
3633 case ScreenPowerState::POWER_ON: {
3634 status = ScreenPowerStatus::POWER_STATUS_ON;
3635 break;
3636 }
3637 case ScreenPowerState::POWER_OFF: {
3638 status = ScreenPowerStatus::POWER_STATUS_OFF;
3639 break;
3640 }
3641 default: {
3642 TLOGW(WmsLogTag::DMS, "[UL_POWER]SetScreenPowerStatus state not support");
3643 return false;
3644 }
3645 }
3646
3647 CallRsSetScreenPowerStatusSync(screenId, status);
3648 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3649 return true;
3650 }
3651 return NotifyDisplayPowerEvent(state == ScreenPowerState::POWER_ON ? DisplayPowerEvent::DISPLAY_ON :
3652 DisplayPowerEvent::DISPLAY_OFF, EventStatus::END, reason);
3653 }
3654
SetScreenPowerForAll(ScreenPowerState state,PowerStateChangeReason reason)3655 bool ScreenSessionManager::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)
3656 {
3657 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3658 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
3659 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
3660 return false;
3661 }
3662 TLOGI(WmsLogTag::DMS, "[UL_POWER]state: %{public}u, reason: %{public}u",
3663 static_cast<uint32_t>(state), static_cast<uint32_t>(reason));
3664 ScreenPowerStatus status;
3665
3666 if (!GetPowerStatus(state, reason, status)) {
3667 return false;
3668 }
3669 if (g_isPcDevice && reason == PowerStateChangeReason::POWER_BUTTON && state == ScreenPowerState::POWER_OFF) {
3670 isDeviceShutDown_ = true;
3671 } else {
3672 isDeviceShutDown_ = false;
3673 }
3674 gotScreenOffNotify_ = false;
3675 keyguardDrawnDone_ = false;
3676 TLOGI(WmsLogTag::DMS, "keyguardDrawnDone_ is false");
3677 prePowerStateChangeReason_ = reason;
3678 return SetScreenPower(status, reason);
3679 }
3680
GetPowerStatus(ScreenPowerState state,PowerStateChangeReason reason,ScreenPowerStatus & status)3681 bool ScreenSessionManager::GetPowerStatus(ScreenPowerState state, PowerStateChangeReason reason,
3682 ScreenPowerStatus& status)
3683 {
3684 switch (state) {
3685 case ScreenPowerState::POWER_ON: {
3686 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT) {
3687 // 预亮屏
3688 status = ScreenPowerStatus::POWER_STATUS_ON_ADVANCED;
3689 TLOGI(WmsLogTag::DMS, "[UL_POWER]POWER_STATUS_ON_ADVANCED");
3690 } else {
3691 status = ScreenPowerStatus::POWER_STATUS_ON;
3692 TLOGI(WmsLogTag::DMS, "[UL_POWER]POWER_STATUS_ON");
3693 }
3694 break;
3695 }
3696 case ScreenPowerState::POWER_OFF: {
3697 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) {
3698 // 预亮屏时指纹认证失败
3699 status = ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED;
3700 TLOGI(WmsLogTag::DMS, "[UL_POWER]POWER_STATUS_OFF_ADVANCED");
3701 } else {
3702 status = ScreenPowerStatus::POWER_STATUS_OFF;
3703 TLOGI(WmsLogTag::DMS, "[UL_POWER]POWER_STATUS_OFF");
3704 }
3705 rsInterface_.MarkPowerOffNeedProcessOneFrame();
3706 break;
3707 }
3708 case ScreenPowerState::POWER_SUSPEND: {
3709 status = ScreenPowerStatus::POWER_STATUS_SUSPEND;
3710 TLOGI(WmsLogTag::DMS, "[UL_POWER] POWER_SUSPEND");
3711 rsInterface_.MarkPowerOffNeedProcessOneFrame();
3712 break;
3713 }
3714 case ScreenPowerState::POWER_DOZE: {
3715 status = ScreenPowerStatus::POWER_STATUS_DOZE;
3716 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_DOZE");
3717 break;
3718 }
3719 case ScreenPowerState::POWER_DOZE_SUSPEND: {
3720 status = ScreenPowerStatus::POWER_STATUS_DOZE_SUSPEND;
3721 TLOGI(WmsLogTag::DMS, "[UL_POWER]Set ScreenPowerStatus: POWER_STATUS_DOZE_SUSPEND");
3722 break;
3723 }
3724 default: {
3725 TLOGW(WmsLogTag::DMS, "[UL_POWER]not support");
3726 return false;
3727 }
3728 }
3729 return true;
3730 }
3731
ExitCoordination(const std::string & reason)3732 void ScreenSessionManager::ExitCoordination(const std::string& reason)
3733 {
3734 #ifdef FOLD_ABILITY_ENABLE
3735 if (GetFoldDisplayMode() != FoldDisplayMode::COORDINATION) {
3736 return;
3737 }
3738 if (foldScreenController_ != nullptr) {
3739 TLOGI(WmsLogTag::DMS, "[UL_POWER] reason:%{public}s", reason.c_str());
3740 foldScreenController_->ExitCoordination();
3741 }
3742 #endif
3743 }
3744
TryToRecoverFoldDisplayMode(ScreenPowerStatus status)3745 void ScreenSessionManager::TryToRecoverFoldDisplayMode(ScreenPowerStatus status)
3746 {
3747 #ifdef FOLD_ABILITY_ENABLE
3748 if (foldScreenController_ == nullptr) {
3749 TLOGW(WmsLogTag::DMS, "foldScreenController_ is null");
3750 return;
3751 }
3752 if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED ||
3753 status == ScreenPowerStatus::POWER_STATUS_OFF_FAKE || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3754 status == ScreenPowerStatus::POWER_STATUS_DOZE) {
3755 foldScreenController_->RecoverDisplayMode();
3756 }
3757 #endif
3758 }
3759
SetScreenPower(ScreenPowerStatus status,PowerStateChangeReason reason)3760 bool ScreenSessionManager::SetScreenPower(ScreenPowerStatus status, PowerStateChangeReason reason)
3761 {
3762 TLOGI(WmsLogTag::DMS, "[UL_POWER] enter status:%{public}u, reason:%{public}u", status, reason);
3763 auto screenIds = GetAllScreenIds();
3764 if (screenIds.empty()) {
3765 TLOGI(WmsLogTag::DMS, "[UL_POWER] screenIds empty");
3766 return false;
3767 }
3768
3769 if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3770 status == ScreenPowerStatus::POWER_STATUS_DOZE) {
3771 ExitCoordination("Press PowerKey");
3772 }
3773 DisplayPowerEvent notifyEvent = DisplayPowerEvent::DISPLAY_OFF;
3774 auto iter = SCREEN_STATUS_POWER_EVENT_MAP.find(status);
3775 if (iter != SCREEN_STATUS_POWER_EVENT_MAP.end()) {
3776 notifyEvent = iter->second;
3777 }
3778 if (((status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3779 status == ScreenPowerStatus::POWER_STATUS_DOZE) &&
3780 gotScreenlockFingerprint_ == true) &&
3781 prePowerStateChangeReason_ != PowerStateChangeReason::STATE_CHANGE_REASON_SHUT_DOWN) {
3782 gotScreenlockFingerprint_ = false;
3783 TLOGI(WmsLogTag::DMS, "[UL_POWER] screenlockFingerprint or shutdown");
3784 return NotifyDisplayPowerEvent(notifyEvent, EventStatus::END, reason);
3785 }
3786 #ifdef FOLD_ABILITY_ENABLE
3787 if (foldScreenController_ != nullptr) {
3788 CallRsSetScreenPowerStatusSyncForFold(status);
3789 CallRsSetScreenPowerStatusSyncForExtend(screenIds, status);
3790 TryToRecoverFoldDisplayMode(status);
3791 } else {
3792 SetRsSetScreenPowerStatusSync(screenIds, status);
3793 }
3794 #else
3795 SetRsSetScreenPowerStatusSync(screenIds, status);
3796 #endif
3797 HandlerSensor(status, reason);
3798 if (reason == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3799 return true;
3800 }
3801 if ((status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3802 status == ScreenPowerStatus::POWER_STATUS_DOZE) &&
3803 gotScreenlockFingerprint_ == true) {
3804 gotScreenlockFingerprint_ = false;
3805 }
3806
3807 return NotifyDisplayPowerEvent(notifyEvent, EventStatus::END, reason);
3808 }
3809
SetRsSetScreenPowerStatusSync(std::vector<ScreenId> & screenIds,ScreenPowerStatus status)3810 void ScreenSessionManager::SetRsSetScreenPowerStatusSync(std::vector<ScreenId>& screenIds,
3811 ScreenPowerStatus status)
3812 {
3813 if (g_isPcDevice && status == ScreenPowerStatus::POWER_STATUS_ON) {
3814 std::sort(screenIds.begin(), screenIds.end(), SortByScreenId);
3815 for (auto screenId : screenIds) {
3816 TLOGI(WmsLogTag::DMS, "[UL_POWER] Power on, screen id is %{public}d", (int)screenId);
3817 if (GetIsOuterOnlyMode() == true && screenId == SCREEN_ID_FULL) {
3818 TLOGI(WmsLogTag::DMS, "Power on skip");
3819 continue;
3820 }
3821 CallRsSetScreenPowerStatusSync(screenId, status);
3822 }
3823 } else if (g_isPcDevice && (status == ScreenPowerStatus::POWER_STATUS_OFF ||
3824 status == ScreenPowerStatus::POWER_STATUS_SUSPEND)) {
3825 std::sort(screenIds.begin(), screenIds.end(), SortByScreenId);
3826 std::reverse(screenIds.begin(), screenIds.end());
3827 for (auto screenId : screenIds) {
3828 TLOGI(WmsLogTag::DMS, "[UL_POWER] Power off, screen id is %{public}d", (int)screenId);
3829 CallRsSetScreenPowerStatusSync(screenId, status);
3830 }
3831 } else {
3832 for (auto screenId : screenIds) {
3833 CallRsSetScreenPowerStatusSync(screenId, status);
3834 }
3835 }
3836 }
3837
CallRsSetScreenPowerStatusSyncForExtend(const std::vector<ScreenId> & screenIds,ScreenPowerStatus status)3838 void ScreenSessionManager::CallRsSetScreenPowerStatusSyncForExtend(const std::vector<ScreenId>& screenIds,
3839 ScreenPowerStatus status)
3840 {
3841 for (auto screenId : screenIds) {
3842 auto session = GetScreenSession(screenId);
3843 if (session && session->GetScreenProperty().GetScreenType() == ScreenType::REAL && !session->isInternal_) {
3844 CallRsSetScreenPowerStatusSync(screenId, status);
3845 }
3846 }
3847 }
3848 #ifdef FOLD_ABILITY_ENABLE
SetScreenPowerForFold(ScreenPowerStatus status)3849 void ScreenSessionManager::SetScreenPowerForFold(ScreenPowerStatus status)
3850 {
3851 if (foldScreenController_ == nullptr) {
3852 TLOGW(WmsLogTag::DMS, "foldScreenController_ is null");
3853 return;
3854 }
3855 SetScreenPowerForFold(foldScreenController_->GetCurrentScreenId(), status);
3856 }
3857
SetScreenPowerForFold(ScreenId screenId,ScreenPowerStatus status)3858 void ScreenSessionManager::SetScreenPowerForFold(ScreenId screenId, ScreenPowerStatus status)
3859 {
3860 if (status != ScreenPowerStatus::POWER_STATUS_OFF) {
3861 SetRSScreenPowerStatus(screenId, status);
3862 return;
3863 }
3864 static bool isNeedScreenOffDevice =
3865 (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() ||
3866 FoldScreenStateInternel::IsDualDisplayFoldDevice() ||
3867 FoldScreenStateInternel::IsSingleDisplayFoldDevice());
3868 if ((lastPowerForAllStatus_.load() == ScreenPowerStatus::POWER_STATUS_ON_ADVANCED ||
3869 lastPowerForAllStatus_.load() == ScreenPowerStatus::POWER_STATUS_SUSPEND) &&
3870 screenId == SCREEN_ID_MAIN && lastScreenId_.load() == SCREEN_ID_MAIN && isNeedScreenOffDevice) {
3871 if (!IsInAod()) {
3872 TLOGW(WmsLogTag::DMS, "preStatus:%{public}d, screenId:%{public}" PRIu64"",
3873 lastPowerForAllStatus_.load(), screenId);
3874 SetRSScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
3875 lastScreenId_ = SCREEN_ID_INVALID;
3876 lastPowerForAllStatus_ = ScreenPowerStatus::INVALID_POWER_STATUS;
3877 }
3878 }
3879 SetRSScreenPowerStatus(screenId, status);
3880 }
3881
TriggerDisplayModeUpdate(FoldDisplayMode targetDisplayMode)3882 void ScreenSessionManager::TriggerDisplayModeUpdate(FoldDisplayMode targetDisplayMode)
3883 {
3884 auto updateDisplayModeTask = [=] {
3885 TLOGNI(WmsLogTag::DMS, "start change displaymode to lastest mode");
3886 foldScreenController_->SetDisplayMode(targetDisplayMode);
3887 };
3888 taskScheduler_->PostAsyncTask(updateDisplayModeTask, "updateDisplayModeTask");
3889 }
3890 #endif
CallRsSetScreenPowerStatusSync(ScreenId screenId,ScreenPowerStatus status)3891 void ScreenSessionManager::CallRsSetScreenPowerStatusSync(ScreenId screenId, ScreenPowerStatus status)
3892 {
3893 auto rsSetScreenPowerStatusTask = [=] {
3894 bool phyMirrorEnable = IsDefaultMirrorMode(screenId);
3895 if (phyMirrorEnable && !g_isPcDevice) {
3896 auto screenSession = GetScreenSession(screenId);
3897 if (screenSession == nullptr) {
3898 return;
3899 }
3900 auto sourceMode = screenSession->GetSourceMode();
3901 if (status != ScreenPowerStatus::POWER_STATUS_ON &&
3902 powerStateChangeReason_ == PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION) {
3903 return;
3904 }
3905 if (sourceMode == ScreenSourceMode::SCREEN_UNIQUE &&
3906 status != ScreenPowerStatus::POWER_STATUS_ON &&
3907 powerStateChangeReason_ == PowerStateChangeReason::STATE_CHANGE_REASON_HARD_KEY) {
3908 return;
3909 }
3910 }
3911 SetRSScreenPowerStatus(screenId, status);
3912 };
3913 screenPowerTaskScheduler_->PostVoidSyncTask(rsSetScreenPowerStatusTask, "rsInterface_.SetScreenPowerStatus task");
3914 }
3915
CallRsSetScreenPowerStatusSyncForFold(ScreenPowerStatus status)3916 void ScreenSessionManager::CallRsSetScreenPowerStatusSyncForFold(ScreenPowerStatus status)
3917 {
3918 #ifdef FOLD_ABILITY_ENABLE
3919 auto rsSetScreenPowerStatusTask = [=] {
3920 if (foldScreenController_ == nullptr) {
3921 TLOGNW(WmsLogTag::DMS, "foldScreenController_ is null");
3922 return;
3923 }
3924 ScreenId screenId = foldScreenController_->GetCurrentScreenId();
3925 lastPowerForAllStatus_.store(status);
3926 lastScreenId_.store(screenId);
3927 SetRSScreenPowerStatus(screenId, status);
3928 };
3929 screenPowerTaskScheduler_->PostVoidSyncTask(rsSetScreenPowerStatusTask, "rsInterface_.SetScreenPowerStatus task");
3930 #endif
3931 }
3932
SetKeyguardDrawnDoneFlag(bool flag)3933 void ScreenSessionManager::SetKeyguardDrawnDoneFlag(bool flag)
3934 {
3935 keyguardDrawnDone_ = flag;
3936 }
3937
HandlerSensor(ScreenPowerStatus status,PowerStateChangeReason reason)3938 void ScreenSessionManager::HandlerSensor(ScreenPowerStatus status, PowerStateChangeReason reason)
3939 {
3940 if (!ScreenSceneConfig::IsSupportRotateWithSensor()) {
3941 TLOGW(WmsLogTag::DMS, "not supportRotateWithSensor.");
3942 return;
3943 }
3944 if (status == ScreenPowerStatus::POWER_STATUS_ON) {
3945 DmsXcollie dmsXcollie("DMS:SubscribeRotationSensor", XCOLLIE_TIMEOUT_10S);
3946 TLOGI(WmsLogTag::DMS, "subscribe rotation and posture sensor when phone turn on");
3947 ScreenSensorConnector::SubscribeRotationSensor();
3948 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
3949 if (g_foldScreenFlag && reason != PowerStateChangeReason::STATE_CHANGE_REASON_DISPLAY_SWITCH) {
3950 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
3951 SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
3952 SecondaryFoldSensorManager::GetInstance().PowerKeySetScreenActiveRect();
3953 } else {
3954 FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
3955 }
3956 } else {
3957 TLOGI(WmsLogTag::DMS, "not fold product, switch screen reason, failed register posture.");
3958 }
3959 #endif
3960 } else if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND ||
3961 status == ScreenPowerStatus::POWER_STATUS_DOZE || status == ScreenPowerStatus::POWER_STATUS_DOZE_SUSPEND) {
3962 UnregisterInHandlerSensorWithPowerOff(reason);
3963 } else {
3964 TLOGI(WmsLogTag::DMS, "SetScreenPower state not support");
3965 screenEventTracker_.RecordEvent("HandlerSensor start!");
3966 }
3967 }
3968
UnregisterInHandlerSensorWithPowerOff(PowerStateChangeReason reason)3969 void ScreenSessionManager::UnregisterInHandlerSensorWithPowerOff(PowerStateChangeReason reason)
3970 {
3971 TLOGI(WmsLogTag::DMS, "unsubscribe sensor when off");
3972 if (isMultiScreenCollaboration_) {
3973 TLOGI(WmsLogTag::DMS, "[UL_POWER]MultiScreenCollaboration, not unsubscribe rotation sensor");
3974 } else {
3975 DmsXcollie dmsXcollie("DMS:UnsubscribeRotationSensor", XCOLLIE_TIMEOUT_10S);
3976 ScreenSensorConnector::UnsubscribeRotationSensor();
3977 }
3978 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
3979 if (g_foldScreenFlag && reason != PowerStateChangeReason::STATE_CHANGE_REASON_DISPLAY_SWITCH &&
3980 !FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
3981 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
3982 SecondaryFoldSensorManager::GetInstance().UnRegisterPostureCallback();
3983 SecondaryFoldSensorManager::GetInstance().isPowerRectExe_ = false;
3984 } else {
3985 FoldScreenSensorManager::GetInstance().UnRegisterPostureCallback();
3986 }
3987 } else {
3988 TLOGI(WmsLogTag::DMS, "not fold product, failed unregister posture.");
3989 }
3990 #endif
3991 }
3992
BootFinishedCallback(const char * key,const char * value,void * context)3993 void ScreenSessionManager::BootFinishedCallback(const char *key, const char *value, void *context)
3994 {
3995 if (strcmp(key, BOOTEVENT_BOOT_COMPLETED.c_str()) == 0 && strcmp(value, "true") == 0) {
3996 TLOGI(WmsLogTag::DMS, "boot animation finished");
3997 auto &that = *reinterpret_cast<ScreenSessionManager *>(context);
3998 that.SetRotateLockedFromSettingData();
3999 that.SetDpiFromSettingData();
4000 that.SetExtendScreenDpi();
4001 that.UpdateDisplayState(that.GetAllScreenIds(), DisplayState::ON);
4002 that.RegisterSettingDpiObserver();
4003 that.RegisterSettingExtendScreenDpiObserver();
4004 if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
4005 that.RegisterSettingDuringCallStateObserver();
4006 }
4007 if (that.foldScreenPowerInit_ != nullptr) {
4008 that.foldScreenPowerInit_();
4009 }
4010 that.RegisterSettingRotationObserver();
4011 if (that.defaultDpi) {
4012 auto ret = ScreenSettingHelper::SetSettingDefaultDpi(that.defaultDpi, SET_SETTING_DPI_KEY);
4013 if (!ret) {
4014 TLOGE(WmsLogTag::DMS, "set setting defaultDpi failed");
4015 } else {
4016 TLOGI(WmsLogTag::DMS, "set setting defaultDpi:%{public}d", that.defaultDpi);
4017 }
4018 }
4019 #ifdef FOLD_ABILITY_ENABLE
4020 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
4021 auto screenSession = that.GetDefaultScreenSession();
4022 if (screenSession == nullptr) {
4023 TLOGE(WmsLogTag::DMS, "screen session is null!");
4024 return;
4025 }
4026 ScreenId screenId = screenSession->GetScreenId();
4027 SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
4028 TLOGI(WmsLogTag::DMS, "SuperFoldStatus: %{public}u", status);
4029 that.OnSuperFoldStatusChange(screenId, status);
4030 float sensorRotation = screenSession->GetSensorRotation();
4031 TLOGI(WmsLogTag::DMS, "sensorRotation: %{public}f", sensorRotation);
4032 if (sensorRotation >= 0.0f) {
4033 that.OnSensorRotationChange(sensorRotation, screenId);
4034 }
4035 screenSession->PropertyChange(screenSession->GetScreenProperty(),
4036 ScreenPropertyChangeReason::SUPER_FOLD_STATUS_CHANGE);
4037 }
4038 #endif
4039 }
4040 }
4041
SetFoldScreenPowerInit(std::function<void ()> foldScreenPowerInit)4042 void ScreenSessionManager::SetFoldScreenPowerInit(std::function<void()> foldScreenPowerInit)
4043 {
4044 foldScreenPowerInit_ = foldScreenPowerInit;
4045 }
4046
SetRotateLockedFromSettingData()4047 void ScreenSessionManager::SetRotateLockedFromSettingData()
4048 {
4049 uint32_t autoRotateStatus = AUTO_ROTATE_OFF; // 0代表自动旋转关闭,1代表自动旋转打开
4050 bool islocked = true;
4051 // ret为true表示从数据库读到了值,并赋给了autoRotateStatus
4052 bool ret = ScreenSettingHelper::GetSettingValue(autoRotateStatus, SETTING_LOCKED_KEY);
4053 TLOGI(WmsLogTag::DMS, "get autoRotateStatus from settingdata: %{public}u", autoRotateStatus);
4054 if (autoRotateStatus) {
4055 islocked =false;
4056 }
4057 if (ret) {
4058 TLOGI(WmsLogTag::DMS, "get islocked success");
4059 SetScreenRotationLockedFromJs(islocked);
4060 }
4061 }
4062
RegisterSettingDpiObserver()4063 void ScreenSessionManager::RegisterSettingDpiObserver()
4064 {
4065 TLOGI(WmsLogTag::DMS, "Register Setting Dpi Observer");
4066 SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetDpiFromSettingData(); };
4067 ScreenSettingHelper::RegisterSettingDpiObserver(updateFunc);
4068 }
4069
SetDpiFromSettingData()4070 void ScreenSessionManager::SetDpiFromSettingData()
4071 {
4072 uint32_t settingDpi;
4073 bool ret = ScreenSettingHelper::GetSettingDpi(settingDpi);
4074 if (!ret) {
4075 settingDpi = defaultDpi;
4076 TLOGW(WmsLogTag::DMS, "get setting dpi failed,use default dpi,defaultDpi: %{public}u", settingDpi);
4077 } else {
4078 TLOGI(WmsLogTag::DMS, "get setting dpi success,settingDpi: %{public}u", settingDpi);
4079 }
4080 if (settingDpi >= DOT_PER_INCH_MINIMUM_VALUE && settingDpi <= DOT_PER_INCH_MAXIMUM_VALUE
4081 && cachedSettingDpi_ != settingDpi) {
4082 cachedSettingDpi_ = settingDpi;
4083 float dpi = static_cast<float>(settingDpi) / BASELINE_DENSITY;
4084 ScreenId defaultScreenId = GetDefaultScreenId();
4085 if (g_isPcDevice) {
4086 ScreenId screenId = screenIdManager_.ConvertToSmsScreenId(RS_ID_DEFAULT);
4087 if (screenId != SCREEN_ID_INVALID) {
4088 TLOGI(WmsLogTag::DMS, "get ScreenId:%{public}" PRIu64" for rsId successful", screenId);
4089 defaultScreenId = screenId;
4090 }
4091 }
4092 SetVirtualPixelRatio(defaultScreenId, dpi);
4093 if (g_isPcDevice) {
4094 SetExtendPixelRatio(dpi * g_extendScreenDpiCoef);
4095 }
4096 } else {
4097 TLOGE(WmsLogTag::DMS, "setting dpi error, settingDpi: %{public}d", settingDpi);
4098 }
4099 }
4100
SetExtendPixelRatio(const float & dpi)4101 void ScreenSessionManager::SetExtendPixelRatio(const float& dpi)
4102 {
4103 auto screenIds = GetAllScreenIds();
4104 if (screenIds.empty()) {
4105 TLOGE(WmsLogTag::DMS, "no screenId");
4106 return;
4107 }
4108 for (auto screenId : screenIds) {
4109 auto screenSession = GetScreenSession(screenId);
4110 if (screenSession == nullptr) {
4111 TLOGE(WmsLogTag::DMS, "screensession is nullptr, screenId: %{public}" PRIu64"", screenId);
4112 continue;
4113 }
4114 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL && !screenSession->isInternal_) {
4115 SetVirtualPixelRatio(screenId, dpi);
4116 }
4117 }
4118 }
4119
GetAllScreenIds()4120 std::vector<ScreenId> ScreenSessionManager::GetAllScreenIds()
4121 {
4122 std::vector<ScreenId> res;
4123 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4124 for (const auto& iter : screenSessionMap_) {
4125 res.emplace_back(iter.first);
4126 }
4127 return res;
4128 }
4129
GetPhysicalScreenIds(std::vector<ScreenId> & screenIds)4130 DMError ScreenSessionManager::GetPhysicalScreenIds(std::vector<ScreenId>& screenIds)
4131 {
4132 TLOGI(WmsLogTag::DMS, "enter");
4133 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4134 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
4135 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4136 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4137 }
4138
4139 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4140 for (const auto& iter : screenSessionMap_) {
4141 auto screenSession = iter.second;
4142 auto screenId = iter.first;
4143 if (screenSession == nullptr) {
4144 TLOGE(WmsLogTag::DMS, "screensession is nullptr, screenId: %{public}" PRIu64, screenId);
4145 continue;
4146 }
4147 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL
4148 && screenId != SCREEN_ID_INVALID) {
4149 screenIds.emplace_back(screenId);
4150 }
4151 }
4152 return DMError::DM_OK;
4153 }
4154
GetDisplayState(DisplayId displayId)4155 DisplayState ScreenSessionManager::GetDisplayState(DisplayId displayId)
4156 {
4157 return sessionDisplayPowerController_->GetDisplayState(displayId);
4158 }
4159
NotifyDisplayEvent(DisplayEvent event)4160 void ScreenSessionManager::NotifyDisplayEvent(DisplayEvent event)
4161 {
4162 TLOGI(WmsLogTag::DMS, "[UL_POWER] receive keyguardDrawnDone");
4163 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4164 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
4165 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4166 return;
4167 }
4168 sessionDisplayPowerController_->NotifyDisplayEvent(event);
4169 if (event == DisplayEvent::KEYGUARD_DRAWN) {
4170 keyguardDrawnDone_ = true;
4171 TLOGI(WmsLogTag::DMS, "[UL_POWER]keyguardDrawnDone_ is true");
4172 if (needScreenOnWhenKeyguardNotify_) {
4173 std::unique_lock <std::mutex> lock(screenOnMutex_);
4174 screenOnCV_.notify_all();
4175 TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOnCV_ notify one");
4176 needScreenOnWhenKeyguardNotify_ = false;
4177 }
4178 }
4179 if (event == DisplayEvent::SCREEN_LOCK_SUSPEND) {
4180 TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock suspend");
4181 if (isPhyScreenConnected_) {
4182 isScreenLockSuspend_ = false;
4183 TLOGI(WmsLogTag::DMS, "[UL_POWER]isScreenLockSuspend__ is false");
4184 } else {
4185 isScreenLockSuspend_ = true;
4186 }
4187 SetGotScreenOffAndWakeUpBlock();
4188 }
4189 if (event == DisplayEvent::SCREEN_LOCK_OFF) {
4190 TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock off");
4191 isScreenLockSuspend_ = false;
4192 TLOGI(WmsLogTag::DMS, "[UL_POWER]isScreenLockSuspend__ is false");
4193 SetGotScreenOffAndWakeUpBlock();
4194 }
4195 if (event == DisplayEvent::SCREEN_LOCK_FINGERPRINT) {
4196 TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock fingerprint");
4197 gotScreenlockFingerprint_ = true;
4198 SetGotScreenOffAndWakeUpBlock();
4199 }
4200 if (event == DisplayEvent::SCREEN_LOCK_DOZE_FINISH) {
4201 TLOGI(WmsLogTag::DMS, "[UL_POWER]screen lock doze finish");
4202 SetGotScreenOffAndWakeUpBlock();
4203 }
4204 WakeUpPictureFrameBlock(event);
4205 }
4206
SetGotScreenOffAndWakeUpBlock()4207 void ScreenSessionManager::SetGotScreenOffAndWakeUpBlock()
4208 {
4209 gotScreenOffNotify_ = true;
4210 if (needScreenOffNotify_) {
4211 ScreenOffCVNotify();
4212 }
4213 }
4214
ScreenOffCVNotify(void)4215 void ScreenSessionManager::ScreenOffCVNotify(void)
4216 {
4217 std::unique_lock <std::mutex> lock(screenOffMutex_);
4218 screenOffCV_.notify_all();
4219 needScreenOffNotify_ = false;
4220 TLOGI(WmsLogTag::DMS, "[UL_POWER]screenOffCV_ notify one");
4221 }
4222
GetScreenPower(ScreenId screenId)4223 ScreenPowerState ScreenSessionManager::GetScreenPower(ScreenId screenId)
4224 {
4225 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4226 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
4227 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4228 return ScreenPowerState::INVALID_STATE;
4229 }
4230 auto state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance().GetScreenPowerStatus(screenId));
4231 std::ostringstream oss;
4232 oss << "GetScreenPower state:" << static_cast<uint32_t>(state) << " screenId:" << static_cast<uint64_t>(screenId);
4233 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
4234 screenEventTracker_.RecordEvent(oss.str());
4235 return state;
4236 }
4237
GetScreenPower()4238 ScreenPowerState ScreenSessionManager::GetScreenPower()
4239 {
4240 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4241 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
4242 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4243 return ScreenPowerState::INVALID_STATE;
4244 }
4245 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetScreenPower");
4246 ScreenPowerState state = ScreenPowerState::INVALID_STATE;
4247 #ifdef FOLD_ABILITY_ENABLE
4248 if (!g_foldScreenFlag || FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
4249 state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance()
4250 .GetScreenPowerStatus(GetDefaultScreenId()));
4251 } else {
4252 state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance()
4253 .GetScreenPowerStatus(foldScreenController_->GetCurrentScreenId()));
4254 }
4255 #else
4256 state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance()
4257 .GetScreenPowerStatus(foldScreenController_->GetCurrentScreenId()));
4258 #endif
4259 std::ostringstream oss;
4260 oss << "GetScreenPower state:" << static_cast<uint32_t>(state);
4261 TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
4262 screenEventTracker_.RecordEvent(oss.str());
4263 return state;
4264 }
4265
IsScreenRotationLocked(bool & isLocked)4266 DMError ScreenSessionManager::IsScreenRotationLocked(bool& isLocked)
4267 {
4268 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4269 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4270 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4271 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4272 }
4273 sptr<ScreenSession> screenSession = GetDefaultScreenSession();
4274 if (screenSession == nullptr) {
4275 TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
4276 return DMError::DM_ERROR_INVALID_PARAM;
4277 }
4278 isLocked = screenSession->IsScreenRotationLocked();
4279 TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
4280 return DMError::DM_OK;
4281 }
4282
SetScreenRotationLocked(bool isLocked)4283 DMError ScreenSessionManager::SetScreenRotationLocked(bool isLocked)
4284 {
4285 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4286 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4287 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4288 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4289 }
4290 sptr<ScreenSession> screenSession = GetDefaultScreenSession();
4291 if (screenSession == nullptr) {
4292 TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
4293 return DMError::DM_ERROR_INVALID_PARAM;
4294 }
4295 screenSession->SetScreenRotationLocked(isLocked);
4296 TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
4297 return DMError::DM_OK;
4298 }
4299
SetScreenRotationLockedFromJs(bool isLocked)4300 DMError ScreenSessionManager::SetScreenRotationLockedFromJs(bool isLocked)
4301 {
4302 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4303 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4304 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4305 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4306 }
4307 sptr<ScreenSession> screenSession = GetDefaultScreenSession();
4308 if (screenSession == nullptr) {
4309 TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
4310 return DMError::DM_ERROR_INVALID_PARAM;
4311 }
4312 screenSession->SetScreenRotationLockedFromJs(isLocked);
4313 TLOGI(WmsLogTag::DMS, "isLocked: %{public}u", isLocked);
4314 return DMError::DM_OK;
4315 }
4316
NotifyAndPublishEvent(sptr<DisplayInfo> displayInfo,ScreenId screenId,sptr<ScreenSession> screenSession)4317 void ScreenSessionManager::NotifyAndPublishEvent(sptr<DisplayInfo> displayInfo, ScreenId screenId,
4318 sptr<ScreenSession> screenSession)
4319 {
4320 if (displayInfo == nullptr || screenSession == nullptr) {
4321 TLOGE(WmsLogTag::DMS, "error, displayInfo or screenSession is nullptr");
4322 return;
4323 }
4324 NotifyDisplayChanged(displayInfo, DisplayChangeEvent::UPDATE_ROTATION);
4325 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
4326 UpdateDisplayScaleState(screenId);
4327 std::map<DisplayId, sptr<DisplayInfo>> emptyMap;
4328 NotifyDisplayStateChange(GetDefaultScreenId(), screenSession->ConvertToDisplayInfo(),
4329 emptyMap, DisplayStateChangeType::UPDATE_ROTATION);
4330 std::string identity = IPCSkeleton::ResetCallingIdentity();
4331 ScreenSessionPublish::GetInstance().PublishDisplayRotationEvent(
4332 displayInfo->GetScreenId(), displayInfo->GetRotation());
4333 IPCSkeleton::SetCallingIdentity(identity);
4334 }
4335
UpdateScreenDirectionInfo(ScreenId screenId,const ScreenDirectionInfo & directionInfo,ScreenPropertyChangeType screenPropertyChangeType,const RRect & bounds)4336 void ScreenSessionManager::UpdateScreenDirectionInfo(ScreenId screenId, const ScreenDirectionInfo& directionInfo,
4337 ScreenPropertyChangeType screenPropertyChangeType, const RRect& bounds)
4338 {
4339 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4340 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4341 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4342 return;
4343 }
4344 if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_END) {
4345 TLOGI(WmsLogTag::DMS, "ROTATION_END");
4346 return;
4347 }
4348 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4349 if (screenSession == nullptr) {
4350 TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"",
4351 screenId);
4352 return;
4353 }
4354 float screenComponentRotation = directionInfo.screenRotation_;
4355 float rotation = directionInfo.rotation_;
4356 float phyRotation = directionInfo.phyRotation_;
4357 screenSession->SetPhysicalRotation(phyRotation);
4358 screenSession->SetScreenComponentRotation(screenComponentRotation);
4359 screenSession->UpdateRotationOrientation(rotation, GetFoldDisplayMode(), bounds);
4360 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", rotation: %{public}f, screenComponentRotation: %{public}f",
4361 screenId, rotation, screenComponentRotation);
4362 }
4363
UpdateScreenRotationProperty(ScreenId screenId,const RRect & bounds,float rotation,ScreenPropertyChangeType screenPropertyChangeType,bool isSwitchUser)4364 void ScreenSessionManager::UpdateScreenRotationProperty(ScreenId screenId, const RRect& bounds, float rotation,
4365 ScreenPropertyChangeType screenPropertyChangeType, bool isSwitchUser)
4366 {
4367 std::ostringstream oss;
4368 std::string changeType = TransferPropertyChangeTypeToString(screenPropertyChangeType);
4369 oss << "screenId: " << screenId << " rotation: " << rotation << " width: " << bounds.rect_.width_ \
4370 << " height: " << bounds.rect_.height_ << " type: " << changeType;
4371 screenEventTracker_.RecordBoundsEvent(oss.str());
4372 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4373 TLOGE(WmsLogTag::DMS, "permission denied!");
4374 return;
4375 }
4376 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4377 if (screenSession == nullptr) {
4378 TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"", screenId);
4379 return;
4380 }
4381 UpdateScreenRotationPropertyForRs(screenSession, screenPropertyChangeType, bounds, rotation, isSwitchUser);
4382 {
4383 std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
4384 screenSession->UpdatePropertyAfterRotation(bounds, rotation, GetFoldDisplayMode());
4385 }
4386 if (g_isPcDevice) {
4387 sptr<ScreenSession> physicalScreen = GetPhysicalScreenSession(screenSession->GetRSScreenId());
4388 if (physicalScreen) {
4389 physicalScreen->UpdatePropertyAfterRotation(bounds, rotation, GetFoldDisplayMode());
4390 }
4391 NotifyScreenModeChange();
4392 }
4393 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
4394 NotifyAndPublishEvent(displayInfo, screenId, screenSession);
4395 }
4396
UpdateScreenRotationPropertyForRs(sptr<ScreenSession> & screenSession,ScreenPropertyChangeType screenPropertyChangeType,const RRect & bounds,float rotation,bool isSwitchUser)4397 void ScreenSessionManager::UpdateScreenRotationPropertyForRs(sptr<ScreenSession>& screenSession,
4398 ScreenPropertyChangeType screenPropertyChangeType, const RRect& bounds, float rotation, bool isSwitchUser)
4399 {
4400 DmsXcollie dmsXcollie("DMS:UpdateScreenRotationProperty:CacheForRotation", XCOLLIE_TIMEOUT_10S);
4401 if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_BEGIN) {
4402 // Rs is used to mark the start of the rotation animation
4403 TLOGI(WmsLogTag::DMS, "EnableCacheForRotation");
4404 RSInterfaces::GetInstance().EnableCacheForRotation();
4405 } else if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_END) {
4406 // Rs is used to mark the end of the rotation animation
4407 TLOGI(WmsLogTag::DMS, "DisableCacheForRotation");
4408 RSInterfaces::GetInstance().DisableCacheForRotation();
4409 return;
4410 } else if (screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY ||
4411 screenPropertyChangeType == ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY) {
4412 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
4413 TLOGI(WmsLogTag::DMS, "Update Screen Rotation Property Only");
4414 {
4415 std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
4416 screenSession->UpdatePropertyOnly(bounds, rotation, GetFoldDisplayMode());
4417 }
4418 if (screenPropertyChangeType != ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY) {
4419 NotifyDisplayChanged(displayInfo, DisplayChangeEvent::UPDATE_ROTATION);
4420 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
4421 }
4422 if(!isSwitchUser) {
4423 screenSession->UpdateDisplayNodeRotation(rotation);
4424 }
4425 return;
4426 }
4427 }
4428
NotifyDisplayChanged(sptr<DisplayInfo> displayInfo,DisplayChangeEvent event)4429 void ScreenSessionManager::NotifyDisplayChanged(sptr<DisplayInfo> displayInfo, DisplayChangeEvent event)
4430 {
4431 if (displayInfo == nullptr) {
4432 TLOGE(WmsLogTag::DMS, "error, displayInfo is nullptr.");
4433 return;
4434 }
4435 auto task = [=] {
4436 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
4437 if (event == DisplayChangeEvent::UPDATE_REFRESHRATE) {
4438 TLOGND(WmsLogTag::DMS, "evevt:%{public}d, displayId:%{public}" PRIu64", agent size: %{public}u",
4439 event, displayInfo->GetDisplayId(), static_cast<uint32_t>(agents.size()));
4440 } else {
4441 TLOGNI(WmsLogTag::DMS, "evevt:%{public}d, displayId:%{public}" PRIu64", agent size: %{public}u",
4442 event, displayInfo->GetDisplayId(), static_cast<uint32_t>(agents.size()));
4443 }
4444 if (agents.empty()) {
4445 return;
4446 }
4447 for (auto& agent : agents) {
4448 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
4449 if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
4450 agent->OnDisplayChange(displayInfo, event);
4451 }
4452 }
4453 };
4454 taskScheduler_->PostAsyncTask(task, "NotifyDisplayChanged");
4455 }
4456
SetOrientation(ScreenId screenId,Orientation orientation)4457 DMError ScreenSessionManager::SetOrientation(ScreenId screenId, Orientation orientation)
4458 {
4459 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4460 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4461 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4462 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4463 }
4464 if (orientation < Orientation::UNSPECIFIED || orientation > Orientation::REVERSE_HORIZONTAL) {
4465 TLOGE(WmsLogTag::DMS, "set: %{public}u", static_cast<uint32_t>(orientation));
4466 return DMError::DM_ERROR_INVALID_PARAM;
4467 }
4468 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetOrientation");
4469 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4470 if (screenSession == nullptr) {
4471 TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"", screenId);
4472 return DMError::DM_ERROR_NULLPTR;
4473 }
4474 // just for get orientation test
4475 screenSession->SetOrientation(orientation);
4476 screenSession->ScreenOrientationChange(orientation, GetFoldDisplayMode());
4477 return DMError::DM_OK;
4478 }
4479
SetRotation(ScreenId screenId,Rotation rotationAfter,bool isFromWindow)4480 bool ScreenSessionManager::SetRotation(ScreenId screenId, Rotation rotationAfter, bool isFromWindow)
4481 {
4482 TLOGI(WmsLogTag::DMS,
4483 "Enter, screenId: %{public}" PRIu64 ", rotation: %{public}u, isFromWindow: %{public}u,",
4484 screenId, rotationAfter, isFromWindow);
4485 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4486 if (screenSession == nullptr) {
4487 TLOGE(WmsLogTag::DMS, "error, cannot get screen with screenId: %{public}" PRIu64, screenId);
4488 return false;
4489 }
4490 if (rotationAfter == screenSession->GetRotation()) {
4491 TLOGE(WmsLogTag::DMS, "rotation not changed. screen %{public}" PRIu64" rotation %{public}u",
4492 screenId, rotationAfter);
4493 return false;
4494 }
4495 TLOGI(WmsLogTag::DMS, "set orientation. rotation %{public}u", rotationAfter);
4496 screenSession->SetRotation(rotationAfter);
4497 screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::ROTATION);
4498 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION);
4499 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::UPDATE_ROTATION);
4500 return true;
4501 }
4502
SetSensorSubscriptionEnabled()4503 void ScreenSessionManager::SetSensorSubscriptionEnabled()
4504 {
4505 isAutoRotationOpen_ = system::GetParameter("persist.display.ar.enabled", "1") == "1";
4506 if (!isAutoRotationOpen_) {
4507 TLOGE(WmsLogTag::DMS, "autoRotation is not open");
4508 return;
4509 }
4510 ScreenSensorConnector::SubscribeRotationSensor();
4511 TLOGI(WmsLogTag::DMS, "subscribe rotation sensor successful");
4512 }
4513
SetPostureAndHallSensorEnabled()4514 void ScreenSessionManager::SetPostureAndHallSensorEnabled()
4515 {
4516 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
4517 if (!g_foldScreenFlag) {
4518 TLOGI(WmsLogTag::DMS, "current device is not fold phone.");
4519 return;
4520 }
4521 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
4522 SecondaryFoldSensorManager::GetInstance().RegisterPostureCallback();
4523 SecondaryFoldSensorManager::GetInstance().RegisterHallCallback();
4524 } else {
4525 FoldScreenSensorManager::GetInstance().RegisterPostureCallback();
4526 FoldScreenSensorManager::GetInstance().RegisterHallCallback();
4527 }
4528 if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() &&
4529 !FoldScreenSensorManager::GetInstance().GetSensorRegisterStatus()) {
4530 TLOGI(WmsLogTag::DMS, "subscribe hall and posture failed, force change to full screen!");
4531 TriggerFoldStatusChange(FoldStatus::EXPAND);
4532 }
4533 TLOGI(WmsLogTag::DMS, "successful");
4534 screenEventTracker_.RecordEvent("Dms subscribe Posture and Hall sensor finished.");
4535 #endif
4536 }
4537
SetRotationFromWindow(Rotation targetRotation)4538 bool ScreenSessionManager::SetRotationFromWindow(Rotation targetRotation)
4539 {
4540 sptr<DisplayInfo> displayInfo = GetDefaultDisplayInfo();
4541 if (displayInfo == nullptr) {
4542 return false;
4543 }
4544 return SetRotation(displayInfo->GetScreenId(), targetRotation, true);
4545 }
4546
GetScreenModesByDisplayId(DisplayId displayId)4547 sptr<SupportedScreenModes> ScreenSessionManager::GetScreenModesByDisplayId(DisplayId displayId)
4548 {
4549 auto displayInfo = GetDisplayInfoById(displayId);
4550 if (displayInfo == nullptr) {
4551 TLOGE(WmsLogTag::DMS, "can not get display.");
4552 return nullptr;
4553 }
4554 auto screenInfo = GetScreenInfoById(displayInfo->GetScreenId());
4555 if (screenInfo == nullptr) {
4556 TLOGE(WmsLogTag::DMS, "can not get screen.");
4557 return nullptr;
4558 }
4559 auto modes = screenInfo->GetModes();
4560 auto id = screenInfo->GetModeId();
4561 if (id >= modes.size()) {
4562 TLOGE(WmsLogTag::DMS, "can not get screenMode.");
4563 return nullptr;
4564 }
4565 return modes[id];
4566 }
4567
GetScreenInfoByDisplayId(DisplayId displayId)4568 sptr<ScreenInfo> ScreenSessionManager::GetScreenInfoByDisplayId(DisplayId displayId)
4569 {
4570 auto displayInfo = GetDisplayInfoById(displayId);
4571 if (displayInfo == nullptr) {
4572 TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
4573 return nullptr;
4574 }
4575 return GetScreenInfoById(displayInfo->GetScreenId());
4576 }
4577
NotifyPowerEventForDualDisplay(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)4578 int ScreenSessionManager::NotifyPowerEventForDualDisplay(DisplayPowerEvent event, EventStatus status,
4579 PowerStateChangeReason reason)
4580 {
4581 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4582 if (screenSessionMap_.empty()) {
4583 TLOGE(WmsLogTag::DMS, "[UL_POWER]screenSessionMap is empty");
4584 return NOTIFY_EVENT_FOR_DUAL_FAILED;
4585 }
4586 #ifdef FOLD_ABILITY_ENABLE
4587 // The on/off screen will send a notification based on the number of screens.
4588 // The dual display device just notify the current screen usage
4589 if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
4590 ScreenId currentScreenId = foldScreenController_->GetCurrentScreenId();
4591 auto iter = screenSessionMap_.find(currentScreenId);
4592 if (iter != screenSessionMap_.end() && iter->second != nullptr) {
4593 iter->second->PowerStatusChange(event, status, reason);
4594 }
4595 return NOTIFY_EVENT_FOR_DUAL_SUCESS;
4596 }
4597 #endif
4598 return NO_NEED_NOTIFY_EVENT_FOR_DUAL;
4599 }
4600
NotifyDisplayPowerEvent(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)4601 bool ScreenSessionManager::NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status,
4602 PowerStateChangeReason reason)
4603 {
4604 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER);
4605 if (agents.empty()) {
4606 TLOGI(WmsLogTag::DMS, "[UL_POWER] agents is empty");
4607 return false;
4608 }
4609 TLOGD(WmsLogTag::DMS, "[UL_POWER] start");
4610 for (auto& agent : agents) {
4611 agent->NotifyDisplayPowerEvent(event, status);
4612 }
4613 auto ret = NotifyPowerEventForDualDisplay(event, status, reason);
4614 if (ret == NOTIFY_EVENT_FOR_DUAL_FAILED) {
4615 TLOGE(WmsLogTag::DMS, "[UL_POWER]NotifyPowerEventForDualDisplay ret false");
4616 return false;
4617 } else if (ret == NOTIFY_EVENT_FOR_DUAL_SUCESS) {
4618 TLOGD(WmsLogTag::DMS, "[UL_POWER]NotifyPowerEventForDualDisplay ret sucess");
4619 return true;
4620 }
4621 auto screenIds = GetAllScreenIds();
4622 if (screenIds.empty()) {
4623 TLOGI(WmsLogTag::DMS, "[UL_POWER]no screenID");
4624 return false;
4625 }
4626 auto screenId = screenIds[0];
4627 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4628 if (screenSession == nullptr) {
4629 TLOGE(WmsLogTag::DMS, "[UL_POWER]Cannot get ScreenSession, screenId: %{public}" PRIu64"", screenId);
4630 return false;
4631 }
4632 screenSession->PowerStatusChange(event, status, reason);
4633 return true;
4634 }
4635
NotifyDisplayStateChanged(DisplayId id,DisplayState state)4636 bool ScreenSessionManager::NotifyDisplayStateChanged(DisplayId id, DisplayState state)
4637 {
4638 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_STATE_LISTENER);
4639 if (agents.empty()) {
4640 TLOGI(WmsLogTag::DMS, "agents is empty");
4641 return false;
4642 }
4643 TLOGI(WmsLogTag::DMS, "notify enter!");
4644 for (auto& agent : agents) {
4645 agent->NotifyDisplayStateChanged(id, state);
4646 }
4647 return true;
4648 }
GetAllScreenInfos(std::vector<sptr<ScreenInfo>> & screenInfos)4649 DMError ScreenSessionManager::GetAllScreenInfos(std::vector<sptr<ScreenInfo>>& screenInfos)
4650 {
4651 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4652 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4653 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4654 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4655 }
4656 std::vector<ScreenId> screenIds = GetAllScreenIds();
4657 if (screenIds.empty()) {
4658 TLOGI(WmsLogTag::DMS, "[UL_POWER]no screen info");
4659 return DMError::DM_OK;
4660 }
4661 for (auto screenId : screenIds) {
4662 auto screenInfo = GetScreenInfoById(screenId);
4663 if (screenInfo == nullptr) {
4664 TLOGE(WmsLogTag::DMS, "cannot find screenInfo: %{public}" PRIu64"", screenId);
4665 continue;
4666 }
4667 screenInfos.emplace_back(screenInfo);
4668 }
4669 return DMError::DM_OK;
4670 }
4671
GetAllScreenIds() const4672 std::vector<ScreenId> ScreenSessionManager::GetAllScreenIds() const
4673 {
4674 std::vector<ScreenId> res;
4675 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4676 for (const auto& iter : screenSessionMap_) {
4677 res.emplace_back(iter.first);
4678 }
4679 return res;
4680 }
4681
GetScreenSupportedColorGamuts(ScreenId screenId,std::vector<ScreenColorGamut> & colorGamuts)4682 DMError ScreenSessionManager::GetScreenSupportedColorGamuts(ScreenId screenId,
4683 std::vector<ScreenColorGamut>& colorGamuts)
4684 {
4685 TLOGI(WmsLogTag::DMS, "ENTER");
4686 if (!SessionPermission::IsSystemCalling()) {
4687 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4688 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4689 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4690 }
4691 sptr<ScreenSession> screen = GetScreenSession(screenId);
4692 if (screen == nullptr) {
4693 TLOGE(WmsLogTag::DMS, "nullptr");
4694 return DMError::DM_ERROR_INVALID_PARAM;
4695 }
4696 return screen->GetScreenSupportedColorGamuts(colorGamuts);
4697 }
4698
GetPixelFormat(ScreenId screenId,GraphicPixelFormat & pixelFormat)4699 DMError ScreenSessionManager::GetPixelFormat(ScreenId screenId, GraphicPixelFormat& pixelFormat)
4700 {
4701 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64, screenId);
4702 if (screenId == SCREEN_ID_INVALID) {
4703 TLOGE(WmsLogTag::DMS, "screenId invalid");
4704 return DMError::DM_ERROR_INVALID_PARAM;
4705 }
4706 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4707 if (screenSession == nullptr) {
4708 return DMError::DM_ERROR_INVALID_PARAM;
4709 }
4710 return screenSession->GetPixelFormat(pixelFormat);
4711 }
4712
SetPixelFormat(ScreenId screenId,GraphicPixelFormat pixelFormat)4713 DMError ScreenSessionManager::SetPixelFormat(ScreenId screenId, GraphicPixelFormat pixelFormat)
4714 {
4715 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4716 TLOGE(WmsLogTag::DMS, "permission denied!");
4717 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4718 }
4719
4720 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", pixelFormat %{public}d",
4721 screenId, pixelFormat);
4722 if (screenId == SCREEN_ID_INVALID) {
4723 TLOGE(WmsLogTag::DMS, "screenId invalid");
4724 return DMError::DM_ERROR_INVALID_PARAM;
4725 }
4726 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4727 if (screenSession == nullptr) {
4728 return DMError::DM_ERROR_INVALID_PARAM;
4729 }
4730 return screenSession->SetPixelFormat(pixelFormat);
4731 }
4732
GetSupportedHDRFormats(ScreenId screenId,std::vector<ScreenHDRFormat> & hdrFormats)4733 DMError ScreenSessionManager::GetSupportedHDRFormats(ScreenId screenId,
4734 std::vector<ScreenHDRFormat>& hdrFormats)
4735 {
4736 #ifdef WM_SCREEN_HDR_FORMAT_ENABLE
4737 TLOGI(WmsLogTag::DMS, "start %{public}" PRIu64, screenId);
4738 if (screenId == SCREEN_ID_INVALID) {
4739 TLOGE(WmsLogTag::DMS, "screenId invalid");
4740 return DMError::DM_ERROR_INVALID_PARAM;
4741 }
4742 sptr<ScreenSession> screen = GetScreenSession(screenId);
4743 if (screen == nullptr) {
4744 TLOGE(WmsLogTag::DMS, "nullptr");
4745 return DMError::DM_ERROR_INVALID_PARAM;
4746 }
4747 return screen->GetSupportedHDRFormats(hdrFormats);
4748 #else
4749 return DMError::DM_OK;
4750 #endif
4751 }
4752
GetScreenHDRFormat(ScreenId screenId,ScreenHDRFormat & hdrFormat)4753 DMError ScreenSessionManager::GetScreenHDRFormat(ScreenId screenId, ScreenHDRFormat& hdrFormat)
4754 {
4755 #ifdef WM_SCREEN_HDR_FORMAT_ENABLE
4756 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64, screenId);
4757 if (screenId == SCREEN_ID_INVALID) {
4758 TLOGE(WmsLogTag::DMS, "screenId invalid");
4759 return DMError::DM_ERROR_INVALID_PARAM;
4760 }
4761 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4762 if (screenSession == nullptr) {
4763 return DMError::DM_ERROR_INVALID_PARAM;
4764 }
4765 return screenSession->GetScreenHDRFormat(hdrFormat);
4766 #else
4767 return DMError::DM_OK;
4768 #endif
4769 }
4770
SetScreenHDRFormat(ScreenId screenId,int32_t modeIdx)4771 DMError ScreenSessionManager::SetScreenHDRFormat(ScreenId screenId, int32_t modeIdx)
4772 {
4773 #ifdef WM_SCREEN_HDR_FORMAT_ENABLE
4774 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4775 TLOGE(WmsLogTag::DMS, "permission denied!");
4776 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4777 }
4778
4779 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", modeIdx %{public}d", screenId, modeIdx);
4780 if (screenId == SCREEN_ID_INVALID) {
4781 TLOGE(WmsLogTag::DMS, "screenId invalid");
4782 return DMError::DM_ERROR_INVALID_PARAM;
4783 }
4784 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4785 if (screenSession == nullptr) {
4786 return DMError::DM_ERROR_INVALID_PARAM;
4787 }
4788 return screenSession->SetScreenHDRFormat(modeIdx);
4789 #else
4790 return DMError::DM_OK;
4791 #endif
4792 }
4793
GetSupportedColorSpaces(ScreenId screenId,std::vector<GraphicCM_ColorSpaceType> & colorSpaces)4794 DMError ScreenSessionManager::GetSupportedColorSpaces(ScreenId screenId,
4795 std::vector<GraphicCM_ColorSpaceType>& colorSpaces)
4796 {
4797 #ifdef WM_SCREEN_COLOR_SPACE_ENABLE
4798 TLOGI(WmsLogTag::DMS, "start %{public}" PRIu64, screenId);
4799 if (screenId == SCREEN_ID_INVALID) {
4800 TLOGE(WmsLogTag::DMS, "screenId invalid");
4801 return DMError::DM_ERROR_INVALID_PARAM;
4802 }
4803 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4804 if (screenSession == nullptr) {
4805 TLOGE(WmsLogTag::DMS, "nullptr");
4806 return DMError::DM_ERROR_INVALID_PARAM;
4807 }
4808 return screenSession->GetSupportedColorSpaces(colorSpaces);
4809 #else
4810 return DMError::DM_OK;
4811 #endif
4812 }
4813
GetScreenColorSpace(ScreenId screenId,GraphicCM_ColorSpaceType & colorSpace)4814 DMError ScreenSessionManager::GetScreenColorSpace(ScreenId screenId, GraphicCM_ColorSpaceType& colorSpace)
4815 {
4816 #ifdef WM_SCREEN_COLOR_SPACE_ENABLE
4817 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64, screenId);
4818 if (screenId == SCREEN_ID_INVALID) {
4819 TLOGE(WmsLogTag::DMS, "screenId invalid");
4820 return DMError::DM_ERROR_INVALID_PARAM;
4821 }
4822 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4823 if (screenSession == nullptr) {
4824 return DMError::DM_ERROR_INVALID_PARAM;
4825 }
4826 return screenSession->GetScreenColorSpace(colorSpace);
4827 #else
4828 return DMError::DM_OK;
4829 #endif
4830 }
4831
SetScreenColorSpace(ScreenId screenId,GraphicCM_ColorSpaceType colorSpace)4832 DMError ScreenSessionManager::SetScreenColorSpace(ScreenId screenId, GraphicCM_ColorSpaceType colorSpace)
4833 {
4834 #ifdef WM_SCREEN_COLOR_SPACE_ENABLE
4835 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4836 TLOGE(WmsLogTag::DMS, "permission denied!");
4837 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4838 }
4839
4840 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 ", colorSpace %{public}d",
4841 screenId, colorSpace);
4842 if (screenId == SCREEN_ID_INVALID) {
4843 TLOGE(WmsLogTag::DMS, "screenId invalid");
4844 return DMError::DM_ERROR_INVALID_PARAM;
4845 }
4846 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4847 if (screenSession == nullptr) {
4848 return DMError::DM_ERROR_INVALID_PARAM;
4849 }
4850 return screenSession->SetScreenColorSpace(colorSpace);
4851 #else
4852 return DMError::DM_OK;
4853 #endif
4854 }
4855
AddVirtualScreenDeathRecipient(const sptr<IRemoteObject> & displayManagerAgent,ScreenId smsScreenId)4856 void ScreenSessionManager::AddVirtualScreenDeathRecipient(const sptr<IRemoteObject>& displayManagerAgent,
4857 ScreenId smsScreenId)
4858 {
4859 if (deathRecipient_ == nullptr) {
4860 TLOGW(WmsLogTag::DMS, "Create deathRecipient");
4861 deathRecipient_ =
4862 new(std::nothrow) AgentDeathRecipient([this](const sptr<IRemoteObject>& agent) { OnRemoteDied(agent); });
4863 }
4864 std::lock_guard<std::mutex> lock(screenAgentMapMutex_);
4865 if (deathRecipient_ != nullptr) {
4866 auto agIter = screenAgentMap_.find(displayManagerAgent);
4867 if (agIter == screenAgentMap_.end()) {
4868 displayManagerAgent->AddDeathRecipient(deathRecipient_);
4869 }
4870 }
4871 screenAgentMap_[displayManagerAgent].emplace_back(smsScreenId);
4872 }
4873
CreateVirtualScreen(VirtualScreenOption option,const sptr<IRemoteObject> & displayManagerAgent)4874 ScreenId ScreenSessionManager::CreateVirtualScreen(VirtualScreenOption option,
4875 const sptr<IRemoteObject>& displayManagerAgent)
4876 {
4877 if (!Permission::IsSystemCalling() && !SessionPermission::IsShellCall() &&
4878 !Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION)) {
4879 return ERROR_ID_NOT_SYSTEM_APP;
4880 }
4881 if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
4882 !SessionPermission::IsShellCall() && !Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION)) {
4883 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4884 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4885 return SCREEN_ID_INVALID;
4886 }
4887 if (option.virtualScreenType_ != VirtualScreenType::SCREEN_RECORDING) {
4888 ExitCoordination("CreateVirtualScreen(cast)");
4889 }
4890 TLOGI(WmsLogTag::DMS, "ENTER, virtualScreenType: %{public}u", static_cast<uint32_t>(option.virtualScreenType_));
4891 if (SessionPermission::IsBetaVersion()) {
4892 CheckAndSendHiSysEvent("CREATE_VIRTUAL_SCREEN", "hmos.screenrecorder");
4893 }
4894 auto clientProxy = GetClientProxy();
4895 if (clientProxy && option.missionIds_.size() > 0) {
4896 std::vector<uint64_t> surfaceNodeIds;
4897 clientProxy->OnGetSurfaceNodeIdsFromMissionIdsChanged(option.missionIds_, surfaceNodeIds, true);
4898 option.missionIds_ = surfaceNodeIds;
4899 }
4900 ScreenId rsId = rsInterface_.CreateVirtualScreen(option.name_, option.width_,
4901 option.height_, option.surface_, SCREEN_ID_INVALID, option.flags_);
4902 if (rsId == SCREEN_ID_INVALID) {
4903 TLOGI(WmsLogTag::DMS, "rsId is invalid");
4904 return SCREEN_ID_INVALID;
4905 }
4906 TLOGW(WmsLogTag::DMS, "rsId: %{public}" PRIu64"", rsId);
4907 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CreateVirtualScreen(%s)", option.name_.c_str());
4908 ScreenId smsScreenId = SCREEN_ID_INVALID;
4909 if (!screenIdManager_.ConvertToSmsScreenId(rsId, smsScreenId)) {
4910 TLOGW(WmsLogTag::DMS, "!ConvertToSmsScreenId(rsId, smsScreenId)");
4911 smsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsId);
4912 auto screenSession = InitVirtualScreen(smsScreenId, rsId, option);
4913 if (screenSession == nullptr) {
4914 TLOGW(WmsLogTag::DMS, "screenSession is nullptr");
4915 screenIdManager_.DeleteScreenId(smsScreenId);
4916 return SCREEN_ID_INVALID;
4917 }
4918 screenSession->SetName(option.name_);
4919 screenSession->SetMirrorScreenType(MirrorScreenType::VIRTUAL_MIRROR);
4920 screenSession->SetSecurity(option.isSecurity_);
4921 {
4922 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
4923 screenSessionMap_.insert(std::make_pair(smsScreenId, screenSession));
4924 }
4925 screenSession->SetVirtualScreenFlag(option.virtualScreenFlag_);
4926 NotifyScreenConnected(screenSession->ConvertToScreenInfo());
4927 TLOGW(WmsLogTag::DMS, "create success. ScreenId: %{public}" PRIu64", rsId: %{public}" PRIu64"",
4928 smsScreenId, rsId);
4929 if (displayManagerAgent == nullptr) {
4930 virtualScreenCount_ = virtualScreenCount_ + 1;
4931 NotifyCaptureStatusChanged();
4932 return smsScreenId;
4933 }
4934 AddVirtualScreenDeathRecipient(displayManagerAgent, smsScreenId);
4935 }
4936 virtualScreenCount_ = virtualScreenCount_ + 1;
4937 NotifyCaptureStatusChanged();
4938 return smsScreenId;
4939 }
4940
SetVirtualScreenSurface(ScreenId screenId,sptr<IBufferProducer> surface)4941 DMError ScreenSessionManager::SetVirtualScreenSurface(ScreenId screenId, sptr<IBufferProducer> surface)
4942 {
4943 bool isCallingByThirdParty = Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION);
4944 if (!(Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) &&
4945 !SessionPermission::IsShellCall() && !isCallingByThirdParty) {
4946 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
4947 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4948 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4949 }
4950 if (surface == nullptr) {
4951 TLOGE(WmsLogTag::DMS, "surface is null");
4952 return DMError::DM_ERROR_INVALID_PARAM;
4953 }
4954 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
4955 if (screenSession == nullptr) {
4956 TLOGE(WmsLogTag::DMS, "No such screen.");
4957 return isCallingByThirdParty ? DMError::DM_ERROR_NULLPTR : DMError::DM_ERROR_INVALID_PARAM;
4958 }
4959 TLOGW(WmsLogTag::DMS, "enter set virtual screen surface");
4960 ScreenId rsScreenId;
4961 int32_t res = -1;
4962 if (screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
4963 sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(surface);
4964 if (pSurface != nullptr) {
4965 res = rsInterface_.SetVirtualScreenSurface(rsScreenId, pSurface);
4966 }
4967 }
4968 if (res != 0) {
4969 TLOGE(WmsLogTag::DMS, "fail to set virtual screen surface in RenderService");
4970 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
4971 }
4972 return DMError::DM_OK;
4973 }
4974
AddVirtualScreenBlockList(const std::vector<int32_t> & persistentIds)4975 DMError ScreenSessionManager::AddVirtualScreenBlockList(const std::vector<int32_t>& persistentIds)
4976 {
4977 if (!Permission::IsSystemCalling()) {
4978 TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4979 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4980 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4981 }
4982 MockSessionManagerService::GetInstance().AddSkipSelfWhenShowOnVirtualScreenList(persistentIds);
4983 return DMError::DM_OK;
4984 }
4985
RemoveVirtualScreenBlockList(const std::vector<int32_t> & persistentIds)4986 DMError ScreenSessionManager::RemoveVirtualScreenBlockList(const std::vector<int32_t>& persistentIds)
4987 {
4988 if (!Permission::IsSystemCalling()) {
4989 TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
4990 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
4991 return DMError::DM_ERROR_NOT_SYSTEM_APP;
4992 }
4993 MockSessionManagerService::GetInstance().RemoveSkipSelfWhenShowOnVirtualScreenList(persistentIds);
4994 return DMError::DM_OK;
4995 }
4996
SetScreenPrivacyMaskImage(ScreenId screenId,const std::shared_ptr<Media::PixelMap> & privacyMaskImg)4997 DMError ScreenSessionManager::SetScreenPrivacyMaskImage(ScreenId screenId,
4998 const std::shared_ptr<Media::PixelMap>& privacyMaskImg)
4999 {
5000 if (!Permission::IsSystemCalling()) {
5001 TLOGE(WmsLogTag::DMS, "Permission Denied! calling clientName: %{public}s, calling pid: %{public}d",
5002 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5003 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5004 }
5005 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
5006 if (screenSession == nullptr) {
5007 TLOGE(WmsLogTag::DMS, "No such screen.");
5008 return DMError::DM_ERROR_NULLPTR;
5009 }
5010 ScreenId rsScreenId;
5011 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
5012 TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
5013 return DMError::DM_ERROR_INVALID_PARAM;
5014 }
5015 int32_t res = -1;
5016 if (privacyMaskImg == nullptr) {
5017 TLOGI(WmsLogTag::DMS, "Clearing screen privacy mask image for screenId: %{public}" PRIu64"",
5018 static_cast<uint64_t>(screenId));
5019 res = rsInterface_.SetScreenSecurityMask(rsScreenId, nullptr);
5020 if (res != 0) {
5021 TLOGE(WmsLogTag::DMS, "Fail to set privacy mask image in RenderService");
5022 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
5023 }
5024 return DMError::DM_OK;
5025 }
5026 TLOGI(WmsLogTag::DMS, "Setting screen privacy mask image for screenId: %{public}" PRIu64"",
5027 static_cast<uint64_t>(screenId));
5028 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetScreenSecurityMask(%" PRIu64")", screenId);
5029 res = rsInterface_.SetScreenSecurityMask(rsScreenId, privacyMaskImg);
5030 if (res != 0) {
5031 TLOGE(WmsLogTag::DMS, "Fail to set privacy mask image in RenderService");
5032 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
5033 }
5034 return DMError::DM_OK;
5035 }
5036
SetVirtualMirrorScreenScaleMode(ScreenId screenId,ScreenScaleMode scaleMode)5037 DMError ScreenSessionManager::SetVirtualMirrorScreenScaleMode(ScreenId screenId, ScreenScaleMode scaleMode)
5038 {
5039 if (!SessionPermission::IsSystemCalling()) {
5040 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5041 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5042 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5043 }
5044 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
5045 if (screenSession == nullptr) {
5046 TLOGE(WmsLogTag::DMS, "No such screen.");
5047 return DMError::DM_ERROR_INVALID_PARAM;
5048 }
5049 ScreenId rsScreenId;
5050 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
5051 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
5052 return DMError::DM_ERROR_INVALID_PARAM;
5053 }
5054 bool res = rsInterface_.SetVirtualMirrorScreenScaleMode(rsScreenId, scaleMode);
5055 if (!res) {
5056 TLOGE(WmsLogTag::DMS, "failed in RenderService");
5057 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
5058 }
5059 return DMError::DM_OK;
5060 }
5061
SetVirtualMirrorScreenCanvasRotation(ScreenId screenId,bool autoRotate)5062 DMError ScreenSessionManager::SetVirtualMirrorScreenCanvasRotation(ScreenId screenId, bool autoRotate)
5063 {
5064 if (!SessionPermission::IsSystemCalling()) {
5065 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5066 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5067 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5068 }
5069 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
5070 if (screenSession == nullptr) {
5071 TLOGE(WmsLogTag::DMS, "No such screen.");
5072 return DMError::DM_ERROR_INVALID_PARAM;
5073 }
5074 TLOGW(WmsLogTag::DMS, "enter set virtual mirror screen canvas rotation");
5075 bool res = false;
5076 ScreenId rsScreenId;
5077 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
5078 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
5079 return DMError::DM_ERROR_INVALID_PARAM;
5080 }
5081 res = rsInterface_.SetVirtualMirrorScreenCanvasRotation(rsScreenId, autoRotate);
5082 if (!res) {
5083 TLOGE(WmsLogTag::DMS, "failed in RenderService");
5084 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
5085 }
5086 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
5087 screenSession->SetIsEnableCanvasRotation(autoRotate);
5088 }
5089 TLOGW(WmsLogTag::DMS, "success");
5090 return DMError::DM_OK;
5091 }
5092
ResizeVirtualScreen(ScreenId screenId,uint32_t width,uint32_t height)5093 DMError ScreenSessionManager::ResizeVirtualScreen(ScreenId screenId, uint32_t width, uint32_t height)
5094 {
5095 if (!SessionPermission::IsSystemCalling()) {
5096 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5097 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5098 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5099 }
5100 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64", width: %{public}u, height: %{public}u.",
5101 screenId, width, height);
5102 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
5103 if (screenSession == nullptr) {
5104 TLOGE(WmsLogTag::DMS, "No such screen.");
5105 return DMError::DM_ERROR_INVALID_PARAM;
5106 }
5107 ScreenId rsScreenId;
5108 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
5109 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
5110 return DMError::DM_ERROR_INVALID_PARAM;
5111 }
5112 rsInterface_.ResizeVirtualScreen(rsScreenId, width, height);
5113 screenSession->Resize(width, height);
5114 screenSession->PropertyChange(screenSession->GetScreenProperty(),
5115 ScreenPropertyChangeReason::VIRTUAL_SCREEN_RESIZE);
5116 return DMError::DM_OK;
5117 }
5118
DestroyVirtualScreen(ScreenId screenId)5119 DMError ScreenSessionManager::DestroyVirtualScreen(ScreenId screenId)
5120 {
5121 bool isCallingByThirdParty = Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION);
5122 if (!SessionPermission::IsSystemCalling() && !isCallingByThirdParty) {
5123 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5124 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5125 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5126 }
5127 if (static_cast<uint64_t>(screenId) < static_cast<uint64_t>(MINIMUM_VIRTUAL_SCREEN_ID)) {
5128 TLOGE(WmsLogTag::DMS, "virtual screenId is invalid, id: %{public}" PRIu64"", static_cast<uint64_t>(screenId));
5129 return DMError::DM_ERROR_INVALID_PARAM;
5130 }
5131 // virtual screen destroy callback to notify scb
5132 TLOGW(WmsLogTag::DMS, "start");
5133 OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED);
5134 ScreenId rsScreenId = SCREEN_ID_INVALID;
5135 {
5136 std::lock_guard<std::mutex> lock(screenAgentMapMutex_);
5137 screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
5138 for (auto &agentIter : screenAgentMap_) {
5139 auto iter = std::find(agentIter.second.begin(), agentIter.second.end(), screenId);
5140 if (iter != agentIter.second.end()) {
5141 iter = agentIter.second.erase(iter);
5142 if (agentIter.first != nullptr && agentIter.second.empty()) {
5143 screenAgentMap_.erase(agentIter.first);
5144 }
5145 break;
5146 }
5147 }
5148 }
5149 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyVirtualScreen(%" PRIu64")", screenId);
5150 auto screen = GetScreenSession(screenId);
5151 if (rsScreenId != SCREEN_ID_INVALID && screen != nullptr) {
5152 NotifyDisplayDestroy(screenId);
5153 {
5154 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5155 auto screenGroup = RemoveFromGroupLocked(screen);
5156 if (screenGroup != nullptr) {
5157 NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
5158 }
5159 screenSessionMap_.erase(screenId);
5160 }
5161 RemoveScreenCastInfo(screenId);
5162 NotifyScreenDisconnected(screenId);
5163 if (auto clientProxy = GetClientProxy()) {
5164 clientProxy->OnVirtualScreenDisconnected(rsScreenId);
5165 }
5166 TLOGW(WmsLogTag::DMS, "destroy success, id: %{public}" PRIu64 ", rsId: %{public}" PRIu64, screenId, rsScreenId);
5167 }
5168 screenIdManager_.DeleteScreenId(screenId);
5169 virtualScreenCount_ = virtualScreenCount_ > 0 ? virtualScreenCount_ - 1 : 0;
5170 NotifyCaptureStatusChanged();
5171 if (rsScreenId == SCREEN_ID_INVALID) {
5172 TLOGE(WmsLogTag::DMS, "No corresponding rsScreenId");
5173 return isCallingByThirdParty ? DMError::DM_ERROR_NULLPTR : DMError::DM_ERROR_INVALID_PARAM;
5174 }
5175 rsInterface_.RemoveVirtualScreen(rsScreenId);
5176 return DMError::DM_OK;
5177 }
5178
DisableMirror(bool disableOrNot)5179 DMError ScreenSessionManager::DisableMirror(bool disableOrNot)
5180 {
5181 TLOGW(WmsLogTag::DMS, "start %{public}d", disableOrNot);
5182 if (!SessionPermission::IsSystemCalling()) {
5183 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5184 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5185 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5186 }
5187 TLOGI(WmsLogTag::DMS, "enter %{public}d", disableOrNot);
5188 if (disableOrNot) {
5189 std::vector<ScreenId> screenIds;
5190 auto allScreenIds = GetAllScreenIds();
5191 for (auto screenId : allScreenIds) {
5192 auto screen = GetScreenSession(screenId);
5193 if (screen && screen->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
5194 screenIds.push_back(screenId);
5195 }
5196 }
5197 StopMirror(screenIds);
5198 }
5199 return DMError::DM_OK;
5200 }
5201
MirrorSwitchNotify(ScreenId screenId)5202 void ScreenSessionManager::MirrorSwitchNotify(ScreenId screenId)
5203 {
5204 auto mirrorScreen = GetScreenSession(screenId);
5205 if (mirrorScreen != nullptr) {
5206 mirrorScreen->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
5207 NotifyScreenChanged(mirrorScreen->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE);
5208 }
5209 }
5210
DoMakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,DMRect mainScreenRegion,ScreenId & screenGroupId)5211 DMError ScreenSessionManager::DoMakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
5212 DMRect mainScreenRegion, ScreenId& screenGroupId)
5213 {
5214 #ifdef WM_MULTI_SCREEN_ENABLE
5215 TLOGW(WmsLogTag::DMS, "enter!");
5216 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5217 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5218 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5219 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5220 }
5221 if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
5222 TLOGW(WmsLogTag::DMS, "disabled by edm!");
5223 return DMError::DM_ERROR_INVALID_PERMISSION;
5224 }
5225
5226 TLOGW(WmsLogTag::DMS, "mainScreenId :%{public}" PRIu64"", mainScreenId);
5227 auto allMirrorScreenIds = GetAllValidScreenIds(mirrorScreenIds);
5228 auto iter = std::find(allMirrorScreenIds.begin(), allMirrorScreenIds.end(), mainScreenId);
5229 if (iter != allMirrorScreenIds.end()) {
5230 allMirrorScreenIds.erase(iter);
5231 }
5232 auto mainScreen = GetScreenSession(mainScreenId);
5233 if (mainScreen == nullptr || allMirrorScreenIds.empty()) {
5234 TLOGE(WmsLogTag::DMS, "MakeMirror fail. mainScreen :%{public}" PRIu64", screens size:%{public}u",
5235 mainScreenId, static_cast<uint32_t>(allMirrorScreenIds.size()));
5236 return DMError::DM_ERROR_NULLPTR;
5237 }
5238 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeMirror start");
5239 for (ScreenId screenId : allMirrorScreenIds) {
5240 OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED);
5241 }
5242 DMError makeResult = MultiScreenManager::GetInstance().MirrorSwitch(mainScreenId,
5243 allMirrorScreenIds, mainScreenRegion, screenGroupId);
5244 if (makeResult != DMError::DM_OK) {
5245 TLOGE(WmsLogTag::DMS, "MakeMirror set mirror failed.");
5246 return makeResult;
5247 }
5248 for (ScreenId screenId : allMirrorScreenIds) {
5249 MirrorSwitchNotify(screenId);
5250 auto screenSession = GetScreenSession(screenId);
5251 if (screenSession != nullptr && mainScreen != nullptr) {
5252 screenSession->SetDisplayGroupId(mainScreen->GetDisplayGroupId());
5253 screenSession->SetMainDisplayIdOfGroup(mainScreen->GetMainDisplayIdOfGroup());
5254 }
5255 }
5256 RegisterCastObserver(allMirrorScreenIds);
5257 TLOGW(WmsLogTag::DMS, "make mirror notify scb end makeResult=%{public}d", makeResult);
5258 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeMirror end");
5259 return makeResult;
5260 #else
5261 return DMError::DM_OK;
5262 #endif
5263 }
5264
MakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,ScreenId & screenGroupId)5265 DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
5266 ScreenId& screenGroupId)
5267 {
5268 #ifdef FOLD_ABILITY_ENABLE
5269 if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
5270 DMRect mainScreenRegion = DMRect::NONE();
5271 foldScreenController_->SetMainScreenRegion(mainScreenRegion);
5272 return DoMakeMirror(mainScreenId, mirrorScreenIds, mainScreenRegion, screenGroupId);
5273 }
5274 #endif
5275 return DoMakeMirror(mainScreenId, mirrorScreenIds, DMRect::NONE(), screenGroupId);
5276 }
5277
MakeMirrorForRecord(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,ScreenId & screenGroupId)5278 DMError ScreenSessionManager::MakeMirrorForRecord(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
5279 ScreenId& screenGroupId)
5280 {
5281 #ifdef FOLD_ABILITY_ENABLE
5282 TLOGW(WmsLogTag::DMS, "start");
5283 ScreenId realScreenId = mainScreenId;
5284 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && mainScreenId == DISPLAY_ID_FAKE) {
5285 if (!SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
5286 TLOGE(WmsLogTag::DMS, "fake display is not exist!");
5287 return DMError::DM_ERROR_INVALID_PARAM;
5288 }
5289 realScreenId = 0;
5290 }
5291 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
5292 SuperFoldPolicy::GetInstance().IsNeedSetSnapshotRect(mainScreenId)) {
5293 DMRect mainScreenRect = SuperFoldPolicy::GetInstance().GetRecordRect(mainScreenId);
5294 return DoMakeMirror(realScreenId, mirrorScreenIds, mainScreenRect, screenGroupId);
5295 }
5296 if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
5297 DMRect mainScreenRegion = DMRect::NONE();
5298 foldScreenController_->SetMainScreenRegion(mainScreenRegion);
5299 return DoMakeMirror(mainScreenId, mirrorScreenIds, mainScreenRegion, screenGroupId);
5300 }
5301 #endif
5302 return DoMakeMirror(mainScreenId, mirrorScreenIds, DMRect::NONE(), screenGroupId);
5303 }
5304
5305
MakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenIds,DMRect mainScreenRegion,ScreenId & screenGroupId)5306 DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenIds,
5307 DMRect mainScreenRegion, ScreenId& screenGroupId)
5308 {
5309 return DoMakeMirror(mainScreenId, mirrorScreenIds, mainScreenRegion, screenGroupId);
5310 }
5311
RegisterCastObserver(std::vector<ScreenId> & mirrorScreenIds)5312 void ScreenSessionManager::RegisterCastObserver(std::vector<ScreenId>& mirrorScreenIds)
5313 {
5314 {
5315 std::lock_guard<std::mutex> lock(mirrorScreenIdsMutex_);
5316 mirrorScreenIds_ = mirrorScreenIds;
5317 }
5318 TLOGI(WmsLogTag::DMS, "Register Setting cast Observer");
5319 SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetCastFromSettingData(); };
5320 ScreenSettingHelper::RegisterSettingCastObserver(updateFunc);
5321 }
5322
SetCastFromSettingData()5323 void ScreenSessionManager::SetCastFromSettingData()
5324 {
5325 bool enable;
5326 bool ret = ScreenSettingHelper::GetSettingCast(enable);
5327 if (!ret) {
5328 TLOGW(WmsLogTag::DMS, "get setting cast failed, default enable");
5329 enable = true;
5330 } else {
5331 TLOGI(WmsLogTag::DMS, "get setting cast success, enable: %{public}u", enable);
5332 }
5333
5334 std::vector<ScreenId> mirrorScreenIdsCopy;
5335 {
5336 std::lock_guard<std::mutex> lock(mirrorScreenIdsMutex_);
5337 mirrorScreenIdsCopy = mirrorScreenIds_;
5338 }
5339 for (ScreenId screenId : mirrorScreenIdsCopy) {
5340 ScreenId rsScreenId;
5341 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
5342 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
5343 continue;
5344 }
5345 rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, enable);
5346 }
5347 }
5348
RegisterSettingRotationObserver()5349 void ScreenSessionManager::RegisterSettingRotationObserver()
5350 {
5351 TLOGI(WmsLogTag::DMS, "start");
5352 SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) {
5353 int32_t rotation = -1;
5354 int32_t screenId = -1;
5355 if (ScreenSettingHelper::GetSettingRotation(rotation) &&
5356 ScreenSettingHelper::GetSettingRotationScreenID(screenId)) {
5357 TLOGNI(WmsLogTag::DMS, "current dms setting rotation:%{public}d, screenId:%{public}d",
5358 rotation, screenId);
5359 } else {
5360 TLOGNI(WmsLogTag::DMS, "get current dms setting rotation and screenId failed");
5361 }
5362 };
5363 ScreenSettingHelper::RegisterSettingRotationObserver(updateFunc);
5364 }
5365
StopMirror(const std::vector<ScreenId> & mirrorScreenIds)5366 DMError ScreenSessionManager::StopMirror(const std::vector<ScreenId>& mirrorScreenIds)
5367 {
5368 if (!SessionPermission::IsSystemCalling()) {
5369 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5370 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5371 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5372 }
5373 auto allMirrorScreenIds = GetAllValidScreenIds(mirrorScreenIds);
5374 if (allMirrorScreenIds.empty()) {
5375 TLOGW(WmsLogTag::DMS, "done. screens' size:%{public}u",
5376 static_cast<uint32_t>(allMirrorScreenIds.size()));
5377 return DMError::DM_OK;
5378 }
5379
5380 DMError ret = StopScreens(allMirrorScreenIds, ScreenCombination::SCREEN_MIRROR);
5381 if (ret != DMError::DM_OK) {
5382 TLOGE(WmsLogTag::DMS, "failed.");
5383 return ret;
5384 }
5385 ScreenSettingHelper::UnregisterSettingCastObserver();
5386
5387 return DMError::DM_OK;
5388 }
5389
StopScreens(const std::vector<ScreenId> & screenIds,ScreenCombination stopCombination)5390 DMError ScreenSessionManager::StopScreens(const std::vector<ScreenId>& screenIds, ScreenCombination stopCombination)
5391 {
5392 for (ScreenId screenId : screenIds) {
5393 TLOGW(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64"", screenId);
5394 auto screen = GetScreenSession(screenId);
5395 if (screen == nullptr) {
5396 TLOGW(WmsLogTag::DMS, "screen:%{public}" PRIu64" is nullptr", screenId);
5397 continue;
5398 }
5399 sptr<ScreenSessionGroup> screenGroup = GetAbstractScreenGroup(screen->groupSmsId_);
5400 if (!screenGroup) {
5401 TLOGW(WmsLogTag::DMS, "groupDmsId:%{public}" PRIu64"is not in smsScreenGroupMap_",
5402 screen->groupSmsId_);
5403 continue;
5404 }
5405 if (screenGroup->combination_ != stopCombination) {
5406 TLOGW(WmsLogTag::DMS, "try to stop screen in another combination");
5407 continue;
5408 }
5409 if (screenGroup->combination_ == ScreenCombination::SCREEN_MIRROR &&
5410 screen->screenId_ == screenGroup->mirrorScreenId_) {
5411 TLOGW(WmsLogTag::DMS, "try to stop main mirror screen");
5412 continue;
5413 }
5414 bool res = RemoveChildFromGroup(screen, screenGroup);
5415 if (res) {
5416 NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
5417 }
5418 }
5419 return DMError::DM_OK;
5420 }
5421
GetVirtualScreenFlag(ScreenId screenId)5422 VirtualScreenFlag ScreenSessionManager::GetVirtualScreenFlag(ScreenId screenId)
5423 {
5424 if (!SessionPermission::IsSystemCalling()) {
5425 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5426 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5427 return VirtualScreenFlag::DEFAULT;
5428 }
5429 auto screen = GetScreenSession(screenId);
5430 if (screen == nullptr) {
5431 TLOGE(WmsLogTag::DMS, "screen session null");
5432 return VirtualScreenFlag::DEFAULT;
5433 }
5434 return screen->GetVirtualScreenFlag();
5435 }
5436
SetVirtualScreenFlag(ScreenId screenId,VirtualScreenFlag screenFlag)5437 DMError ScreenSessionManager::SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag)
5438 {
5439 if (!SessionPermission::IsSystemCalling()) {
5440 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5441 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5442 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5443 }
5444 if (screenFlag < VirtualScreenFlag::DEFAULT || screenFlag >= VirtualScreenFlag::MAX) {
5445 TLOGE(WmsLogTag::DMS, "range error");
5446 return DMError::DM_ERROR_INVALID_PARAM;
5447 }
5448 auto screen = GetScreenSession(screenId);
5449 if (screen == nullptr) {
5450 TLOGE(WmsLogTag::DMS, "screen session null");
5451 return DMError::DM_ERROR_INVALID_PARAM;
5452 }
5453 screen->SetVirtualScreenFlag(screenFlag);
5454 return DMError::DM_OK;
5455 }
5456
SetVirtualScreenRefreshRate(ScreenId screenId,uint32_t refreshInterval)5457 DMError ScreenSessionManager::SetVirtualScreenRefreshRate(ScreenId screenId, uint32_t refreshInterval)
5458 {
5459 if (!SessionPermission::IsSystemCalling()) {
5460 TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
5461 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5462 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5463 }
5464 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64", refreshInterval: %{public}u",
5465 screenId, refreshInterval);
5466 if (screenId == GetDefaultScreenId()) {
5467 TLOGE(WmsLogTag::DMS, "cannot set refresh rate of main screen id: %{public}" PRIu64, GetDefaultScreenId());
5468 return DMError::DM_ERROR_INVALID_PARAM;
5469 }
5470 if (refreshInterval == 0) {
5471 TLOGE(WmsLogTag::DMS, "refresh interval is 0.");
5472 return DMError::DM_ERROR_INVALID_PARAM;
5473 }
5474 auto screenSession = GetScreenSession(screenId);
5475 auto defaultScreenSession = GetDefaultScreenSession();
5476 if (screenSession == nullptr || defaultScreenSession == nullptr) {
5477 TLOGE(WmsLogTag::DMS, "screenSession is null.");
5478 return DMError::DM_ERROR_INVALID_PARAM;
5479 }
5480 ScreenId rsScreenId;
5481 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
5482 TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
5483 return DMError::DM_ERROR_INVALID_PARAM;
5484 }
5485 int32_t res = rsInterface_.SetScreenSkipFrameInterval(rsScreenId, refreshInterval);
5486 if (res != StatusCode::SUCCESS) {
5487 TLOGE(WmsLogTag::DMS, "rsInterface error: %{public}d", res);
5488 return DMError::DM_ERROR_INVALID_PARAM;
5489 }
5490 // when skipFrameInterval > 10 means the skipFrameInterval is the virtual screen refresh rate
5491 if (refreshInterval > IRREGULAR_REFRESH_RATE_SKIP_THRETHOLD) {
5492 screenSession->UpdateRefreshRate(refreshInterval);
5493 screenSession->SetSupportedRefreshRate({refreshInterval});
5494 } else {
5495 screenSession->UpdateRefreshRate(defaultScreenSession->GetRefreshRate() / refreshInterval);
5496 screenSession->SetSupportedRefreshRate({defaultScreenSession->GetRefreshRate() / refreshInterval});
5497 }
5498 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::UPDATE_REFRESHRATE);
5499 TLOGW(WmsLogTag::DMS, "refreshInterval is %{public}d", refreshInterval);
5500 return DMError::DM_OK;
5501 }
5502
VirtualScreenUniqueSwitch(const std::vector<ScreenId> & screenIds)5503 DMError ScreenSessionManager::VirtualScreenUniqueSwitch(const std::vector<ScreenId>& screenIds)
5504 {
5505 #ifdef WM_MULTI_SCREEN_ENABLE
5506 TLOGW(WmsLogTag::DMS, "enter");
5507 auto defaultScreen = GetDefaultScreenSession();
5508 if (!defaultScreen) {
5509 TLOGE(WmsLogTag::DMS, "default screen is nullptr");
5510 return DMError::DM_ERROR_NULLPTR;
5511 }
5512 defaultScreen->groupSmsId_ = 1;
5513 {
5514 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5515 auto iter = smsScreenGroupMap_.find(defaultScreen->groupSmsId_);
5516 if (iter != smsScreenGroupMap_.end()) {
5517 smsScreenGroupMap_.erase(iter);
5518 }
5519 }
5520 DMError uniqueSwitchRet = MultiScreenManager::GetInstance().VirtualScreenUniqueSwitch(defaultScreen, screenIds);
5521 TLOGW(WmsLogTag::DMS, "result: %{public}d", uniqueSwitchRet);
5522 return uniqueSwitchRet;
5523 #else
5524 return DMError::DM_OK;
5525 #endif
5526 }
5527
MakeUniqueScreen(const std::vector<ScreenId> & screenIds,std::vector<DisplayId> & displayIds)5528 DMError ScreenSessionManager::MakeUniqueScreen(const std::vector<ScreenId>& screenIds,
5529 std::vector<DisplayId>& displayIds)
5530 {
5531 #ifdef WM_MULTI_SCREEN_ENABLE
5532 bool isCallingByThirdParty = Permission::CheckCallingPermission(ACCESS_VIRTUAL_SCREEN_PERMISSION);
5533 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd() && !isCallingByThirdParty) {
5534 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5535 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5536 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5537 }
5538 TLOGW(WmsLogTag::DMS, "enter!");
5539 if (screenIds.empty()) {
5540 TLOGE(WmsLogTag::DMS, "screen is empty");
5541 return DMError::DM_ERROR_INVALID_PARAM;
5542 }
5543 std::vector<ScreenId> validScreenIds;
5544 for (auto screenId : screenIds) {
5545 if (!IsDefaultMirrorMode(screenId)) {
5546 continue;
5547 }
5548 validScreenIds.emplace_back(screenId);
5549 }
5550 const auto& allUniqueScreenIds = GetAllValidScreenIds(validScreenIds);
5551 if (allUniqueScreenIds.empty()) {
5552 TLOGE(WmsLogTag::DMS, "screenIds is invalid.");
5553 return DMError::DM_ERROR_NULLPTR;
5554 }
5555 ScreenId uniqueScreenId = validScreenIds[0];
5556 auto uniqueScreen = GetScreenSession(uniqueScreenId);
5557 if (uniqueScreen != nullptr) {
5558 if (uniqueScreen->GetSourceMode() == ScreenSourceMode::SCREEN_UNIQUE) {
5559 TLOGW(WmsLogTag::DMS, "make unique ignore");
5560 return DMError::DM_OK;
5561 }
5562 if (isCallingByThirdParty) {
5563 uniqueScreen->SetInnerName("CustomScbScreen");
5564 }
5565 return MultiScreenManager::GetInstance().UniqueSwitch(allUniqueScreenIds, displayIds);
5566 }
5567 return DoMakeUniqueScreenOld(allUniqueScreenIds, displayIds, isCallingByThirdParty);
5568 #else
5569 return DMError::DM_ERROR_DEVICE_NOT_SUPPORT;
5570 #endif
5571 }
5572
DoMakeUniqueScreenOld(const std::vector<ScreenId> & allUniqueScreenIds,std::vector<DisplayId> & displayIds,bool isCallingByThirdParty)5573 DMError ScreenSessionManager::DoMakeUniqueScreenOld(const std::vector<ScreenId>& allUniqueScreenIds,
5574 std::vector<DisplayId>& displayIds, bool isCallingByThirdParty)
5575 {
5576 #ifdef WM_MULTI_SCREEN_ENABLE
5577 std::unordered_set<std::shared_ptr<RSUIContext>> rsUIContexts;
5578 for (auto screenId : allUniqueScreenIds) {
5579 ScreenId rsScreenId = SCREEN_ID_INVALID;
5580 bool res = ConvertScreenIdToRsScreenId(screenId, rsScreenId);
5581 TLOGI(WmsLogTag::DMS, "unique screenId: %{public}" PRIu64" rsScreenId: %{public}" PRIu64,
5582 screenId, rsScreenId);
5583 if (!res) {
5584 TLOGE(WmsLogTag::DMS, "convert screenId to rsScreenId failed");
5585 continue;
5586 }
5587 auto screenSession = GetScreenSession(screenId);
5588 if (!screenSession) {
5589 TLOGE(WmsLogTag::DMS, "screen session is nullptr");
5590 continue;
5591 }
5592 displayIds.emplace_back(static_cast<uint64_t>(screenId));
5593 Rosen::RSDisplayNodeConfig rsConfig;
5594 rsConfig.screenId = rsScreenId;
5595 screenSession->CreateDisplayNode(rsConfig);
5596 screenSession->SetDisplayNodeScreenId(rsScreenId);
5597 if (isCallingByThirdParty) {
5598 screenSession->SetInnerName("CustomScbScreen");
5599 }
5600 // notify scb to build Screen widget
5601 OnVirtualScreenChange(screenId, ScreenEvent::CONNECTED);
5602 rsUIContexts.insert(screenSession->GetRSUIContext());
5603 }
5604 TLOGD(WmsLogTag::DMS, "flush data");
5605 RSTransactionAdapter::FlushImplicitTransaction(rsUIContexts);
5606 #endif
5607 return DMError::DM_OK;
5608 }
5609
NotifyScreenConnectCompletion(ScreenId screenId)5610 void ScreenSessionManager::NotifyScreenConnectCompletion(ScreenId screenId)
5611 {
5612 #ifdef WM_MULTI_SCREEN_ENABLE
5613 TLOGI(WmsLogTag::DMS, "ENTER, screenId:%{public}" PRIu64, screenId);
5614 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5615 TLOGE(WmsLogTag::DMS, "permission denied!");
5616 return;
5617 }
5618 MultiScreenManager::GetInstance().NotifyScreenConnectCompletion(screenId);
5619 #endif
5620 }
5621
MakeExpand(std::vector<ScreenId> screenId,std::vector<Point> startPoint,ScreenId & screenGroupId)5622 DMError ScreenSessionManager::MakeExpand(std::vector<ScreenId> screenId,
5623 std::vector<Point> startPoint,
5624 ScreenId& screenGroupId)
5625 {
5626 TLOGI(WmsLogTag::DMS, "enter!");
5627 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5628 TLOGE(WmsLogTag::DMS, "permission denied! pid: %{public}d", IPCSkeleton::GetCallingPid());
5629 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5630 }
5631 if (screenId.empty() || startPoint.empty() || screenId.size() != startPoint.size()) {
5632 TLOGE(WmsLogTag::DMS, "create expand fail, screenId size:%{public}ud,startPoint size:%{public}ud",
5633 static_cast<uint32_t>(screenId.size()), static_cast<uint32_t>(startPoint.size()));
5634 return DMError::DM_ERROR_INVALID_PARAM;
5635 }
5636 std::map<ScreenId, Point> pointsMap;
5637 uint32_t size = screenId.size();
5638 for (uint32_t i = 0; i < size; i++) {
5639 if (pointsMap.find(screenId[i]) != pointsMap.end()) {
5640 continue;
5641 }
5642 pointsMap[screenId[i]] = startPoint[i];
5643 }
5644 ScreenId defaultScreenId = GetDefaultScreenId();
5645 auto allExpandScreenIds = GetAllValidScreenIds(screenId);
5646 auto iter = std::find(allExpandScreenIds.begin(), allExpandScreenIds.end(), defaultScreenId);
5647 if (iter != allExpandScreenIds.end()) {
5648 allExpandScreenIds.erase(iter);
5649 }
5650 if (allExpandScreenIds.empty()) {
5651 TLOGE(WmsLogTag::DMS, "allExpandScreenIds is empty. make expand failed.");
5652 return DMError::DM_ERROR_NULLPTR;
5653 }
5654 std::shared_ptr<RSDisplayNode> rsDisplayNode;
5655 std::vector<Point> points;
5656 for (uint32_t i = 0; i < allExpandScreenIds.size(); i++) {
5657 ScreenId expandScreenId = allExpandScreenIds[i];
5658 if (pointsMap.find(expandScreenId) == pointsMap.end()) {
5659 continue;
5660 }
5661 points.emplace_back(pointsMap[expandScreenId]);
5662 rsDisplayNode = GetRSDisplayNodeByScreenId(expandScreenId);
5663 if (rsDisplayNode != nullptr) {
5664 SetScreenOffset(expandScreenId, pointsMap[expandScreenId].posX_, pointsMap[expandScreenId].posY_);
5665 }
5666 }
5667 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:MakeExpand");
5668 if (!OnMakeExpand(allExpandScreenIds, points)) {
5669 return DMError::DM_ERROR_NULLPTR;
5670 }
5671 auto screen = GetScreenSession(allExpandScreenIds[0]);
5672 if (screen == nullptr || GetAbstractScreenGroup(screen->groupSmsId_) == nullptr) {
5673 return DMError::DM_ERROR_NULLPTR;
5674 }
5675 screenGroupId = screen->groupSmsId_;
5676 return DMError::DM_OK;
5677 }
5678
OnMakeExpand(std::vector<ScreenId> screenId,std::vector<Point> startPoint)5679 bool ScreenSessionManager::OnMakeExpand(std::vector<ScreenId> screenId, std::vector<Point> startPoint)
5680 {
5681 ScreenId defaultScreenId = GetDefaultScreenId();
5682 TLOGI(WmsLogTag::DMS, "defaultScreenId:%{public}" PRIu64"", defaultScreenId);
5683 auto defaultScreen = GetScreenSession(defaultScreenId);
5684 if (defaultScreen == nullptr) {
5685 TLOGI(WmsLogTag::DMS, "failed.");
5686 return false;
5687 }
5688 auto group = GetAbstractScreenGroup(defaultScreen->groupSmsId_);
5689 if (group == nullptr) {
5690 group = AddToGroupLocked(defaultScreen);
5691 if (group == nullptr) {
5692 TLOGE(WmsLogTag::DMS, "group is nullptr");
5693 return false;
5694 }
5695 NotifyScreenGroupChanged(defaultScreen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
5696 }
5697 bool filterExpandScreen = group->combination_ == ScreenCombination::SCREEN_EXPAND;
5698 ChangeScreenGroup(group, screenId, startPoint, filterExpandScreen, ScreenCombination::SCREEN_EXPAND);
5699 TLOGI(WmsLogTag::DMS, "success");
5700 return true;
5701 }
5702
StopExpand(const std::vector<ScreenId> & expandScreenIds)5703 DMError ScreenSessionManager::StopExpand(const std::vector<ScreenId>& expandScreenIds)
5704 {
5705 if (!SessionPermission::IsSystemCalling()) {
5706 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
5707 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
5708 return DMError::DM_ERROR_NOT_SYSTEM_APP;
5709 }
5710 auto allExpandScreenIds = GetAllValidScreenIds(expandScreenIds);
5711 if (allExpandScreenIds.empty()) {
5712 TLOGI(WmsLogTag::DMS, "done. screens' size:%{public}u",
5713 static_cast<uint32_t>(allExpandScreenIds.size()));
5714 return DMError::DM_OK;
5715 }
5716
5717 DMError ret = StopScreens(allExpandScreenIds, ScreenCombination::SCREEN_EXPAND);
5718 if (ret != DMError::DM_OK) {
5719 TLOGE(WmsLogTag::DMS, "stop expand failed.");
5720 return ret;
5721 }
5722
5723 return DMError::DM_OK;
5724 }
5725
ConvertToRsScreenId(ScreenId smsScreenId,ScreenId & rsScreenId) const5726 bool ScreenSessionManager::ScreenIdManager::ConvertToRsScreenId(ScreenId smsScreenId, ScreenId& rsScreenId) const
5727 {
5728 std::shared_lock lock(screenIdMapMutex_);
5729 auto iter = sms2RsScreenIdMap_.find(smsScreenId);
5730 if (iter == sms2RsScreenIdMap_.end()) {
5731 return false;
5732 }
5733 rsScreenId = iter->second;
5734 return true;
5735 }
5736
ConvertToRsScreenId(ScreenId screenId) const5737 ScreenId ScreenSessionManager::ScreenIdManager::ConvertToRsScreenId(ScreenId screenId) const
5738 {
5739 ScreenId rsScreenId = SCREEN_ID_INVALID;
5740 ConvertToRsScreenId(screenId, rsScreenId);
5741 return rsScreenId;
5742 }
5743
ConvertToSmsScreenId(ScreenId rsScreenId) const5744 ScreenId ScreenSessionManager::ScreenIdManager::ConvertToSmsScreenId(ScreenId rsScreenId) const
5745 {
5746 ScreenId smsScreenId = SCREEN_ID_INVALID;
5747 ConvertToSmsScreenId(rsScreenId, smsScreenId);
5748 return smsScreenId;
5749 }
5750
ConvertToSmsScreenId(ScreenId rsScreenId,ScreenId & smsScreenId) const5751 bool ScreenSessionManager::ScreenIdManager::ConvertToSmsScreenId(ScreenId rsScreenId, ScreenId& smsScreenId) const
5752 {
5753 std::shared_lock lock(screenIdMapMutex_);
5754 auto iter = rs2SmsScreenIdMap_.find(rsScreenId);
5755 if (iter == rs2SmsScreenIdMap_.end()) {
5756 return false;
5757 }
5758 smsScreenId = iter->second;
5759 return true;
5760 }
5761
CreateAndGetNewScreenId(ScreenId rsScreenId)5762 ScreenId ScreenSessionManager::ScreenIdManager::CreateAndGetNewScreenId(ScreenId rsScreenId)
5763 {
5764 std::unique_lock lock(screenIdMapMutex_);
5765 ScreenId smsScreenId = smsScreenCount_++;
5766 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64"", smsScreenId);
5767 if (sms2RsScreenIdMap_.find(smsScreenId) != sms2RsScreenIdMap_.end()) {
5768 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64" exit", smsScreenId);
5769 }
5770 sms2RsScreenIdMap_[smsScreenId] = rsScreenId;
5771 if (rsScreenId == SCREEN_ID_INVALID) {
5772 return smsScreenId;
5773 }
5774 if (rs2SmsScreenIdMap_.find(rsScreenId) != rs2SmsScreenIdMap_.end()) {
5775 TLOGW(WmsLogTag::DMS, "rsScreenId: %{public}" PRIu64" exit", rsScreenId);
5776 }
5777 rs2SmsScreenIdMap_[rsScreenId] = smsScreenId;
5778 return smsScreenId;
5779 }
5780
UpdateScreenId(ScreenId rsScreenId,ScreenId smsScreenId)5781 void ScreenSessionManager::ScreenIdManager::UpdateScreenId(ScreenId rsScreenId, ScreenId smsScreenId)
5782 {
5783 std::unique_lock lock(screenIdMapMutex_);
5784 rs2SmsScreenIdMap_[rsScreenId] = smsScreenId;
5785 sms2RsScreenIdMap_[smsScreenId] = rsScreenId;
5786 }
5787
DeleteScreenId(ScreenId smsScreenId)5788 bool ScreenSessionManager::ScreenIdManager::DeleteScreenId(ScreenId smsScreenId)
5789 {
5790 std::unique_lock lock(screenIdMapMutex_);
5791 auto iter = sms2RsScreenIdMap_.find(smsScreenId);
5792 if (iter == sms2RsScreenIdMap_.end()) {
5793 return false;
5794 }
5795 ScreenId rsScreenId = iter->second;
5796 sms2RsScreenIdMap_.erase(smsScreenId);
5797 rs2SmsScreenIdMap_.erase(rsScreenId);
5798 return true;
5799 }
5800
HasRsScreenId(ScreenId smsScreenId) const5801 bool ScreenSessionManager::ScreenIdManager::HasRsScreenId(ScreenId smsScreenId) const
5802 {
5803 std::shared_lock lock(screenIdMapMutex_);
5804 return rs2SmsScreenIdMap_.find(smsScreenId) != rs2SmsScreenIdMap_.end();
5805 }
5806
InitVirtualScreen(ScreenId smsScreenId,ScreenId rsId,VirtualScreenOption option)5807 sptr<ScreenSession> ScreenSessionManager::InitVirtualScreen(ScreenId smsScreenId, ScreenId rsId,
5808 VirtualScreenOption option)
5809 {
5810 TLOGI(WmsLogTag::DMS, "Enter");
5811 ScreenSessionConfig config = {
5812 .screenId = smsScreenId,
5813 .rsId = rsId,
5814 .defaultScreenId = GetDefaultScreenId(),
5815 .name = option.name_,
5816 };
5817 sptr<ScreenSession> screenSession =
5818 new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
5819 sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
5820 if (screenSession == nullptr || info == nullptr) {
5821 TLOGI(WmsLogTag::DMS, "new screenSession or info failed");
5822 screenIdManager_.DeleteScreenId(smsScreenId);
5823 rsInterface_.RemoveVirtualScreen(rsId);
5824 return nullptr;
5825 }
5826 info->width_ = option.width_;
5827 info->height_ = option.height_;
5828 auto defaultScreen = GetScreenSession(GetDefaultScreenId());
5829 if (defaultScreen != nullptr) {
5830 info->refreshRate_ = defaultScreen->GetRefreshRate();
5831 screenSession->UpdateRefreshRate(info->refreshRate_);
5832 std::vector<uint32_t> virtualRefreshRateVec = {info->refreshRate_};
5833 screenSession->SetSupportedRefreshRate(std::move(virtualRefreshRateVec));
5834 }
5835 screenSession->modes_.emplace_back(info);
5836 screenSession->activeIdx_ = 0;
5837 screenSession->SetScreenType(ScreenType::VIRTUAL);
5838 screenSession->SetVirtualPixelRatio(option.density_);
5839 screenSession->SetIsPcUse(g_isPcDevice ? true : false);
5840 screenSession->SetDisplayBoundary(RectF(0, 0, option.width_, option.height_), 0);
5841 screenSession->RegisterScreenChangeListener(this);
5842 screenSession->SetValidWidth(option.width_);
5843 screenSession->SetValidHeight(option.height_);
5844 screenSession->SetRealWidth(option.width_);
5845 screenSession->SetRealHeight(option.height_);
5846 screenSession->SetScreenAreaWidth(option.width_);
5847 screenSession->SetScreenAreaHeight(option.height_);
5848 return screenSession;
5849 }
5850
InitAbstractScreenModesInfo(sptr<ScreenSession> & screenSession)5851 bool ScreenSessionManager::InitAbstractScreenModesInfo(sptr<ScreenSession>& screenSession)
5852 {
5853 TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenSupportedModes");
5854 std::vector<RSScreenModeInfo> allModes = rsInterface_.GetScreenSupportedModes(
5855 screenIdManager_.ConvertToRsScreenId(screenSession->screenId_));
5856 if (allModes.size() == 0) {
5857 TLOGE(WmsLogTag::DMS, "allModes.size() == 0, screenId=%{public}" PRIu64"", screenSession->rsId_);
5858 return false;
5859 }
5860 for (const RSScreenModeInfo& rsScreenModeInfo : allModes) {
5861 sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
5862 if (info == nullptr) {
5863 TLOGE(WmsLogTag::DMS, "create SupportedScreenModes failed");
5864 return false;
5865 }
5866 info->id_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenModeId());
5867 info->width_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenWidth());
5868 info->height_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenHeight());
5869 info->refreshRate_ = rsScreenModeInfo.GetScreenRefreshRate();
5870 screenSession->modes_.push_back(info);
5871 TLOGW(WmsLogTag::DMS, "fill screen idx:%{public}d w/h:%{public}d/%{public}d",
5872 rsScreenModeInfo.GetScreenModeId(), info->width_, info->height_);
5873 }
5874 TLOGW(WmsLogTag::DMS, "Call rsInterface_ GetScreenActiveMode");
5875 int32_t activeModeId = rsInterface_.GetScreenActiveMode(screenSession->rsId_).GetScreenModeId();
5876 TLOGW(WmsLogTag::DMS, "fill screen activeModeId:%{public}d", activeModeId);
5877 if (static_cast<std::size_t>(activeModeId) >= allModes.size()) {
5878 TLOGE(WmsLogTag::DMS, "activeModeId exceed, screenId=%{public}" PRIu64", activeModeId:%{public}d/%{public}ud",
5879 screenSession->rsId_, activeModeId, static_cast<uint32_t>(allModes.size()));
5880 return false;
5881 }
5882 screenSession->activeIdx_ = activeModeId;
5883 return true;
5884 }
5885
InitAndGetScreen(ScreenId rsScreenId)5886 sptr<ScreenSession> ScreenSessionManager::InitAndGetScreen(ScreenId rsScreenId)
5887 {
5888 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5889 ScreenId smsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsScreenId);
5890 RSScreenCapability screenCapability = rsInterface_.GetScreenCapability(rsScreenId);
5891 TLOGI(WmsLogTag::DMS, "Screen name is %{public}s, phyWidth is %{public}u, phyHeight is %{public}u",
5892 screenCapability.GetName().c_str(), screenCapability.GetPhyWidth(), screenCapability.GetPhyHeight());
5893 ScreenSessionConfig config = {
5894 .screenId = smsScreenId,
5895 .rsId = rsScreenId,
5896 .defaultScreenId = GetDefaultScreenId(),
5897 .name = screenCapability.GetName(),
5898 };
5899 sptr<ScreenSession> screenSession =
5900 new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_FOR_VIRTUAL);
5901 if (screenSession == nullptr) {
5902 TLOGE(WmsLogTag::DMS, "screenSession == nullptr.");
5903 screenIdManager_.DeleteScreenId(smsScreenId);
5904 return nullptr;
5905 }
5906 if (!InitAbstractScreenModesInfo(screenSession)) {
5907 screenIdManager_.DeleteScreenId(smsScreenId);
5908 TLOGE(WmsLogTag::DMS, "failed.");
5909 return nullptr;
5910 }
5911 TLOGI(WmsLogTag::DMS, "screenSessionMap_ add screenId=%{public}" PRIu64"", smsScreenId);
5912 screenSessionMap_.insert(std::make_pair(smsScreenId, screenSession));
5913 return screenSession;
5914 }
5915
IsExtendMode()5916 bool ScreenSessionManager::IsExtendMode()
5917 {
5918 std::vector<ScreenId> mainVector;
5919 std::vector<ScreenId> extendVector;
5920 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5921 for (const auto& pair : screenSessionMap_) {
5922 sptr<ScreenSession> session = pair.second;
5923 if (!session) {
5924 TLOGE(WmsLogTag::DMS, "screenId=%{public}" PRIu64", session is null", pair.first);
5925 continue;
5926 }
5927 if (session->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
5928 extendVector.push_back(session->GetScreenId());
5929 }
5930 if (session->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
5931 mainVector.push_back(session->GetScreenId());
5932 }
5933 }
5934 std::ostringstream oss;
5935 oss << "main screenId:";
5936 for (const auto& screenId : mainVector) {
5937 oss << static_cast<uint64_t>(screenId);
5938 }
5939 oss << ", extend screenId:";
5940 for (const auto& screenId : extendVector) {
5941 oss << static_cast<uint64_t>(screenId);
5942 }
5943 oss << std::endl;
5944 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
5945 return mainVector.size() > 0 && extendVector.size() > 0;
5946 }
5947
AddToGroupLocked(sptr<ScreenSession> newScreen,bool isUnique)5948 sptr<ScreenSessionGroup> ScreenSessionManager::AddToGroupLocked(sptr<ScreenSession> newScreen, bool isUnique)
5949 {
5950 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5951 sptr<ScreenSessionGroup> res;
5952 if (smsScreenGroupMap_.empty()) {
5953 TLOGI(WmsLogTag::DMS, "connect the first screen");
5954 res = AddAsFirstScreenLocked(newScreen, isUnique);
5955 } else {
5956 res = AddAsSuccedentScreenLocked(newScreen);
5957 }
5958 return res;
5959 }
5960
AddAsFirstScreenLocked(sptr<ScreenSession> newScreen,bool isUnique)5961 sptr<ScreenSessionGroup> ScreenSessionManager::AddAsFirstScreenLocked(sptr<ScreenSession> newScreen, bool isUnique)
5962 {
5963 ScreenId smsGroupScreenId(1);
5964 std::ostringstream buffer;
5965 buffer << "ScreenGroup_" << smsGroupScreenId;
5966 std::string name = buffer.str();
5967 // default ScreenCombination is mirror
5968 isExpandCombination_ = system::GetParameter("persist.display.expand.enabled", "0") == "1";
5969 sptr<ScreenSessionGroup> screenGroup;
5970 if (isExpandCombination_) {
5971 screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
5972 SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_EXPAND);
5973 } else if (isUnique) {
5974 screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
5975 SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_UNIQUE);
5976 } else {
5977 screenGroup = new(std::nothrow) ScreenSessionGroup(smsGroupScreenId,
5978 SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_MIRROR);
5979 }
5980 if (screenGroup == nullptr) {
5981 TLOGE(WmsLogTag::DMS, "new ScreenSessionGroup failed");
5982 screenIdManager_.DeleteScreenId(smsGroupScreenId);
5983 return nullptr;
5984 }
5985 screenGroup->groupSmsId_ = 1;
5986 Point point;
5987 if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none") {
5988 if (IsExtendMode()) {
5989 point = {newScreen->GetScreenProperty().GetStartX(), newScreen->GetScreenProperty().GetStartY()};
5990 }
5991 }
5992 if (!screenGroup->AddChild(newScreen, point, GetScreenSession(GetDefaultScreenId()), g_isPcDevice)) {
5993 TLOGE(WmsLogTag::DMS, "fail to add screen to group. screen=%{public}" PRIu64"", newScreen->screenId_);
5994 screenIdManager_.DeleteScreenId(smsGroupScreenId);
5995 return nullptr;
5996 }
5997 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
5998 auto iter = smsScreenGroupMap_.find(smsGroupScreenId);
5999 if (iter != smsScreenGroupMap_.end()) {
6000 TLOGE(WmsLogTag::DMS, "group screen existed. id=%{public}" PRIu64"", smsGroupScreenId);
6001 smsScreenGroupMap_.erase(iter);
6002 }
6003 smsScreenGroupMap_.insert(std::make_pair(smsGroupScreenId, screenGroup));
6004 screenGroup->mirrorScreenId_ = newScreen->screenId_;
6005 TLOGI(WmsLogTag::DMS, "connect new group screen, screenId: %{public}" PRIu64", screenGroupId: %{public}" PRIu64", "
6006 "combination:%{public}u", newScreen->screenId_, smsGroupScreenId,
6007 newScreen->GetScreenProperty().GetScreenType());
6008 return screenGroup;
6009 }
6010
AddAsSuccedentScreenLocked(sptr<ScreenSession> newScreen)6011 sptr<ScreenSessionGroup> ScreenSessionManager::AddAsSuccedentScreenLocked(sptr<ScreenSession> newScreen)
6012 {
6013 ScreenId defaultScreenId = GetDefaultScreenId();
6014 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6015 auto iter = screenSessionMap_.find(defaultScreenId);
6016 if (iter == screenSessionMap_.end()) {
6017 TLOGE(WmsLogTag::DMS, "defaultScreenId:%{public}" PRIu64" is not in screenSessionMap_.",
6018 defaultScreenId);
6019 return nullptr;
6020 }
6021 auto screen = iter->second;
6022 auto screenGroupIter = smsScreenGroupMap_.find(screen->groupSmsId_);
6023 if (screenGroupIter == smsScreenGroupMap_.end()) {
6024 TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64" is not in smsScreenGroupMap_.",
6025 screen->groupSmsId_);
6026 return nullptr;
6027 }
6028 auto screenGroup = screenGroupIter->second;
6029 Point point;
6030 if (screenGroup->combination_ == ScreenCombination::SCREEN_EXPAND) {
6031 point = {screen->GetActiveScreenMode()->width_, 0};
6032 }
6033 screenGroup->AddChild(newScreen, point, screen);
6034 return screenGroup;
6035 }
6036
RemoveFromGroupLocked(sptr<ScreenSession> screen)6037 sptr<ScreenSessionGroup> ScreenSessionManager::RemoveFromGroupLocked(sptr<ScreenSession> screen)
6038 {
6039 TLOGI(WmsLogTag::DMS, "start");
6040 auto groupSmsId = screen->groupSmsId_;
6041 sptr<ScreenSessionGroup> screenGroup = GetAbstractScreenGroup(groupSmsId);
6042 if (!screenGroup) {
6043 TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64"is not in smsScreenGroupMap_.",
6044 groupSmsId);
6045 return nullptr;
6046 }
6047 if (!RemoveChildFromGroup(screen, screenGroup)) {
6048 return nullptr;
6049 }
6050 return screenGroup;
6051 }
6052
RemoveChildFromGroup(sptr<ScreenSession> screen,sptr<ScreenSessionGroup> screenGroup)6053 bool ScreenSessionManager::RemoveChildFromGroup(sptr<ScreenSession> screen, sptr<ScreenSessionGroup> screenGroup)
6054 {
6055 auto rsUIContext = screen ? screen->GetRSUIContext() : nullptr;
6056 bool res = screenGroup->RemoveChild(screen);
6057 RSTransactionAdapter::FlushImplicitTransaction(rsUIContext);
6058 TLOGI(WmsLogTag::DMS, "remove child and call flush.");
6059 if (!res) {
6060 TLOGE(WmsLogTag::DMS, "remove screen:%{public}" PRIu64" failed from screenGroup:%{public}" PRIu64".",
6061 screen->screenId_, screen->groupSmsId_);
6062 return false;
6063 }
6064 if (screenGroup->GetChildCount() == 0) {
6065 // Group removed, need to do something.
6066 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6067 smsScreenGroupMap_.erase(screenGroup->screenId_);
6068 screenSessionMap_.erase(screenGroup->screenId_);
6069 TLOGE(WmsLogTag::DMS, "screenSessionMap_ remove screen:%{public}" PRIu64, screenGroup->screenId_);
6070 }
6071 return true;
6072 }
6073
SetMirror(ScreenId screenId,std::vector<ScreenId> screens,DMRect mainScreenRegion)6074 DMError ScreenSessionManager::SetMirror(ScreenId screenId, std::vector<ScreenId> screens, DMRect mainScreenRegion)
6075 {
6076 TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64"", screenId);
6077 sptr<ScreenSession> screen = GetScreenSession(screenId);
6078 if (screen == nullptr || screen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
6079 TLOGE(WmsLogTag::DMS, "screen is nullptr, or screenCommbination is mirror.");
6080 return DMError::DM_ERROR_NULLPTR;
6081 }
6082 screen->groupSmsId_ = 1;
6083 auto group = GetAbstractScreenGroup(screen->groupSmsId_);
6084 if (group == nullptr) {
6085 group = AddToGroupLocked(screen);
6086 if (group == nullptr) {
6087 TLOGE(WmsLogTag::DMS, "group is nullptr");
6088 return DMError::DM_ERROR_NULLPTR;
6089 }
6090 NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
6091 }
6092 Point point;
6093 std::vector<Point> startPoints;
6094 startPoints.insert(startPoints.begin(), screens.size(), point);
6095 bool filterMirroredScreen =
6096 group->combination_ == ScreenCombination::SCREEN_MIRROR && group->mirrorScreenId_ == screen->screenId_;
6097 group->mirrorScreenId_ = screen->screenId_;
6098 ChangeScreenGroup(group, screens, startPoints, filterMirroredScreen, ScreenCombination::SCREEN_MIRROR,
6099 mainScreenRegion);
6100 TLOGI(WmsLogTag::DMS, "success");
6101 return DMError::DM_OK;
6102 }
6103
GetAbstractScreenGroup(ScreenId smsScreenId)6104 sptr<ScreenSessionGroup> ScreenSessionManager::GetAbstractScreenGroup(ScreenId smsScreenId)
6105 {
6106 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6107 auto iter = smsScreenGroupMap_.find(smsScreenId);
6108 if (iter == smsScreenGroupMap_.end()) {
6109 TLOGE(WmsLogTag::DMS, "did not find screen:%{public}" PRIu64"", smsScreenId);
6110 return nullptr;
6111 }
6112 return iter->second;
6113 }
6114
CheckScreenInScreenGroup(sptr<ScreenSession> screen) const6115 bool ScreenSessionManager::CheckScreenInScreenGroup(sptr<ScreenSession> screen) const
6116 {
6117 if (screen == nullptr) {
6118 TLOGE(WmsLogTag::DMS, "screen is nullptr");
6119 return false;
6120 }
6121 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6122 auto groupSmsId = screen->groupSmsId_;
6123 auto iter = smsScreenGroupMap_.find(groupSmsId);
6124 if (iter == smsScreenGroupMap_.end()) {
6125 TLOGE(WmsLogTag::DMS, "groupSmsId:%{public}" PRIu64"is not in smsScreenGroupMap_.", groupSmsId);
6126 return false;
6127 }
6128 sptr<ScreenSessionGroup> screenGroup = iter->second;
6129 return screenGroup->HasChild(screen->screenId_);
6130 }
6131
ChangeScreenGroup(sptr<ScreenSessionGroup> group,const std::vector<ScreenId> & screens,const std::vector<Point> & startPoints,bool filterScreen,ScreenCombination combination,DMRect mainScreenRegion)6132 void ScreenSessionManager::ChangeScreenGroup(sptr<ScreenSessionGroup> group, const std::vector<ScreenId>& screens,
6133 const std::vector<Point>& startPoints, bool filterScreen, ScreenCombination combination, DMRect mainScreenRegion)
6134 {
6135 std::map<ScreenId, bool> removeChildResMap;
6136 std::vector<ScreenId> addScreens;
6137 std::vector<Point> addChildPos;
6138 for (uint64_t i = 0; i != screens.size(); i++) {
6139 ScreenId screenId = screens[i];
6140 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64"", screenId);
6141 auto screen = GetScreenSession(screenId);
6142 if (screen == nullptr) {
6143 TLOGE(WmsLogTag::DMS, "screen:%{public}" PRIu64" is nullptr", screenId);
6144 continue;
6145 }
6146 TLOGI(WmsLogTag::DMS, "Screen->groupSmsId_: %{public}" PRIu64"", screen->groupSmsId_);
6147 screen->groupSmsId_ = 1;
6148 if (!HasSameScreenCastInfo(screen->GetScreenId(), group->mirrorScreenId_, combination)) {
6149 TLOGI(WmsLogTag::DMS, "has not same cast info");
6150 filterScreen = false;
6151 }
6152 if (filterScreen && screen->groupSmsId_ == group->screenId_ && group->HasChild(screen->screenId_)) {
6153 // screen already in group
6154 if (combination != ScreenCombination::SCREEN_MIRROR ||
6155 (screen->GetMirrorScreenRegion().second == mainScreenRegion &&
6156 screen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR)) {
6157 continue;
6158 }
6159 // mirror mode and mirror area change
6160 TLOGI(WmsLogTag::DMS, "Screen: %{public}" PRIu64
6161 ", apply new region, x:%{public}d y:%{public}d w:%{public}u h:%{public}u", screenId,
6162 mainScreenRegion.posX_, mainScreenRegion.posY_, mainScreenRegion.width_, mainScreenRegion.height_);
6163 }
6164 if (CheckScreenInScreenGroup(screen)) {
6165 NotifyDisplayDestroy(screenId);
6166 }
6167 auto originGroup = RemoveFromGroupLocked(screen);
6168 addChildPos.emplace_back(startPoints[i]);
6169 removeChildResMap[screenId] = originGroup != nullptr;
6170 addScreens.emplace_back(screenId);
6171 if (combination == ScreenCombination::SCREEN_MIRROR) {
6172 ChangeMirrorScreenConfig(group, mainScreenRegion, screen);
6173 }
6174 NotifyScreenChanged(screen->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SOURCE_MODE_CHANGE);
6175 NotifyDisplayChanged(screen->ConvertToDisplayInfo(), DisplayChangeEvent::SOURCE_MODE_CHANGED);
6176 SetScreenCastInfo(screen->GetScreenId(), group->mirrorScreenId_, combination);
6177 }
6178 group->combination_ = combination;
6179 AddScreenToGroup(group, addScreens, addChildPos, removeChildResMap);
6180 }
6181
ChangeMirrorScreenConfig(const sptr<ScreenSessionGroup> & group,const DMRect & mainScreenRegion,sptr<ScreenSession> & screen)6182 void ScreenSessionManager::ChangeMirrorScreenConfig(const sptr<ScreenSessionGroup>& group,
6183 const DMRect& mainScreenRegion, sptr<ScreenSession>& screen)
6184 {
6185 if (screen == nullptr) {
6186 return;
6187 }
6188 auto screenId = screen->GetScreenId();
6189 if (group == nullptr) {
6190 return;
6191 }
6192 auto mirrorScreenId = group->mirrorScreenId_;
6193 ScreenId rsScreenId = SCREEN_ID_INVALID;
6194 if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
6195 TLOGE(WmsLogTag::DMS, "Screen: %{public}" PRIu64" convert to rs id failed", mirrorScreenId);
6196 return;
6197 }
6198 screen->SetMirrorScreenRegion(rsScreenId, mainScreenRegion);
6199 screen->SetIsPhysicalMirrorSwitch(false);
6200 IsEnableRegionRotation(screen);
6201 TLOGI(WmsLogTag::DMS, "Screen: %{public}" PRIu64" mirror to %{public}"
6202 PRIu64" with region, x:%{public}d y:%{public}d w:%{public}u h:%{public}u",
6203 screenId, mirrorScreenId, mainScreenRegion.posX_, mainScreenRegion.posY_,
6204 mainScreenRegion.width_, mainScreenRegion.height_);
6205 }
6206
HasSameScreenCastInfo(ScreenId screenId,ScreenId castScreenId,ScreenCombination screenCombination)6207 bool ScreenSessionManager::HasSameScreenCastInfo(ScreenId screenId,
6208 ScreenId castScreenId, ScreenCombination screenCombination)
6209 {
6210 std::shared_lock<std::shared_mutex> lock(screenCastInfoMapMutex_);
6211 auto iter = screenCastInfoMap_.find(screenId);
6212 if (iter != screenCastInfoMap_.end() && iter->second.first == castScreenId &&
6213 iter->second.second == screenCombination) {
6214 return true;
6215 }
6216 return false;
6217 }
6218
SetScreenCastInfo(ScreenId screenId,ScreenId castScreenId,ScreenCombination screenCombination)6219 void ScreenSessionManager::SetScreenCastInfo(ScreenId screenId,
6220 ScreenId castScreenId, ScreenCombination screenCombination)
6221 {
6222 std::unique_lock<std::shared_mutex> lock(screenCastInfoMapMutex_);
6223 screenCastInfoMap_.insert(std::make_pair(screenId, std::make_pair(castScreenId, screenCombination)));
6224 TLOGI(WmsLogTag::DMS,
6225 "screenId:%{public}" PRIu64 ",castScreenId:%{public}" PRIu64 ",screenCombination:%{public}d",
6226 screenId, castScreenId, screenCombination);
6227 }
6228
RemoveScreenCastInfo(ScreenId screenId)6229 void ScreenSessionManager::RemoveScreenCastInfo(ScreenId screenId)
6230 {
6231 std::unique_lock<std::shared_mutex> lock(screenCastInfoMapMutex_);
6232 auto iter = screenCastInfoMap_.find(screenId);
6233 if (iter == screenCastInfoMap_.end()) {
6234 return;
6235 }
6236 screenCastInfoMap_.erase(iter);
6237 TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 "", screenId);
6238 }
6239
IsEnableRegionRotation(sptr<ScreenSession> screenSession)6240 void ScreenSessionManager::IsEnableRegionRotation(sptr<ScreenSession> screenSession)
6241 {
6242 if (!FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
6243 screenSession->SetIsEnableRegionRotation(false);
6244 TLOGI(WmsLogTag::DMS, "Region rotation is not supported");
6245 return;
6246 }
6247 if (screenSession->GetName() == "screen_capture_file" || screenSession->GetName() == "screen_capture") {
6248 screenSession->SetIsEnableRegionRotation(false);
6249 } else {
6250 screenSession->SetIsEnableRegionRotation(true);
6251 }
6252 TLOGI(WmsLogTag::DMS, "Screen session name: %{public}s", screenSession->GetName().c_str());
6253 }
6254
AddScreenToGroup(sptr<ScreenSessionGroup> group,const std::vector<ScreenId> & addScreens,const std::vector<Point> & addChildPos,std::map<ScreenId,bool> & removeChildResMap)6255 void ScreenSessionManager::AddScreenToGroup(sptr<ScreenSessionGroup> group,
6256 const std::vector<ScreenId>& addScreens, const std::vector<Point>& addChildPos,
6257 std::map<ScreenId, bool>& removeChildResMap)
6258 {
6259 std::vector<sptr<ScreenInfo>> addToGroup;
6260 std::vector<sptr<ScreenInfo>> removeFromGroup;
6261 std::vector<sptr<ScreenInfo>> changeGroup;
6262 for (uint64_t i = 0; i != addScreens.size(); i++) {
6263 ScreenId screenId = addScreens[i];
6264 sptr<ScreenSession> screen = GetScreenSession(screenId);
6265 if (screen == nullptr) {
6266 continue;
6267 }
6268 Point expandPoint = addChildPos[i];
6269 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64", Point: %{public}d, %{public}d",
6270 screen->screenId_, expandPoint.posX_, expandPoint.posY_);
6271 bool addChildRes = group->AddChild(screen, expandPoint, GetScreenSession(group->mirrorScreenId_));
6272 if (removeChildResMap[screenId] && addChildRes) {
6273 changeGroup.emplace_back(screen->ConvertToScreenInfo());
6274 TLOGD(WmsLogTag::DMS, "changeGroup");
6275 } else if (removeChildResMap[screenId]) {
6276 TLOGD(WmsLogTag::DMS, "removeChild");
6277 removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
6278 } else if (addChildRes) {
6279 TLOGD(WmsLogTag::DMS, "AddChild");
6280 addToGroup.emplace_back(screen->ConvertToScreenInfo());
6281 } else {
6282 TLOGD(WmsLogTag::DMS, "default, AddChild failed");
6283 }
6284 NotifyDisplayCreate(screen->ConvertToDisplayInfo());
6285 }
6286
6287 NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
6288 NotifyScreenGroupChanged(changeGroup, ScreenGroupChangeEvent::CHANGE_GROUP);
6289 NotifyScreenGroupChanged(addToGroup, ScreenGroupChangeEvent::ADD_TO_GROUP);
6290 }
6291
RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)6292 void ScreenSessionManager::RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)
6293 {
6294 TLOGW(WmsLogTag::DMS, "enter!");
6295 if (!SessionPermission::IsSystemCalling()) {
6296 TLOGE(WmsLogTag::DMS, "permission denied calling: %{public}s, pid: %{public}d",
6297 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6298 return;
6299 }
6300 if (screens.empty()) {
6301 return;
6302 }
6303 std::vector<sptr<ScreenInfo>> removeFromGroup;
6304 for (ScreenId screenId : screens) {
6305 auto screen = GetScreenSession(screenId);
6306 if (screen == nullptr || screen->GetScreenProperty().GetScreenType() != ScreenType::VIRTUAL) {
6307 continue;
6308 }
6309 auto originGroup = GetAbstractScreenGroup(screen->groupSmsId_);
6310 if (originGroup == nullptr) {
6311 continue;
6312 }
6313 if (!originGroup->HasChild(screenId)) {
6314 continue;
6315 }
6316 RemoveFromGroupLocked(screen);
6317 removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
6318 }
6319 NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
6320 }
6321
GetRSDisplayNodeByScreenId(ScreenId smsScreenId) const6322 const std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetRSDisplayNodeByScreenId(ScreenId smsScreenId) const
6323 {
6324 static std::shared_ptr<RSDisplayNode> notFound = nullptr;
6325 sptr<ScreenSession> screen = GetScreenSession(smsScreenId);
6326 if (screen == nullptr) {
6327 TLOGE(WmsLogTag::DMS, "screen == nullptr!");
6328 return notFound;
6329 }
6330 if (screen->GetDisplayNode() == nullptr) {
6331 TLOGE(WmsLogTag::DMS, "displayNode_ == nullptr!");
6332 return notFound;
6333 }
6334 TLOGI(WmsLogTag::DMS, "screen: %{public}" PRIu64", nodeId: %{public}" PRIu64" ",
6335 screen->screenId_, screen->GetDisplayNode()->GetId());
6336 return screen->GetDisplayNode();
6337 }
6338
GetDisplayNodeByDisplayId(DisplayId displayId)6339 std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetDisplayNodeByDisplayId(DisplayId displayId)
6340 {
6341 std::shared_ptr<RSDisplayNode> displayNode = nullptr;
6342 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6343 for (auto sessionIt : screenSessionMap_) {
6344 auto screenSession = sessionIt.second;
6345 if (screenSession == nullptr) {
6346 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
6347 continue;
6348 }
6349 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
6350 if (displayInfo == nullptr) {
6351 TLOGE(WmsLogTag::DMS, "displayInfo is nullptr!");
6352 continue;
6353 }
6354 if (displayId == displayInfo->GetDisplayId()) {
6355 if (sessionIt.first == SCREEN_ID_INVALID) {
6356 TLOGE(WmsLogTag::DMS, "screenId is invalid!");
6357 continue;
6358 }
6359 displayNode = screenSession->GetDisplayNode();
6360 break;
6361 }
6362 }
6363 return displayNode;
6364 }
6365
IsFakeDisplayExist()6366 bool ScreenSessionManager::IsFakeDisplayExist()
6367 {
6368 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
6369 SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
6370 return true;
6371 }
6372 return false;
6373 }
6374
GetScreenSnapshot(DisplayId displayId,bool isUseDma,bool isCaptureFullOfScreen,const std::vector<NodeId> & surfaceNodesList)6375 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetScreenSnapshot(DisplayId displayId, bool isUseDma,
6376 bool isCaptureFullOfScreen, const std::vector<NodeId>& surfaceNodesList)
6377 {
6378 DisplayId realDisplayId = displayId;
6379 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && displayId == DISPLAY_ID_FAKE) {
6380 if (!SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
6381 TLOGE(WmsLogTag::DMS, "fake display is not exist!");
6382 return nullptr;
6383 }
6384 realDisplayId = 0;
6385 }
6386 TLOGW(WmsLogTag::DMS, "dma=%{public}d, displayId:%{public}" PRIu64, isUseDma, realDisplayId);
6387 std::shared_ptr<RSDisplayNode> displayNode = GetDisplayNodeByDisplayId(realDisplayId);
6388 if (displayNode == nullptr) {
6389 TLOGE(WmsLogTag::DMS, "displayNode is null!");
6390 return nullptr;
6391 }
6392 std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
6393 RSSurfaceCaptureConfig config;
6394 config.isHdrCapture = false;
6395 config.useDma = isUseDma;
6396 #ifdef FOLD_ABILITY_ENABLE
6397 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
6398 SuperFoldPolicy::GetInstance().IsNeedSetSnapshotRect(displayId)) {
6399 config.mainScreenRect = SuperFoldPolicy::GetInstance().GetSnapshotRect(displayId, isCaptureFullOfScreen);
6400 }
6401 #endif
6402 config.blackList = surfaceNodesList;
6403 if (surfaceNodesList.size() > 0) {
6404 TLOGI(WmsLogTag::DMS, "Snapshot filtering surfaceNodesList surfaceNodes, size:%{public}ud",
6405 static_cast<uint32_t>(surfaceNodesList.size()));
6406 }
6407 bool ret = rsInterface_.TakeSurfaceCapture(displayNode, callback, config);
6408 if (!ret) {
6409 TLOGE(WmsLogTag::DMS, "TakeSurfaceCapture failed");
6410 return nullptr;
6411 }
6412 std::shared_ptr<Media::PixelMap> screenshot = callback->GetResult(GET_HDR_PIXELMAP_TIMEOUT); // wait for <= 2000ms
6413 if (screenshot == nullptr) {
6414 TLOGE(WmsLogTag::DMS, "Failed to get pixelmap from RS, return nullptr!");
6415 } else {
6416 TLOGD(WmsLogTag::DMS, "Sucess to get pixelmap from RS!");
6417 }
6418 // notify dm listener
6419 sptr<ScreenshotInfo> snapshotInfo = new ScreenshotInfo();
6420 snapshotInfo->SetTrigger(SysCapUtil::GetClientName());
6421 snapshotInfo->SetDisplayId(displayId);
6422 OnScreenshot(snapshotInfo);
6423 return screenshot;
6424 }
6425
GetScreenHDRSnapshot(DisplayId displayId,bool isUseDma,bool isCaptureFullOfScreen,const std::vector<NodeId> & surfaceNodesList)6426 std::vector<std::shared_ptr<Media::PixelMap>> ScreenSessionManager::GetScreenHDRSnapshot(
6427 DisplayId displayId, bool isUseDma, bool isCaptureFullOfScreen, const std::vector<NodeId>& surfaceNodesList)
6428 {
6429 DisplayId realDisplayId = displayId;
6430 #ifdef FOLD_ABILITY_ENABLE
6431 static bool isSuperFoldDisplayDevice = FoldScreenStateInternel::IsSuperFoldDisplayDevice();
6432 if (isSuperFoldDisplayDevice && displayId == DISPLAY_ID_FAKE) {
6433 if (!SuperFoldPolicy::GetInstance().IsFakeDisplayExist()) {
6434 TLOGE(WmsLogTag::DMS, "fake display is not exist!");
6435 return {nullptr, nullptr};
6436 }
6437 realDisplayId = 0;
6438 }
6439 #endif
6440 std::shared_ptr<RSDisplayNode> displayNode = GetDisplayNodeByDisplayId(realDisplayId);
6441 if (displayNode == nullptr) {
6442 TLOGE(WmsLogTag::DMS, "displayNode is null!");
6443 return {nullptr, nullptr};
6444 }
6445 std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
6446 RSSurfaceCaptureConfig config;
6447 config.isHdrCapture = true;
6448 config.useDma = isUseDma;
6449 TLOGI(WmsLogTag::DMS, "take surface capture with dma=%{public}d", isUseDma);
6450 #ifdef FOLD_ABILITY_ENABLE
6451 if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
6452 config.mainScreenRect = foldScreenController_->GetScreenSnapshotRect();
6453 }
6454 if (isSuperFoldDisplayDevice && SuperFoldPolicy::GetInstance().IsNeedSetSnapshotRect(displayId)) {
6455 config.mainScreenRect = SuperFoldPolicy::GetInstance().GetSnapshotRect(displayId, isCaptureFullOfScreen);
6456 }
6457 #endif
6458 config.blackList = surfaceNodesList;
6459 if (surfaceNodesList.size() > 0) {
6460 TLOGI(WmsLogTag::DMS, "Snapshot filter, size:%{public}ud", static_cast<uint32_t>(surfaceNodesList.size()));
6461 }
6462 bool ret = rsInterface_.TakeSurfaceCapture(displayNode, callback, config);
6463 if (!ret) {
6464 TLOGE(WmsLogTag::DMS, "TakeSurfaceCapture failed");
6465 return {nullptr, nullptr};
6466 }
6467 // wait for <= 2000ms
6468 std::vector<std::shared_ptr<Media::PixelMap>> screenshotVec = callback->GetHDRResult(GET_HDR_PIXELMAP_TIMEOUT);
6469 if (screenshotVec.size() != PIXMAP_VECTOR_SIZE || screenshotVec[0] == nullptr) {
6470 TLOGE(WmsLogTag::DMS, "Failed to get pixelmap vector from RS, return nullptr!");
6471 return {nullptr, nullptr};
6472 }
6473 // notify dm listener
6474 sptr<ScreenshotInfo> snapshotInfo = new ScreenshotInfo();
6475 snapshotInfo->SetTrigger(SysCapUtil::GetClientName());
6476 snapshotInfo->SetDisplayId(displayId);
6477 OnScreenshot(snapshotInfo);
6478 return screenshotVec;
6479 }
6480
GetDisplaySnapshot(DisplayId displayId,DmErrorCode * errorCode,bool isUseDma,bool isCaptureFullOfScreen)6481 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetDisplaySnapshot(DisplayId displayId,
6482 DmErrorCode* errorCode, bool isUseDma, bool isCaptureFullOfScreen)
6483 {
6484 TLOGD(WmsLogTag::DMS, "enter!");
6485 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall() && errorCode) {
6486 *errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
6487 return nullptr;
6488 }
6489 if (system::GetBoolParameter("persist.edm.disallow_screenshot", false) && errorCode) {
6490 TLOGI(WmsLogTag::DMS, "snapshot disabled by edm!");
6491 *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6492 return nullptr;
6493 }
6494 if (displayId == DISPLAY_ID_FAKE && !IsFakeDisplayExist() && errorCode) {
6495 *errorCode = DmErrorCode::DM_ERROR_INVALID_SCREEN;
6496 TLOGE(WmsLogTag::DMS, "fake display not exist!");
6497 return nullptr;
6498 }
6499 if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
6500 SessionPermission::IsShellCall()) {
6501 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplaySnapshot(%" PRIu64")", displayId);
6502 auto res = GetScreenSnapshot(displayId, isUseDma, isCaptureFullOfScreen);
6503 if (res != nullptr) {
6504 NotifyScreenshot(displayId);
6505 if (SessionPermission::IsBetaVersion()) {
6506 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
6507 }
6508 }
6509 isScreenShot_ = true;
6510 NotifyCaptureStatusChanged();
6511 return res;
6512 } else if (errorCode) {
6513 *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6514 }
6515 return nullptr;
6516 }
6517
GetDisplayHDRSnapshot(DisplayId displayId,DmErrorCode & errorCode,bool isUseDma,bool isCaptureFullOfScreen)6518 std::vector<std::shared_ptr<Media::PixelMap>> ScreenSessionManager::GetDisplayHDRSnapshot(DisplayId displayId,
6519 DmErrorCode& errorCode, bool isUseDma, bool isCaptureFullOfScreen)
6520 {
6521 TLOGI(WmsLogTag::DMS, "enter!");
6522 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall()) {
6523 errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
6524 return {nullptr, nullptr};
6525 }
6526 if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
6527 TLOGE(WmsLogTag::DMS, "snapshot disabled by edm!");
6528 errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6529 return {nullptr, nullptr};
6530 }
6531 if (displayId == DISPLAY_ID_FAKE && !IsFakeDisplayExist()) {
6532 TLOGE(WmsLogTag::DMS, "fake display not exist!");
6533 errorCode = DmErrorCode::DM_ERROR_INVALID_SCREEN;
6534 return {nullptr, nullptr};
6535 }
6536 if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
6537 SessionPermission::IsShellCall()) {
6538 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplayHDRSnapshot(%" PRIu64")", displayId);
6539 std::vector<std::shared_ptr<Media::PixelMap>> res = GetScreenHDRSnapshot(
6540 displayId, isUseDma, isCaptureFullOfScreen);
6541 if (res.size() == PIXMAP_VECTOR_SIZE && res[SDR_PIXMAP] != nullptr) {
6542 NotifyScreenshot(displayId);
6543 if (SessionPermission::IsBetaVersion()) {
6544 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
6545 }
6546 } else {
6547 TLOGE(WmsLogTag::DMS, "GetScreenHDRSnapshot get PixelMap vector failed");
6548 }
6549 isScreenShot_ = true;
6550 NotifyCaptureStatusChanged();
6551 return res;
6552 } else {
6553 errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6554 }
6555 return {nullptr, nullptr};
6556 }
6557
GetDisplaySnapshotWithOption(const CaptureOption & option,DmErrorCode * errorCode)6558 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetDisplaySnapshotWithOption(const CaptureOption& option,
6559 DmErrorCode* errorCode)
6560 {
6561 TLOGD(WmsLogTag::DMS, "enter!");
6562 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall() &&
6563 !SessionPermission::IsSACalling()) {
6564 if (errorCode != nullptr) {
6565 *errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
6566 }
6567 return nullptr;
6568 }
6569 if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
6570 TLOGI(WmsLogTag::DMS, "snapshot was disabled by edm!");
6571 return nullptr;
6572 }
6573 if (option.displayId_ == DISPLAY_ID_FAKE && !IsFakeDisplayExist() && errorCode) {
6574 TLOGE(WmsLogTag::DMS, "fake display not exist!");
6575 *errorCode = DmErrorCode::DM_ERROR_INVALID_SCREEN;
6576 return nullptr;
6577 }
6578 if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
6579 SessionPermission::IsShellCall()) {
6580 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetDisplaySnapshot(%" PRIu64")", option.displayId_);
6581 auto res = GetScreenSnapshot(option.displayId_, true, option.isCaptureFullOfScreen_, option.surfaceNodesList_);
6582 if (res != nullptr) {
6583 if (SessionPermission::IsBetaVersion()) {
6584 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
6585 }
6586 TLOGI(WmsLogTag::DMS, "isNeedNotify_:%{public}d", option.isNeedNotify_);
6587 if (option.isNeedNotify_) {
6588 isScreenShot_ = true;
6589 NotifyScreenshot(option.displayId_);
6590 NotifyCaptureStatusChanged();
6591 }
6592 }
6593 return res;
6594 } else if (errorCode) {
6595 *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6596 }
6597 return nullptr;
6598 }
6599
GetDisplayHDRSnapshotWithOption(const CaptureOption & option,DmErrorCode & errorCode)6600 std::vector<std::shared_ptr<Media::PixelMap>> ScreenSessionManager::GetDisplayHDRSnapshotWithOption(
6601 const CaptureOption& option, DmErrorCode& errorCode)
6602 {
6603 TLOGD(WmsLogTag::DMS, "enter!");
6604 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsShellCall() &&
6605 !SessionPermission::IsSACalling()) {
6606 errorCode = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
6607 return {nullptr, nullptr};
6608 }
6609 if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
6610 TLOGE(WmsLogTag::DMS, "snapshot was disabled by edm!");
6611 errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6612 return {nullptr, nullptr};
6613 }
6614 if (option.displayId_ == DISPLAY_ID_FAKE && !IsFakeDisplayExist()) {
6615 TLOGE(WmsLogTag::DMS, "fake display not exist!");
6616 errorCode = DmErrorCode::DM_ERROR_INVALID_SCREEN;
6617 return {nullptr, nullptr};
6618 }
6619 if ((Permission::IsSystemCalling() && Permission::CheckCallingPermission(SCREEN_CAPTURE_PERMISSION)) ||
6620 SessionPermission::IsShellCall()) {
6621 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
6622 "ssm:GetDisplayHDRSnapshotWithOption(%" PRIu64")", option.displayId_);
6623 std::vector<std::shared_ptr<Media::PixelMap>> res = GetScreenHDRSnapshot(
6624 option.displayId_, true, option.isCaptureFullOfScreen_, option.surfaceNodesList_);
6625 if (res.size() == PIXMAP_VECTOR_SIZE && res[SDR_PIXMAP] != nullptr) {
6626 if (SessionPermission::IsBetaVersion()) {
6627 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
6628 }
6629 TLOGI(WmsLogTag::DMS, "isNeedNotify_:%{public}d", option.isNeedNotify_);
6630 if (option.isNeedNotify_) {
6631 isScreenShot_ = true;
6632 NotifyScreenshot(option.displayId_);
6633 NotifyCaptureStatusChanged();
6634 }
6635 }
6636 return res;
6637 } else {
6638 errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6639 }
6640 return {nullptr, nullptr};
6641 }
6642
GetSnapshotByPicker(Media::Rect & rect,DmErrorCode * errorCode)6643 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetSnapshotByPicker(Media::Rect &rect, DmErrorCode* errorCode)
6644 {
6645 TLOGD(WmsLogTag::DMS, "ENTER!");
6646 *errorCode = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
6647 std::lock_guard<std::mutex> lock(snapBypickerMutex_);
6648
6649 if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
6650 *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
6651 TLOGI(WmsLogTag::DMS, "snapshot was disabled by edm!");
6652 return nullptr;
6653 }
6654 ScreenId screenId = SCREEN_ID_INVALID;
6655 // get snapshot area frome Screenshot extension
6656 if (!GetSnapshotArea(rect, errorCode, screenId)) {
6657 return nullptr;
6658 }
6659 auto screenSession = GetScreenSession(screenId);
6660 if (screenSession == nullptr) {
6661 TLOGE(WmsLogTag::DMS, "can not get screen session");
6662 return nullptr;
6663 }
6664 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
6665 if (displayInfo == nullptr) {
6666 TLOGE(WmsLogTag::DMS, "can not get default display");
6667 return nullptr;
6668 }
6669 DisplayId displayId = displayInfo->GetDisplayId();
6670 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSnapshotByPicker(%" PRIu64")", displayId);
6671 auto pixelMap = GetScreenSnapshot(displayId, false);
6672 if (pixelMap != nullptr && SessionPermission::IsBetaVersion()) {
6673 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
6674 }
6675 isScreenShot_ = true;
6676 NotifyCaptureStatusChanged();
6677 *errorCode = DmErrorCode::DM_OK;
6678 return pixelMap;
6679 }
6680
GetSnapshotArea(Media::Rect & rect,DmErrorCode * errorCode,ScreenId & screenId)6681 bool ScreenSessionManager::GetSnapshotArea(Media::Rect &rect, DmErrorCode* errorCode, ScreenId &screenId)
6682 {
6683 ConfigureScreenSnapshotParams();
6684 if (ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerConnectExtension()) {
6685 int32_t ret = ScreenSnapshotPickerConnection::GetInstance().GetScreenSnapshotInfo(rect, screenId);
6686 if (ret != 0) {
6687 TLOGE(WmsLogTag::DMS, "GetScreenSnapshotInfo failed");
6688 ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerDisconnectExtension();
6689 if (ret == RES_FAILURE_FOR_PRIVACY_WINDOW) {
6690 *errorCode = DmErrorCode::DM_ERROR_INVALID_CALLING;
6691 } else {
6692 *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
6693 }
6694 return false;
6695 }
6696 ScreenSnapshotPickerConnection::GetInstance().SnapshotPickerDisconnectExtension();
6697 } else {
6698 *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
6699 TLOGE(WmsLogTag::DMS, "SnapshotPickerConnectExtension failed");
6700 return false;
6701 }
6702 return true;
6703 }
6704
OnRemoteDied(const sptr<IRemoteObject> & agent)6705 bool ScreenSessionManager::OnRemoteDied(const sptr<IRemoteObject>& agent)
6706 {
6707 if (agent == nullptr) {
6708 return false;
6709 }
6710 std::vector<ScreenId> screenVecCopy;
6711 {
6712 std::lock_guard<std::mutex> lock(screenAgentMapMutex_);
6713 auto agentIter = screenAgentMap_.find(agent);
6714 if (agentIter != screenAgentMap_.end()) {
6715 screenVecCopy = agentIter->second;
6716 }
6717 }
6718 bool ret = true;
6719 for (const auto screenId : screenVecCopy) {
6720 auto screenSession = GetScreenSession(screenId);
6721 if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
6722 TLOGI(WmsLogTag::DMS, "stop mirror in OnRemoteDied: %{public}" PRIu64, screenId);
6723 StopMirror(std::vector<ScreenId>(1, screenId));
6724 }
6725 TLOGI(WmsLogTag::DMS, "destroy screenId in OnRemoteDied: %{public}" PRIu64, screenId);
6726 DMError res = DestroyVirtualScreen(screenId);
6727 if (res != DMError::DM_OK) {
6728 TLOGE(WmsLogTag::DMS, "destroy failed in OnRemoteDied: %{public}" PRIu64, screenId);
6729 ret = false;
6730 }
6731 }
6732 return ret;
6733 }
6734
GetAllValidScreenIds(const std::vector<ScreenId> & screenIds) const6735 std::vector<ScreenId> ScreenSessionManager::GetAllValidScreenIds(const std::vector<ScreenId>& screenIds) const
6736 {
6737 std::vector<ScreenId> validScreenIds;
6738 for (ScreenId screenId : screenIds) {
6739 auto screenIdIter = std::find(validScreenIds.begin(), validScreenIds.end(), screenId);
6740 if (screenIdIter != validScreenIds.end()) {
6741 continue;
6742 }
6743 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
6744 auto iter = screenSessionMap_.find(screenId);
6745 if (iter != screenSessionMap_.end() && iter->second != nullptr &&
6746 iter->second->GetScreenProperty().GetScreenType() != ScreenType::UNDEFINED) {
6747 validScreenIds.emplace_back(screenId);
6748 }
6749 }
6750 return validScreenIds;
6751 }
6752
GetScreenGroupInfoById(ScreenId screenId)6753 sptr<ScreenGroupInfo> ScreenSessionManager::GetScreenGroupInfoById(ScreenId screenId)
6754 {
6755 if (!SessionPermission::IsSystemCalling()) {
6756 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
6757 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6758 return nullptr;
6759 }
6760 auto screenSessionGroup = GetAbstractScreenGroup(screenId);
6761 if (screenSessionGroup == nullptr) {
6762 TLOGE(WmsLogTag::DMS, "cannot find screenGroupInfo: %{public}" PRIu64"", screenId);
6763 return nullptr;
6764 }
6765 return screenSessionGroup->ConvertToScreenGroupInfo();
6766 }
6767
NotifyScreenConnected(sptr<ScreenInfo> screenInfo)6768 void ScreenSessionManager::NotifyScreenConnected(sptr<ScreenInfo> screenInfo)
6769 {
6770 if (screenInfo == nullptr) {
6771 TLOGE(WmsLogTag::DMS, "error, screenInfo is nullptr.");
6772 return;
6773 }
6774 auto task = [=] {
6775 TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64"", screenInfo->GetScreenId());
6776 OnScreenConnect(screenInfo);
6777 };
6778 taskScheduler_->PostAsyncTask(task, "NotifyScreenConnected");
6779 }
6780
NotifyScreenDisconnected(ScreenId screenId)6781 void ScreenSessionManager::NotifyScreenDisconnected(ScreenId screenId)
6782 {
6783 auto task = [=] {
6784 TLOGNI(WmsLogTag::DMS, "notify screenId:%{public}" PRIu64"", screenId);
6785 OnScreenDisconnect(screenId);
6786 };
6787 taskScheduler_->PostAsyncTask(task, "NotifyScreenDisconnected");
6788 }
6789
NotifyDisplayCreate(sptr<DisplayInfo> displayInfo)6790 void ScreenSessionManager::NotifyDisplayCreate(sptr<DisplayInfo> displayInfo)
6791 {
6792 if (displayInfo == nullptr) {
6793 return;
6794 }
6795 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
6796 TLOGI(WmsLogTag::DMS, "start, agent size: %{public}u", static_cast<uint32_t>(agents.size()));
6797 if (agents.empty()) {
6798 return;
6799 }
6800 for (auto& agent : agents) {
6801 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6802 if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
6803 agent->OnDisplayCreate(displayInfo);
6804 }
6805 }
6806 }
6807
NotifyDisplayDestroy(DisplayId displayId)6808 void ScreenSessionManager::NotifyDisplayDestroy(DisplayId displayId)
6809 {
6810 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
6811 TLOGI(WmsLogTag::DMS, "agent size: %{public}u", static_cast<uint32_t>(agents.size()));
6812 if (agents.empty()) {
6813 return;
6814 }
6815 for (auto& agent : agents) {
6816 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
6817 if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER)) {
6818 agent->OnDisplayDestroy(displayId);
6819 }
6820 }
6821 }
6822
NotifyScreenGroupChanged(const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent event)6823 void ScreenSessionManager::NotifyScreenGroupChanged(
6824 const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent event)
6825 {
6826 if (screenInfo == nullptr) {
6827 TLOGE(WmsLogTag::DMS, "screenInfo is nullptr.");
6828 return;
6829 }
6830 std::string trigger = SysCapUtil::GetClientName();
6831 auto task = [=] {
6832 TLOGNI(WmsLogTag::DMS, "screenId:%{public}" PRIu64", trigger:[%{public}s]",
6833 screenInfo->GetScreenId(), trigger.c_str());
6834 OnScreenGroupChange(trigger, screenInfo, event);
6835 };
6836 taskScheduler_->PostAsyncTask(task, "NotifyScreenGroupChanged:PID");
6837 }
6838
NotifyScreenGroupChanged(const std::vector<sptr<ScreenInfo>> & screenInfo,ScreenGroupChangeEvent event)6839 void ScreenSessionManager::NotifyScreenGroupChanged(
6840 const std::vector<sptr<ScreenInfo>>& screenInfo, ScreenGroupChangeEvent event)
6841 {
6842 if (screenInfo.empty()) {
6843 return;
6844 }
6845 std::string trigger = SysCapUtil::GetClientName();
6846 auto task = [=] {
6847 TLOGNI(WmsLogTag::DMS, "trigger:[%{public}s]", trigger.c_str());
6848 OnScreenGroupChange(trigger, screenInfo, event);
6849 };
6850 taskScheduler_->PostAsyncTask(task, "NotifyScreenGroupChanged");
6851 }
6852
NotifyPrivateSessionStateChanged(bool hasPrivate)6853 void ScreenSessionManager::NotifyPrivateSessionStateChanged(bool hasPrivate)
6854 {
6855 if (hasPrivate == screenPrivacyStates) {
6856 TLOGD(WmsLogTag::DMS, "screen session state is not changed, return");
6857 return;
6858 }
6859 TLOGI(WmsLogTag::DMS, "status : %{public}u", hasPrivate);
6860 screenPrivacyStates = hasPrivate;
6861 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::PRIVATE_WINDOW_LISTENER);
6862 if (agents.empty()) {
6863 return;
6864 }
6865 for (auto& agent : agents) {
6866 agent->NotifyPrivateWindowStateChanged(hasPrivate);
6867 }
6868 }
6869
SetScreenPrivacyState(bool hasPrivate)6870 void ScreenSessionManager::SetScreenPrivacyState(bool hasPrivate)
6871 {
6872 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6873 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
6874 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6875 return;
6876 }
6877 TLOGI(WmsLogTag::DMS, "enter, hasPrivate: %{public}d", hasPrivate);
6878 ScreenId id = GetDefaultScreenId();
6879 auto screenSession = GetScreenSession(id);
6880 if (screenSession == nullptr) {
6881 TLOGE(WmsLogTag::DMS, "can not get default screen now");
6882 return;
6883 }
6884 screenSession->SetPrivateSessionForeground(hasPrivate);
6885 NotifyPrivateSessionStateChanged(hasPrivate);
6886 }
6887
SetPrivacyStateByDisplayId(DisplayId id,bool hasPrivate)6888 void ScreenSessionManager::SetPrivacyStateByDisplayId(DisplayId id, bool hasPrivate)
6889 {
6890 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6891 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
6892 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6893 return;
6894 }
6895 TLOGI(WmsLogTag::DMS, "enter, hasPrivate: %{public}d", hasPrivate);
6896 std::vector<ScreenId> screenIds = GetAllScreenIds();
6897 auto iter = std::find(screenIds.begin(), screenIds.end(), id);
6898 if (iter == screenIds.end()) {
6899 TLOGE(WmsLogTag::DMS, "invalid displayId");
6900 return;
6901 }
6902 auto screenSession = GetScreenSession(id);
6903 if (screenSession == nullptr) {
6904 TLOGE(WmsLogTag::DMS, "can not get id: %{public}" PRIu64" screen now", id);
6905 return;
6906 }
6907 screenSession->SetPrivateSessionForeground(hasPrivate);
6908 NotifyPrivateSessionStateChanged(hasPrivate);
6909 }
6910
SetScreenPrivacyWindowList(DisplayId id,std::vector<std::string> privacyWindowList)6911 void ScreenSessionManager::SetScreenPrivacyWindowList(DisplayId id, std::vector<std::string> privacyWindowList)
6912 {
6913 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6914 TLOGE(WmsLogTag::DMS, "Permmission Denied! calling: %{public}s, pid: %{public}d",
6915 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6916 return;
6917 }
6918 TLOGW(WmsLogTag::DMS, "enter");
6919 std::vector<ScreenId> screenIds = GetAllScreenIds();
6920 auto iter = std::find(screenIds.begin(), screenIds.end(), id);
6921 if (iter == screenIds.end()) {
6922 TLOGE(WmsLogTag::DMS, "invalid displayId");
6923 return;
6924 }
6925 auto screenSession = GetScreenSession(id);
6926 if (screenSession == nullptr) {
6927 TLOGE(WmsLogTag::DMS, "can not get id: %{public}" PRIu64" screen now", id);
6928 return;
6929 }
6930 NotifyPrivateWindowListChanged(id, privacyWindowList);
6931 }
6932
NotifyPrivateWindowListChanged(DisplayId id,std::vector<std::string> privacyWindowList)6933 void ScreenSessionManager::NotifyPrivateWindowListChanged(DisplayId id, std::vector<std::string> privacyWindowList)
6934 {
6935 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::PRIVATE_WINDOW_LIST_LISTENER);
6936 if (agents.empty()) {
6937 return;
6938 }
6939 for (auto& agent : agents) {
6940 agent->NotifyPrivateStateWindowListChanged(id, privacyWindowList);
6941 }
6942 }
6943
HasPrivateWindow(DisplayId id,bool & hasPrivateWindow)6944 DMError ScreenSessionManager::HasPrivateWindow(DisplayId id, bool& hasPrivateWindow)
6945 {
6946 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6947 TLOGE(WmsLogTag::DMS, "Permmision Denied! calling: %{public}s, pid: %{public}d",
6948 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
6949 return DMError::DM_ERROR_NOT_SYSTEM_APP;
6950 }
6951 if (id == DISPLAY_ID_FAKE) {
6952 auto displayInfo = GetDefaultDisplayInfo();
6953 if (displayInfo) {
6954 id = displayInfo->GetDisplayId();
6955 TLOGI(WmsLogTag::DMS, "change displayId: %{public}" PRIu64" to displayId: %{public}" PRIu64,
6956 DISPLAY_ID_FAKE, id);
6957 }
6958 }
6959 std::vector<ScreenId> screenIds = GetAllScreenIds();
6960 auto iter = std::find(screenIds.begin(), screenIds.end(), id);
6961 if (iter == screenIds.end()) {
6962 TLOGE(WmsLogTag::DMS, "invalid displayId");
6963 return DMError::DM_ERROR_INVALID_PARAM;
6964 }
6965 auto screenSession = GetScreenSession(id);
6966 if (screenSession == nullptr) {
6967 return DMError::DM_ERROR_NULLPTR;
6968 }
6969 hasPrivateWindow = screenSession->HasPrivateSessionForeground();
6970 TLOGI(WmsLogTag::DMS, "id: %{public}" PRIu64" has private window: %{public}u",
6971 id, static_cast<uint32_t>(hasPrivateWindow));
6972 return DMError::DM_OK;
6973 }
6974
OnScreenGroupChange(const std::string & trigger,const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent groupEvent)6975 void ScreenSessionManager::OnScreenGroupChange(const std::string& trigger,
6976 const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent groupEvent)
6977 {
6978 if (screenInfo == nullptr) {
6979 return;
6980 }
6981 std::vector<sptr<ScreenInfo>> screenInfos;
6982 screenInfos.push_back(screenInfo);
6983 OnScreenGroupChange(trigger, screenInfos, groupEvent);
6984 }
6985
OnScreenGroupChange(const std::string & trigger,const std::vector<sptr<ScreenInfo>> & screenInfos,ScreenGroupChangeEvent groupEvent)6986 void ScreenSessionManager::OnScreenGroupChange(const std::string& trigger,
6987 const std::vector<sptr<ScreenInfo>>& screenInfos, ScreenGroupChangeEvent groupEvent)
6988 {
6989 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
6990 std::vector<sptr<ScreenInfo>> infos;
6991 for (auto& screenInfo : screenInfos) {
6992 if (screenInfo != nullptr) {
6993 infos.emplace_back(screenInfo);
6994 }
6995 }
6996 if (agents.empty() || infos.empty()) {
6997 return;
6998 }
6999 for (auto& agent : agents) {
7000 agent->OnScreenGroupChange(trigger, infos, groupEvent);
7001 }
7002 }
7003
OnScreenConnect(const sptr<ScreenInfo> screenInfo)7004 void ScreenSessionManager::OnScreenConnect(const sptr<ScreenInfo> screenInfo)
7005 {
7006 if (screenInfo == nullptr) {
7007 TLOGE(WmsLogTag::DMS, "screenInfo nullptr");
7008 return;
7009 }
7010 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
7011 if (agents.empty()) {
7012 TLOGI(WmsLogTag::DMS, "agents empty");
7013 return;
7014 }
7015 TLOGI(WmsLogTag::DMS, "start");
7016 for (auto& agent : agents) {
7017 agent->OnScreenConnect(screenInfo);
7018 }
7019 NotifyScreenModeChange();
7020 }
7021
OnScreenDisconnect(ScreenId screenId)7022 void ScreenSessionManager::OnScreenDisconnect(ScreenId screenId)
7023 {
7024 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
7025 if (agents.empty()) {
7026 TLOGI(WmsLogTag::DMS, "agents empty");
7027 return;
7028 }
7029 TLOGI(WmsLogTag::DMS, "start");
7030 for (auto& agent : agents) {
7031 agent->OnScreenDisconnect(screenId);
7032 }
7033 NotifyScreenModeChange(screenId);
7034 }
7035
OnScreenshot(sptr<ScreenshotInfo> info)7036 void ScreenSessionManager::OnScreenshot(sptr<ScreenshotInfo> info)
7037 {
7038 if (info == nullptr) {
7039 TLOGE(WmsLogTag::DMS, "info is null");
7040 return;
7041 }
7042 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREENSHOT_EVENT_LISTENER);
7043 if (agents.empty()) {
7044 TLOGD(WmsLogTag::DMS, "agents empty");
7045 return;
7046 }
7047 TLOGI(WmsLogTag::DMS, "start");
7048 for (auto& agent : agents) {
7049 agent->OnScreenshot(info);
7050 }
7051 }
7052
GetCutoutInfo(DisplayId displayId)7053 sptr<CutoutInfo> ScreenSessionManager::GetCutoutInfo(DisplayId displayId)
7054 {
7055 DmsXcollie dmsXcollie("DMS:GetCutoutInfo", XCOLLIE_TIMEOUT_10S);
7056 return screenCutoutController_ ? screenCutoutController_->GetScreenCutoutInfo(displayId) : nullptr;
7057 }
7058
GetCutoutInfo(DisplayId displayId,int32_t width,int32_t height,Rotation rotation)7059 sptr<CutoutInfo> ScreenSessionManager::GetCutoutInfo(DisplayId displayId, int32_t width,
7060 int32_t height, Rotation rotation)
7061 {
7062 DmsXcollie dmsXcollie("DMS:GetCutoutInfo", XCOLLIE_TIMEOUT_10S);
7063 return screenCutoutController_ ? screenCutoutController_->GetScreenCutoutInfo(displayId, width, height, rotation) :
7064 nullptr;
7065 }
7066
HasImmersiveWindow(ScreenId screenId,bool & immersive)7067 DMError ScreenSessionManager::HasImmersiveWindow(ScreenId screenId, bool& immersive)
7068 {
7069 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7070 TLOGE(WmsLogTag::DMS, "permission denied!");
7071 return DMError::DM_ERROR_NOT_SYSTEM_APP;
7072 }
7073 auto clientProxy = GetClientProxy();
7074 if (!clientProxy) {
7075 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
7076 return DMError::DM_ERROR_NULLPTR;
7077 }
7078 clientProxy->OnImmersiveStateChanged(screenId, immersive);
7079 return DMError::DM_OK;
7080 }
7081
TransferTypeToString(ScreenType type) const7082 std::string ScreenSessionManager::TransferTypeToString(ScreenType type) const
7083 {
7084 std::string screenType;
7085 switch (type) {
7086 case ScreenType::REAL:
7087 screenType = "REAL";
7088 break;
7089 case ScreenType::VIRTUAL:
7090 screenType = "VIRTUAL";
7091 break;
7092 default:
7093 screenType = "UNDEFINED";
7094 break;
7095 }
7096 return screenType;
7097 }
7098
TransferPropertyChangeTypeToString(ScreenPropertyChangeType type) const7099 std::string ScreenSessionManager::TransferPropertyChangeTypeToString(ScreenPropertyChangeType type) const
7100 {
7101 std::string screenType;
7102 switch (type) {
7103 case ScreenPropertyChangeType::UNSPECIFIED:
7104 screenType = "UNSPECIFIED";
7105 break;
7106 case ScreenPropertyChangeType::ROTATION_BEGIN:
7107 screenType = "ROTATION_BEGIN";
7108 break;
7109 case ScreenPropertyChangeType::ROTATION_END:
7110 screenType = "ROTATION_END";
7111 break;
7112 case ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY:
7113 screenType = "ROTATION_UPDATE_PROPERTY_ONLY";
7114 break;
7115 case ScreenPropertyChangeType::ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY:
7116 screenType = "ROTATION_UPDATE_PROPERTY_ONLY_NOT_NOTIFY";
7117 break;
7118 default:
7119 screenType = "UNDEFINED";
7120 break;
7121 }
7122 return screenType;
7123 }
7124
DumpAllScreensInfo(std::string & dumpInfo)7125 void ScreenSessionManager::DumpAllScreensInfo(std::string& dumpInfo)
7126 {
7127 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
7128 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
7129 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7130 return;
7131 }
7132 std::ostringstream oss;
7133 oss << "--------------------------------------Free Screen"
7134 << "--------------------------------------"
7135 << std::endl;
7136 oss << "ScreenName Type IsGroup DmsId RsId ActiveIdx VPR Rotation Orientation "
7137 << "RequestOrientation NodeId "
7138 << std::endl;
7139 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
7140 for (auto sessionIt : screenSessionMap_) {
7141 auto screenSession = sessionIt.second;
7142 if (screenSession == nullptr) {
7143 continue;
7144 }
7145 sptr<ScreenInfo> screenInfo = screenSession->ConvertToScreenInfo();
7146 if (screenInfo == nullptr) {
7147 continue;
7148 }
7149 std::string screenType = TransferTypeToString(screenInfo->GetType());
7150 NodeId nodeId = (screenSession->GetDisplayNode() == nullptr) ?
7151 SCREEN_ID_INVALID : screenSession->GetDisplayNode()->GetId();
7152 oss << std::left << std::setw(21) << screenInfo->GetName() // 21 is width
7153 << std::left << std::setw(9) << screenType // 9 is width
7154 << std::left << std::setw(8) << (screenSession->isScreenGroup_ ? "true" : "false") // 8 is width
7155 << std::left << std::setw(6) << screenSession->screenId_ // 6 is width
7156 << std::left << std::setw(21) << screenSession->rsId_ // 21 is width
7157 << std::left << std::setw(10) << screenSession->activeIdx_ // 10 is width
7158 << std::left << std::setw(4) << screenInfo->GetVirtualPixelRatio() // 4 is width
7159 << std::left << std::setw(9) << static_cast<uint32_t>(screenInfo->GetRotation()) // 9 is width
7160 << std::left << std::setw(12) << static_cast<uint32_t>(screenInfo->GetOrientation()) // 12 is width
7161 << std::left << std::setw(19) // 19 is width
7162 << static_cast<uint32_t>(screenSession->GetScreenRequestedOrientation())
7163 << std::left << std::setw(21) << nodeId // 21 is width
7164 << std::endl;
7165 }
7166 oss << "total screen num: " << screenSessionMap_.size() << std::endl;
7167 dumpInfo.append(oss.str());
7168 }
7169
DumpSpecialScreenInfo(ScreenId id,std::string & dumpInfo)7170 void ScreenSessionManager::DumpSpecialScreenInfo(ScreenId id, std::string& dumpInfo)
7171 {
7172 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
7173 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
7174 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7175 return;
7176 }
7177 std::ostringstream oss;
7178 sptr<ScreenSession> session = GetScreenSession(id);
7179 if (!session) {
7180 TLOGE(WmsLogTag::DMS, "Get screen session failed.");
7181 oss << "This screen id is invalid.";
7182 dumpInfo.append(oss.str());
7183 return;
7184 }
7185 sptr<ScreenInfo> screenInfo = GetScreenInfoById(id);
7186 if (screenInfo == nullptr) {
7187 return;
7188 }
7189 std::string screenType = TransferTypeToString(screenInfo->GetType());
7190 NodeId nodeId = (session->GetDisplayNode() == nullptr) ?
7191 SCREEN_ID_INVALID : session->GetDisplayNode()->GetId();
7192 oss << "ScreenName: " << screenInfo->GetName() << std::endl;
7193 oss << "Type: " << screenType << std::endl;
7194 oss << "IsGroup: " << (session->isScreenGroup_ ? "true" : "false") << std::endl;
7195 oss << "DmsId: " << id << std::endl;
7196 oss << "RsId: " << session->rsId_ << std::endl;
7197 oss << "ActiveIdx: " << session->activeIdx_ << std::endl;
7198 oss << "VPR: " << screenInfo->GetVirtualPixelRatio() << std::endl;
7199 oss << "Rotation: " << static_cast<uint32_t>(screenInfo->GetRotation()) << std::endl;
7200 oss << "Orientation: " << static_cast<uint32_t>(screenInfo->GetOrientation()) << std::endl;
7201 oss << "RequestOrientation: " << static_cast<uint32_t>(session->GetScreenRequestedOrientation()) << std::endl;
7202 oss << "NodeId: " << nodeId << std::endl;
7203 dumpInfo.append(oss.str());
7204 }
7205
7206 // --- Fold Screen ---
GetPhyScreenProperty(ScreenId screenId)7207 ScreenProperty ScreenSessionManager::GetPhyScreenProperty(ScreenId screenId)
7208 {
7209 std::lock_guard<std::recursive_mutex> lock_phy(phyScreenPropMapMutex_);
7210 ScreenProperty property;
7211 auto iter = phyScreenPropMap_.find(screenId);
7212 if (iter == phyScreenPropMap_.end()) {
7213 TLOGI(WmsLogTag::DMS, "Error found physic screen config with id: %{public}" PRIu64, screenId);
7214 return property;
7215 }
7216 return iter->second;
7217 }
7218
UpdateCameraBackSelfie(bool isCameraBackSelfie)7219 void ScreenSessionManager::UpdateCameraBackSelfie(bool isCameraBackSelfie)
7220 {
7221 if (isCameraBackSelfie_ == isCameraBackSelfie) {
7222 return;
7223 }
7224 isCameraBackSelfie_ = isCameraBackSelfie;
7225
7226 auto screenSession = GetDefaultScreenSession();
7227 if (!screenSession) {
7228 TLOGW(WmsLogTag::DMS, "screenSession is null, notify camera back selfie failed");
7229 return;
7230 }
7231 screenSession->HandleCameraBackSelfieChange(isCameraBackSelfie);
7232
7233 if (isCameraBackSelfie) {
7234 TLOGI(WmsLogTag::DMS, "isBackSelfie, SetScreenCorrection MAIN to 270");
7235 rsInterface_.SetScreenCorrection(SCREEN_ID_MAIN, static_cast<ScreenRotation>(ROTATION_270));
7236 } else {
7237 TLOGI(WmsLogTag::DMS, "exit BackSelfie, SetScreenCorrection MAIN to 90");
7238 SetScreenCorrection();
7239 }
7240 }
7241
SetFoldDisplayMode(const FoldDisplayMode displayMode)7242 void ScreenSessionManager::SetFoldDisplayMode(const FoldDisplayMode displayMode)
7243 {
7244 SetFoldDisplayModeInner(displayMode);
7245 }
7246
SetFoldDisplayModeInner(const FoldDisplayMode displayMode,std::string reason)7247 DMError ScreenSessionManager::SetFoldDisplayModeInner(const FoldDisplayMode displayMode, std::string reason)
7248 {
7249 #ifdef FOLD_ABILITY_ENABLE
7250 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7251 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d, reason: %{public}s",
7252 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid(), reason.c_str());
7253 return DMError::DM_ERROR_NOT_SYSTEM_APP;
7254 }
7255 if (!g_foldScreenFlag) {
7256 return DMError::DM_ERROR_INVALID_MODE_ID;
7257 }
7258 if (foldScreenController_ == nullptr) {
7259 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
7260 return DMError::DM_ERROR_INVALID_MODE_ID;
7261 }
7262 if (!SessionPermission::IsSystemCalling()) {
7263 TLOGE(WmsLogTag::DMS, "permission denied!");
7264 return DMError::DM_ERROR_NOT_SYSTEM_APP;
7265 }
7266 TLOGI(WmsLogTag::DMS, "calling clientName: %{public}s, calling pid: %{public}d, setmode: %{public}d",
7267 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid(), displayMode);
7268 if (foldScreenController_->GetTentMode() &&
7269 (displayMode == FoldDisplayMode::FULL || displayMode == FoldDisplayMode::COORDINATION)) {
7270 TLOGW(WmsLogTag::DMS, "in TentMode, SetFoldDisplayMode to %{public}d failed", displayMode);
7271 return DMError::DM_ERROR_INVALID_MODE_ID;
7272 } else if ((FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() ||
7273 FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) && IsScreenCasting() &&
7274 displayMode == FoldDisplayMode::COORDINATION) {
7275 TLOGW(WmsLogTag::DMS, "is phone casting, SetFoldDisplayMode to %{public}d is not allowed", displayMode);
7276 return DMError::DM_ERROR_INVALID_MODE_ID;
7277 }
7278 if (reason.compare("backSelfie") == 0) {
7279 UpdateCameraBackSelfie(true);
7280 }
7281 foldScreenController_->SetDisplayMode(displayMode);
7282 NotifyClientProxyUpdateFoldDisplayMode(displayMode);
7283 #endif
7284 return DMError::DM_OK;
7285 }
7286
SetFoldDisplayModeFromJs(const FoldDisplayMode displayMode,std::string reason)7287 DMError ScreenSessionManager::SetFoldDisplayModeFromJs(const FoldDisplayMode displayMode, std::string reason)
7288 {
7289 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7290 TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
7291 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7292 return DMError::DM_ERROR_NOT_SYSTEM_APP;
7293 }
7294 return SetFoldDisplayModeInner(displayMode, reason);
7295 }
7296
UpdateDisplayScaleState(ScreenId screenId)7297 void ScreenSessionManager::UpdateDisplayScaleState(ScreenId screenId)
7298 {
7299 auto session = GetScreenSession(screenId);
7300 if (session == nullptr) {
7301 TLOGE(WmsLogTag::DMS, "session is null");
7302 return;
7303 }
7304 const ScreenProperty& property = session->GetScreenProperty();
7305 if (std::fabs(property.GetScaleX() - DEFAULT_SCALE) < FLT_EPSILON &&
7306 std::fabs(property.GetScaleY() - DEFAULT_SCALE) < FLT_EPSILON &&
7307 std::fabs(property.GetPivotX() - DEFAULT_PIVOT) < FLT_EPSILON &&
7308 std::fabs(property.GetPivotY() - DEFAULT_PIVOT) < FLT_EPSILON) {
7309 TLOGD(WmsLogTag::DMS, "The scale and pivot is default value now. There is no need to update");
7310 return;
7311 }
7312 SetDisplayScaleInner(screenId, property.GetScaleX(), property.GetScaleY(), property.GetPivotX(),
7313 property.GetPivotY());
7314 }
7315
SetDisplayScaleInner(ScreenId screenId,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY)7316 void ScreenSessionManager::SetDisplayScaleInner(ScreenId screenId, const float& scaleX, const float& scaleY,
7317 const float& pivotX, const float& pivotY)
7318 {
7319 auto session = GetScreenSession(screenId);
7320 if (session == nullptr) {
7321 TLOGE(WmsLogTag::DMS, "session is null");
7322 return;
7323 }
7324 if (pivotX > 1.0f || pivotX < 0.0f || pivotY > 1.0f || pivotY < 0.0f) {
7325 TLOGE(WmsLogTag::DMS, "pivotX [%{public}f] and pivotY [%{public}f] should be in [0.0~1.0f]", pivotX, pivotY);
7326 return;
7327 }
7328 float translateX = 0.0f;
7329 float translateY = 0.0f;
7330 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7331 CalcDisplayNodeTranslateOnPocketFoldRotation(session, scaleX, scaleY, pivotX, pivotY,
7332 translateX, translateY);
7333 } else if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
7334 if (FoldDisplayMode::MAIN == GetFoldDisplayMode()) {
7335 CalcDisplayNodeTranslateOnPocketFoldRotation(session, scaleX, scaleY, pivotX, pivotY,
7336 translateX, translateY);
7337 } else {
7338 CalcDisplayNodeTranslateOnRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
7339 }
7340 } else if (ROTATE_POLICY == FOLDABLE_DEVICE && FoldDisplayMode::FULL == GetFoldDisplayMode()) {
7341 CalcDisplayNodeTranslateOnFoldableRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
7342 } else if (SCREEN_SCAN_TYPE == SCAN_TYPE_VERTICAL) {
7343 CalcDisplayNodeTranslateOnVerticalScanRotation(session, ScaleProperty(scaleX, scaleY, pivotX, pivotY),
7344 translateX, translateY);
7345 } else {
7346 CalcDisplayNodeTranslateOnRotation(session, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
7347 }
7348 TLOGW(WmsLogTag::DMS,
7349 "screenId %{public}" PRIu64 ", scale [%{public}f, %{public}f], "
7350 "pivot [%{public}f, %{public}f], translate [%{public}f, %{public}f]",
7351 screenId, scaleX, scaleY, pivotX, pivotY, translateX, translateY);
7352 session->SetScreenScale(scaleX, scaleY, pivotX, pivotY, translateX, translateY);
7353 NotifyDisplayStateChange(GetDefaultScreenId(), session->ConvertToDisplayInfo(), {},
7354 DisplayStateChangeType::UPDATE_SCALE);
7355 }
7356
CalcDisplayNodeTranslateOnFoldableRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)7357 void ScreenSessionManager::CalcDisplayNodeTranslateOnFoldableRotation(sptr<ScreenSession>& session, const float& scaleX,
7358 const float& scaleY, const float& pivotX,
7359 const float& pivotY, float& translateX,
7360 float& translateY)
7361 {
7362 if (session == nullptr) {
7363 TLOGE(WmsLogTag::DMS, "session is nullptr");
7364 return;
7365 }
7366 const ScreenProperty& screenProperty = session->GetScreenProperty();
7367 auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
7368 auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
7369 Rotation rotation = session->GetRotation();
7370 float rotatedPivotX = DEFAULT_PIVOT;
7371 float rotatedPivotY = DEFAULT_PIVOT;
7372 float width = 0.0f;
7373 float height = 0.0f;
7374 switch (rotation) {
7375 case Rotation::ROTATION_0:
7376 rotatedPivotX = pivotY;
7377 rotatedPivotY = 1.0f - pivotX;
7378 width = screenHeight;
7379 height = screenWidth;
7380 break;
7381 case Rotation::ROTATION_90:
7382 rotatedPivotX = 1.0f - pivotX;
7383 rotatedPivotY = 1.0f - pivotY;
7384 width = screenWidth;
7385 height = screenHeight;
7386 break;
7387 case Rotation::ROTATION_180:
7388 rotatedPivotX = 1.0f - pivotY;
7389 rotatedPivotY = pivotX;
7390 width = screenHeight;
7391 height = screenWidth;
7392 break;
7393 case Rotation::ROTATION_270:
7394 rotatedPivotX = pivotX;
7395 rotatedPivotY = pivotY;
7396 width = screenWidth;
7397 height = screenHeight;
7398 break;
7399 default:
7400 TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
7401 break;
7402 }
7403 translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
7404 translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
7405 }
7406
CalcDisplayNodeTranslateOnPocketFoldRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)7407 void ScreenSessionManager::CalcDisplayNodeTranslateOnPocketFoldRotation(sptr<ScreenSession>& session,
7408 const float& scaleX, const float& scaleY,
7409 const float& pivotX, const float& pivotY,
7410 float& translateX, float& translateY)
7411 {
7412 if (session == nullptr) {
7413 TLOGE(WmsLogTag::DMS, "session is nullptr");
7414 return;
7415 }
7416 const ScreenProperty& screenProperty = session->GetScreenProperty();
7417 auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
7418 auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
7419 Rotation rotation = session->GetRotation();
7420 float rotatedPivotX = DEFAULT_PIVOT;
7421 float rotatedPivotY = DEFAULT_PIVOT;
7422 float width = 0.0f;
7423 float height = 0.0f;
7424 switch (rotation) {
7425 case Rotation::ROTATION_0:
7426 rotatedPivotX = 1.0f - pivotY;
7427 rotatedPivotY = pivotX;
7428 width = screenHeight;
7429 height = screenWidth;
7430 break;
7431 case Rotation::ROTATION_90:
7432 rotatedPivotX = pivotX;
7433 rotatedPivotY = pivotY;
7434 width = screenWidth;
7435 height = screenHeight;
7436 break;
7437 case Rotation::ROTATION_180:
7438 rotatedPivotX = pivotY;
7439 rotatedPivotY = 1.0f - pivotX;
7440 width = screenHeight;
7441 height = screenWidth;
7442 break;
7443 case Rotation::ROTATION_270:
7444 rotatedPivotX = 1.0f - pivotX;
7445 rotatedPivotY = 1.0f - pivotY;
7446 width = screenWidth;
7447 height = screenHeight;
7448 break;
7449 default:
7450 TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
7451 break;
7452 }
7453 translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
7454 translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
7455 }
7456
CalcDisplayNodeTranslateOnVerticalScanRotation(const sptr<ScreenSession> & session,const ScaleProperty & scalep,float & translateX,float & translateY)7457 void ScreenSessionManager::CalcDisplayNodeTranslateOnVerticalScanRotation(const sptr<ScreenSession>& session,
7458 const ScaleProperty& scalep,
7459 float& translateX, float& translateY)
7460 {
7461 if (session == nullptr) {
7462 TLOGE(WmsLogTag::DMS, "session is nullptr");
7463 return;
7464 }
7465 auto screenProperty = session->GetScreenProperty();
7466 auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
7467 auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
7468 Rotation rotation = session->GetRotation();
7469 float rotatedPivotX = DEFAULT_PIVOT;
7470 float rotatedPivotY = DEFAULT_PIVOT;
7471 float width = 0.0f;
7472 float height = 0.0f;
7473 switch (rotation) {
7474 case Rotation::ROTATION_90:
7475 rotatedPivotX = scalep.pivotX;
7476 rotatedPivotY = scalep.pivotY;
7477 width = screenWidth;
7478 height = screenHeight;
7479 break;
7480 case Rotation::ROTATION_180:
7481 rotatedPivotX = scalep.pivotY;
7482 rotatedPivotY = 1.0f - scalep.pivotX;
7483 width = screenHeight;
7484 height = screenWidth;
7485 break;
7486 case Rotation::ROTATION_270:
7487 rotatedPivotX = 1.0f - scalep.pivotX;
7488 rotatedPivotY = 1.0f - scalep.pivotY;
7489 width = screenWidth;
7490 height = screenHeight;
7491 break;
7492 case Rotation::ROTATION_0:
7493 rotatedPivotX = 1.0f - scalep.pivotY;
7494 rotatedPivotY = scalep.pivotX;
7495 width = screenHeight;
7496 height = screenWidth;
7497 break;
7498 default:
7499 TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
7500 break;
7501 }
7502 translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scalep.scaleX - DEFAULT_SCALE) * width;
7503 translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scalep.scaleY - DEFAULT_SCALE) * height;
7504 }
7505
CalcDisplayNodeTranslateOnRotation(sptr<ScreenSession> & session,const float & scaleX,const float & scaleY,const float & pivotX,const float & pivotY,float & translateX,float & translateY)7506 void ScreenSessionManager::CalcDisplayNodeTranslateOnRotation(sptr<ScreenSession>& session, const float& scaleX,
7507 const float& scaleY, const float& pivotX,
7508 const float& pivotY, float& translateX, float& translateY)
7509 {
7510 if (session == nullptr) {
7511 TLOGE(WmsLogTag::DMS, "session is nullptr");
7512 return;
7513 }
7514 const ScreenProperty& screenProperty = session->GetScreenProperty();
7515 auto screenWidth = screenProperty.GetBounds().rect_.GetWidth();
7516 auto screenHeight = screenProperty.GetBounds().rect_.GetHeight();
7517 Rotation rotation = session->GetRotation();
7518 float rotatedPivotX = DEFAULT_PIVOT;
7519 float rotatedPivotY = DEFAULT_PIVOT;
7520 float width = 0.0f;
7521 float height = 0.0f;
7522 switch (rotation) {
7523 case Rotation::ROTATION_0:
7524 rotatedPivotX = pivotX;
7525 rotatedPivotY = pivotY;
7526 width = screenWidth;
7527 height = screenHeight;
7528 break;
7529 case Rotation::ROTATION_90:
7530 rotatedPivotX = pivotY;
7531 rotatedPivotY = 1.0f - pivotX;
7532 width = screenHeight;
7533 height = screenWidth;
7534 break;
7535 case Rotation::ROTATION_180:
7536 rotatedPivotX = 1.0f - pivotX;
7537 rotatedPivotY = 1.0f - pivotY;
7538 width = screenWidth;
7539 height = screenHeight;
7540 break;
7541 case Rotation::ROTATION_270:
7542 rotatedPivotX = 1.0f - pivotY;
7543 rotatedPivotY = pivotX;
7544 width = screenHeight;
7545 height = screenWidth;
7546 break;
7547 default:
7548 TLOGE(WmsLogTag::DMS, "Unknown Rotation %{public}d", rotation);
7549 break;
7550 }
7551 translateX = (DEFAULT_PIVOT - rotatedPivotX) * (scaleX - DEFAULT_SCALE) * width;
7552 translateY = (DEFAULT_PIVOT - rotatedPivotY) * (scaleY - DEFAULT_SCALE) * height;
7553 }
7554
SetDisplayScale(ScreenId screenId,float scaleX,float scaleY,float pivotX,float pivotY)7555 void ScreenSessionManager::SetDisplayScale(ScreenId screenId, float scaleX, float scaleY, float pivotX,
7556 float pivotY)
7557 {
7558 if (!SessionPermission::IsSACalling()) {
7559 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
7560 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7561 return;
7562 }
7563 SetDisplayScaleInner(screenId, scaleX, scaleY, pivotX, pivotY);
7564 }
7565
SetFoldStatusLocked(bool locked)7566 void ScreenSessionManager::SetFoldStatusLocked(bool locked)
7567 {
7568 #ifdef FOLD_ABILITY_ENABLE
7569 HandleSuperFoldStatusLocked(locked);
7570 if (!g_foldScreenFlag) {
7571 return;
7572 }
7573 if (foldScreenController_ == nullptr) {
7574 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
7575 return;
7576 }
7577 if (!SessionPermission::IsSystemCalling()) {
7578 TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
7579 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7580 return;
7581 }
7582 foldScreenController_->LockDisplayStatus(locked);
7583 #endif
7584 }
7585
SetFoldStatusLockedFromJs(bool locked)7586 DMError ScreenSessionManager::SetFoldStatusLockedFromJs(bool locked)
7587 {
7588 if (!SessionPermission::IsSystemCalling()) {
7589 TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d",
7590 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
7591 return DMError::DM_ERROR_NOT_SYSTEM_APP;
7592 }
7593 SetFoldStatusLocked(locked);
7594 return DMError::DM_OK;
7595 }
7596
GetFoldDisplayMode()7597 FoldDisplayMode ScreenSessionManager::GetFoldDisplayMode()
7598 {
7599 #ifdef FOLD_ABILITY_ENABLE
7600 DmsXcollie dmsXcollie("DMS:GetFoldDisplayMode", XCOLLIE_TIMEOUT_10S);
7601 if (!g_foldScreenFlag) {
7602 return FoldDisplayMode::UNKNOWN;
7603 }
7604 if (foldScreenController_ == nullptr) {
7605 TLOGD(WmsLogTag::DMS, "foldScreenController_ is null");
7606 return FoldDisplayMode::UNKNOWN;
7607 }
7608 if (IsSpecialApp()) {
7609 return FoldDisplayMode::MAIN;
7610 }
7611 return foldScreenController_->GetDisplayMode();
7612 #else
7613 return FoldDisplayMode::UNKNOWN;
7614 #endif
7615 }
7616
IsFoldable()7617 bool ScreenSessionManager::IsFoldable()
7618 {
7619 #ifdef FOLD_ABILITY_ENABLE
7620 // Most applications do not adapt to Lem rotation and are temporarily treated as non fold device
7621 if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
7622 return false;
7623 }
7624
7625 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7626 return true;
7627 }
7628
7629 if (!g_foldScreenFlag) {
7630 return false;
7631 }
7632 if (foldScreenController_ == nullptr) {
7633 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
7634 return false;
7635 }
7636 if (IsSpecialApp()) {
7637 return false;
7638 }
7639 return foldScreenController_->IsFoldable();
7640 #else
7641 return false;
7642 #endif
7643 }
7644
IsCaptured()7645 bool ScreenSessionManager::IsCaptured()
7646 {
7647 if (ScreenSceneConfig::GetExternalScreenDefaultMode() == "none") {
7648 // 如果当前是PC拓展模式,非截屏,录屏,投屏,则返回false
7649 return isScreenShot_ || virtualScreenCount_ > 0 || (hdmiScreenCount_ > 0 && !IsExtendMode());
7650 } else {
7651 return isScreenShot_ || virtualScreenCount_ > 0 || hdmiScreenCount_ > 0;
7652 }
7653 }
7654
IsMultiScreenCollaboration()7655 bool ScreenSessionManager::IsMultiScreenCollaboration()
7656 {
7657 return isMultiScreenCollaboration_;
7658 }
7659
HasCastEngineOrPhyMirror(const std::vector<ScreenId> & screenIdsToExclude)7660 bool ScreenSessionManager::HasCastEngineOrPhyMirror(const std::vector<ScreenId>& screenIdsToExclude)
7661 {
7662 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
7663 for (auto sessionItem : screenSessionMap_) {
7664 auto screenId = sessionItem.first;
7665 auto screenSession = sessionItem.second;
7666 if (screenSession == nullptr) {
7667 TLOGI(WmsLogTag::DMS, "screenSession is null");
7668 continue;
7669 }
7670 if (std::find(screenIdsToExclude.begin(), screenIdsToExclude.end(), screenId) != screenIdsToExclude.end()) {
7671 continue;
7672 }
7673 auto screenType = screenSession->GetScreenProperty().GetScreenType();
7674 if (screenType == ScreenType::VIRTUAL
7675 && screenSession->GetName() == SCREEN_NAME_CAST) {
7676 return true;
7677 }
7678
7679 if (IsDefaultMirrorMode(screenId) && screenType == ScreenType::REAL &&
7680 screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
7681 return true;
7682 }
7683 }
7684 return false;
7685 }
7686
GetFoldStatus()7687 FoldStatus ScreenSessionManager::GetFoldStatus()
7688 {
7689 #ifdef FOLD_ABILITY_ENABLE
7690 DmsXcollie dmsXcollie("DMS:GetFoldStatus", XCOLLIE_TIMEOUT_10S);
7691 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7692 SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
7693 return SuperFoldStateManager::GetInstance().MatchSuperFoldStatusToFoldStatus(status);
7694 }
7695 if (!g_foldScreenFlag) {
7696 return FoldStatus::UNKNOWN;
7697 }
7698 if (foldScreenController_ == nullptr) {
7699 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
7700 return FoldStatus::UNKNOWN;
7701 }
7702 if (IsSpecialApp()) {
7703 return FoldStatus::UNKNOWN;
7704 }
7705 return foldScreenController_->GetFoldStatus();
7706 #else
7707 return FoldStatus::UNKNOWN;
7708 #endif
7709 }
7710
GetSuperFoldStatus()7711 SuperFoldStatus ScreenSessionManager::GetSuperFoldStatus()
7712 {
7713 #ifdef FOLD_ABILITY_ENABLE
7714 DmsXcollie dmsXcollie("DMS:GetSuperFoldStatus", XCOLLIE_TIMEOUT_10S);
7715 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7716 return SuperFoldStatus::UNKNOWN;
7717 }
7718 SuperFoldStatus status = SuperFoldStateManager::GetInstance().GetCurrentStatus();
7719 return status;
7720 #else
7721 return SuperFoldStatus::UNKNOWN;
7722 #endif
7723 }
7724
GetSuperRotation()7725 float ScreenSessionManager::GetSuperRotation()
7726 {
7727 DmsXcollie dmsXcollie("DMS:GetSuperRotation", XCOLLIE_TIMEOUT_10S);
7728 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7729 return -1.f;
7730 }
7731 {
7732 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
7733 for (auto sessionIt : screenSessionMap_) {
7734 auto screenSession = sessionIt.second;
7735 if (screenSession == nullptr) {
7736 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
7737 continue;
7738 }
7739 if (screenSession->GetIsInternal()) {
7740 float rotation = static_cast<int>(screenSession->GetRotation()) * 90.f;
7741 TLOGI(WmsLogTag::DMS, "is internal, screenId = %{public}" PRIu64 ", rotation = %{public}f",
7742 sessionIt.first, rotation);
7743 return rotation;
7744 } else {
7745 TLOGI(WmsLogTag::DMS, "not internal, screenId = %{public}" PRIu64"", sessionIt.first);
7746 }
7747 }
7748 }
7749 TLOGE(WmsLogTag::DMS, "all screenSession is nullptr or not internal");
7750 return -1.f;
7751 }
7752
GetIsLandscapeLockStatus()7753 bool ScreenSessionManager::GetIsLandscapeLockStatus()
7754 {
7755 return isLandscapeLockStatus_;
7756 }
7757
SetIsLandscapeLockStatus(bool isLandscapeLockStatus)7758 void ScreenSessionManager::SetIsLandscapeLockStatus(bool isLandscapeLockStatus)
7759 {
7760 isLandscapeLockStatus_ = isLandscapeLockStatus;
7761 }
7762
SetLandscapeLockStatus(bool isLocked)7763 void ScreenSessionManager::SetLandscapeLockStatus(bool isLocked)
7764 {
7765 #ifdef FOLD_ABILITY_ENABLE
7766 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7767 TLOGE(WmsLogTag::DMS, "permission denied! pid: %{public}d", IPCSkeleton::GetCallingPid());
7768 return;
7769 }
7770 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7771 TLOGI(WmsLogTag::DMS, "not super fold display device.");
7772 return;
7773 }
7774 if (isLocked) {
7775 SetIsLandscapeLockStatus(true);
7776 SuperFoldSensorManager::GetInstance().HandleScreenConnectChange();
7777 } else {
7778 SetIsLandscapeLockStatus(false);
7779 SuperFoldSensorManager::GetInstance().HandleScreenDisconnectChange();
7780 }
7781 #endif
7782 }
7783
GetExtendScreenConnectStatus()7784 ExtendScreenConnectStatus ScreenSessionManager::GetExtendScreenConnectStatus()
7785 {
7786 #ifdef WM_MULTI_SCREEN_ENABLE
7787 DmsXcollie dmsXcollie("DMS:GetExtendScreenConnectStatus", XCOLLIE_TIMEOUT_10S);
7788 return extendScreenConnectStatus_.load();
7789 #else
7790 return ExtendScreenConnectStatus::UNKNOWN;
7791 #endif
7792 }
7793
GetIsExtendScreenConnected()7794 bool ScreenSessionManager::GetIsExtendScreenConnected()
7795 {
7796 return isExtendScreenConnected_;
7797 }
7798
SetIsExtendScreenConnected(bool isExtendScreenConnected)7799 void ScreenSessionManager::SetIsExtendScreenConnected(bool isExtendScreenConnected)
7800 {
7801 isExtendScreenConnected_ = isExtendScreenConnected;
7802 }
7803
HandleExtendScreenConnect(ScreenId screenId)7804 void ScreenSessionManager::HandleExtendScreenConnect(ScreenId screenId)
7805 {
7806 #ifdef FOLD_ABILITY_ENABLE
7807 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7808 TLOGI(WmsLogTag::DMS, "not super fold display device.");
7809 return;
7810 }
7811 SetIsExtendScreenConnected(true);
7812 extendScreenConnectStatus_.store(ExtendScreenConnectStatus::CONNECT);
7813 OnExtendScreenConnectStatusChange(screenId, ExtendScreenConnectStatus::CONNECT);
7814 #endif
7815 }
7816
HandleExtendScreenDisconnect(ScreenId screenId)7817 void ScreenSessionManager::HandleExtendScreenDisconnect(ScreenId screenId)
7818 {
7819 #ifdef FOLD_ABILITY_ENABLE
7820 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7821 TLOGI(WmsLogTag::DMS, "not super fold display device.");
7822 return;
7823 }
7824 SetIsExtendScreenConnected(false);
7825 SuperFoldSensorManager::GetInstance().HandleScreenDisconnectChange();
7826 OnExtendScreenConnectStatusChange(screenId, ExtendScreenConnectStatus::DISCONNECT);
7827 extendScreenConnectStatus_.store(ExtendScreenConnectStatus::DISCONNECT);
7828 #endif
7829 }
7830
GetIsFoldStatusLocked()7831 bool ScreenSessionManager::GetIsFoldStatusLocked()
7832 {
7833 return isFoldStatusLocked_;
7834 }
7835
SetIsFoldStatusLocked(bool isFoldStatusLocked)7836 void ScreenSessionManager::SetIsFoldStatusLocked(bool isFoldStatusLocked)
7837 {
7838 isFoldStatusLocked_ = isFoldStatusLocked;
7839 }
7840
SetFoldStatusExpandAndLocked(bool isLocked)7841 void ScreenSessionManager::SetFoldStatusExpandAndLocked(bool isLocked)
7842 {
7843 if (!SessionPermission::IsSystemCalling()) {
7844 TLOGE(WmsLogTag::DMS, "permission denied!");
7845 return;
7846 }
7847 #ifdef FOLD_ABILITY_ENABLE
7848 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7849 TLOGI(WmsLogTag::DMS, "not super fold display device.");
7850 return;
7851 }
7852 SetIsFoldStatusLocked(isLocked);
7853 if (isLocked == true) {
7854 SuperFoldSensorManager::GetInstance().HandleFoldStatusLockedToExpand();
7855 } else {
7856 SuperFoldSensorManager::GetInstance().HandleFoldStatusUnlocked();
7857 }
7858 #endif
7859 }
7860
HandleSuperFoldStatusLocked(bool isLocked)7861 void ScreenSessionManager::HandleSuperFoldStatusLocked(bool isLocked)
7862 {
7863 #ifdef FOLD_ABILITY_ENABLE
7864 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7865 TLOGI(WmsLogTag::DMS, "not super fold display device.");
7866 return;
7867 }
7868 SetIsFoldStatusLocked(isLocked);
7869 if (isLocked == true) {
7870 TLOGI(WmsLogTag::DMS, "Fold status is locked.");
7871 } else {
7872 SuperFoldSensorManager::GetInstance().HandleFoldStatusUnlocked();
7873 }
7874 #endif
7875 }
7876
GetIsOuterOnlyMode()7877 bool ScreenSessionManager::GetIsOuterOnlyMode()
7878 {
7879 return isOuterOnlyMode_;
7880 }
7881
SetIsOuterOnlyMode(bool isOuterOnlyMode)7882 void ScreenSessionManager::SetIsOuterOnlyMode(bool isOuterOnlyMode)
7883 {
7884 isOuterOnlyMode_ = isOuterOnlyMode;
7885 }
7886
GetIsOuterOnlyModeBeforePowerOff()7887 bool ScreenSessionManager::GetIsOuterOnlyModeBeforePowerOff()
7888 {
7889 return isOuterOnlyModeBeforePowerOff_;
7890 }
7891
SetIsOuterOnlyModeBeforePowerOff(bool isOuterOnlyModeBeforePowerOff)7892 void ScreenSessionManager::SetIsOuterOnlyModeBeforePowerOff(bool isOuterOnlyModeBeforePowerOff)
7893 {
7894 isOuterOnlyModeBeforePowerOff_ = isOuterOnlyModeBeforePowerOff;
7895 }
7896
GetTentMode()7897 bool ScreenSessionManager::GetTentMode()
7898 {
7899 #ifdef FOLD_ABILITY_ENABLE
7900 if (!g_foldScreenFlag) {
7901 return false;
7902 }
7903 if (foldScreenController_ == nullptr) {
7904 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
7905 return false;
7906 }
7907 return foldScreenController_->GetTentMode();
7908 #else
7909 return false;
7910 #endif
7911 }
7912
GetCurrentFoldCreaseRegion()7913 sptr<FoldCreaseRegion> ScreenSessionManager::GetCurrentFoldCreaseRegion()
7914 {
7915 #ifdef FOLD_ABILITY_ENABLE
7916 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7917 return SuperFoldStateManager::GetInstance().GetCurrentFoldCreaseRegion();
7918 }
7919 if (!g_foldScreenFlag) {
7920 return nullptr;
7921 }
7922 if (foldScreenController_ == nullptr) {
7923 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
7924 return nullptr;
7925 }
7926 return foldScreenController_->GetCurrentFoldCreaseRegion();
7927 #else
7928 return nullptr;
7929 #endif
7930 }
7931
GetLiveCreaseRegion(FoldCreaseRegion & region)7932 DMError ScreenSessionManager::GetLiveCreaseRegion(FoldCreaseRegion& region)
7933 {
7934 #ifdef FOLD_ABILITY_ENABLE
7935 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
7936 region = SuperFoldStateManager::GetInstance().GetLiveCreaseRegion();
7937 return DMError::DM_OK;
7938 }
7939 if (!g_foldScreenFlag) {
7940 region = FoldCreaseRegion(0, {});
7941 return DMError::DM_OK;
7942 }
7943 if (foldScreenController_ == nullptr) {
7944 TLOGE(WmsLogTag::DMS, "foldScreenController_ is null");
7945 return DMError::DM_ERROR_INVALID_MODE_ID;
7946 }
7947 region = foldScreenController_->GetLiveCreaseRegion();
7948 return DMError::DM_OK;
7949 #else
7950 region = FoldCreaseRegion(0, {});
7951 return DMError::DM_OK;
7952 #endif
7953 }
7954
GetCurvedCompressionArea()7955 uint32_t ScreenSessionManager::GetCurvedCompressionArea()
7956 {
7957 return ScreenSceneConfig::GetCurvedCompressionAreaInLandscape();
7958 }
7959
NotifyFoldStatusChanged(FoldStatus foldStatus)7960 void ScreenSessionManager::NotifyFoldStatusChanged(FoldStatus foldStatus)
7961 {
7962 #ifdef FOLD_ABILITY_ENABLE
7963 sptr<ScreenSession> screenSession = GetDefaultScreenSession();
7964 if (screenSession != nullptr) {
7965 if (foldStatus == FoldStatus::FOLDED && !FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
7966 screenSession->SetDefaultDeviceRotationOffset(0);
7967 } else {
7968 screenSession->SetDefaultDeviceRotationOffset(defaultDeviceRotationOffset_);
7969 }
7970 }
7971 if (screenSession != nullptr && FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
7972 // 维护外屏独立dpi
7973 if (foldStatus == FoldStatus::FOLDED) {
7974 // sub screen default rotation offset is 270
7975 screenSession->SetDefaultDeviceRotationOffset(270);
7976 auto property = screenSession->GetScreenProperty();
7977 densityDpi_ = property.GetDensity();
7978 SetVirtualPixelRatio(GetDefaultScreenId(), subDensityDpi_);
7979 } else {
7980 SetVirtualPixelRatio(GetDefaultScreenId(), densityDpi_);
7981 }
7982 }
7983 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER);
7984 TLOGI(WmsLogTag::DMS, "foldStatus:%{public}d, agent size: %{public}u",
7985 foldStatus, static_cast<uint32_t>(agents.size()));
7986 if (agents.empty()) {
7987 return;
7988 }
7989 for (auto& agent : agents) {
7990 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
7991 if (!IsFreezed(agentPid, DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER)) {
7992 agent->NotifyFoldStatusChanged(foldStatus);
7993 }
7994 }
7995 if (lowTemp_ == LowTempMode::LOW_TEMP_ON) {
7996 ScreenSessionPublish::GetInstance().PublishSmartNotificationEvent(FAULT_DESCRIPTION, FAULT_SUGGESTION);
7997 }
7998 #endif
7999 }
8000
SetLowTemp(LowTempMode lowTemp)8001 void ScreenSessionManager::SetLowTemp(LowTempMode lowTemp)
8002 {
8003 std::lock_guard<std::mutex> lock(lowTempMutex_);
8004 if (lowTemp == LowTempMode::LOW_TEMP_ON && lowTemp_ != lowTemp) {
8005 TLOGI(WmsLogTag::DMS, "device enter low temperature mode.");
8006 ScreenSessionPublish::GetInstance().PublishSmartNotificationEvent(FAULT_DESCRIPTION, FAULT_SUGGESTION);
8007 }
8008 if (lowTemp == LowTempMode::LOW_TEMP_OFF) {
8009 TLOGI(WmsLogTag::DMS, "device exit low temperature mode.");
8010 }
8011 lowTemp_ = lowTemp;
8012 }
8013
NotifyFoldAngleChanged(std::vector<float> foldAngles)8014 void ScreenSessionManager::NotifyFoldAngleChanged(std::vector<float> foldAngles)
8015 {
8016 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER);
8017 if (agents.empty()) {
8018 TLOGI(WmsLogTag::DMS, "agents is empty");
8019 return;
8020 }
8021 {
8022 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
8023 lastFoldAngles_ = foldAngles;
8024 }
8025 for (auto& agent : agents) {
8026 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8027 if (!IsFreezed(agentPid, DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER)) {
8028 agent->NotifyFoldAngleChanged(foldAngles);
8029 }
8030 }
8031 }
8032
NotifyCaptureStatusChanged()8033 void ScreenSessionManager::NotifyCaptureStatusChanged()
8034 {
8035 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER);
8036 bool isCapture = IsCaptured();
8037 isScreenShot_ = false;
8038 if (agents.empty()) {
8039 return;
8040 }
8041 for (auto& agent : agents) {
8042 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8043 if (!IsFreezed(agentPid, DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER)) {
8044 agent->NotifyCaptureStatusChanged(isCapture);
8045 }
8046 }
8047 }
8048
NotifyCaptureStatusChanged(bool isCapture)8049 void ScreenSessionManager::NotifyCaptureStatusChanged(bool isCapture)
8050 {
8051 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER);
8052 if (agents.empty()) {
8053 return;
8054 }
8055 for (auto& agent : agents) {
8056 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8057 if (!IsFreezed(agentPid, DisplayManagerAgentType::CAPTURE_STATUS_CHANGED_LISTENER)) {
8058 agent->NotifyCaptureStatusChanged(isCapture);
8059 }
8060 }
8061 }
8062
NotifyDisplayChangeInfoChanged(const sptr<DisplayChangeInfo> & info)8063 void ScreenSessionManager::NotifyDisplayChangeInfoChanged(const sptr<DisplayChangeInfo>& info)
8064 {
8065 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER);
8066 if (agents.empty()) {
8067 return;
8068 }
8069 {
8070 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
8071 lastDisplayChangeInfo_ = info;
8072 }
8073 for (auto& agent : agents) {
8074 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8075 if (!IsFreezed(agentPid, DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER)) {
8076 agent->NotifyDisplayChangeInfoChanged(info);
8077 }
8078 }
8079 }
8080
RefreshMirrorScreenRegion(ScreenId screenId)8081 void ScreenSessionManager::RefreshMirrorScreenRegion(ScreenId screenId)
8082 {
8083 #if defined(FOLD_ABILITY_ENABLE) && defined(WM_MULTI_SCREEN_ENABLE)
8084 auto screenSession = GetScreenSession(screenId);
8085 if (screenSession == nullptr) {
8086 TLOGE(WmsLogTag::DMS, "can not get screen session");
8087 return;
8088 }
8089 DMRect mainScreenRegion = {0, 0, 0, 0};
8090 foldScreenController_->SetMainScreenRegion(mainScreenRegion);
8091 ScreenId rsScreenId = SCREEN_ID_INVALID;
8092 if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
8093 TLOGE(WmsLogTag::DMS, "Screen: %{public}" PRIu64" convert to rs id failed", screenId);
8094 } else {
8095 screenSession->SetMirrorScreenRegion(rsScreenId, mainScreenRegion);
8096 screenSession->EnableMirrorScreenRegion();
8097 }
8098 #endif
8099 }
8100
NotifyDisplayModeChanged(FoldDisplayMode displayMode)8101 void ScreenSessionManager::NotifyDisplayModeChanged(FoldDisplayMode displayMode)
8102 {
8103 NotifyClientProxyUpdateFoldDisplayMode(displayMode);
8104 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER);
8105 TLOGI(WmsLogTag::DMS, "DisplayMode:%{public}d, agent size: %{public}u",
8106 displayMode, static_cast<uint32_t>(agents.size()));
8107 if (agents.empty()) {
8108 return;
8109 }
8110 for (auto& agent : agents) {
8111 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8112 if (!IsFreezed(agentPid,
8113 DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER)) {
8114 agent->NotifyDisplayModeChanged(displayMode);
8115 }
8116 }
8117 #ifdef FOLD_ABILITY_ENABLE
8118 if (foldScreenController_ != nullptr && FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
8119 auto screenIds = GetAllScreenIds();
8120 for (auto screenId : screenIds) {
8121 RefreshMirrorScreenRegion(screenId);
8122 }
8123 }
8124 #endif
8125 }
8126
NotifyScreenMagneticStateChanged(bool isMagneticState)8127 void ScreenSessionManager::NotifyScreenMagneticStateChanged(bool isMagneticState)
8128 {
8129 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_MAGNETIC_STATE_CHANGED_LISTENER);
8130 TLOGI(WmsLogTag::DMS, "IsScreenMagneticState:%{public}u, agent size: %{public}u",
8131 static_cast<uint32_t>(isMagneticState), static_cast<uint32_t>(agents.size()));
8132 if (agents.empty()) {
8133 return;
8134 }
8135 for (auto& agent : agents) {
8136 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8137 if (!IsFreezed(agentPid,
8138 DisplayManagerAgentType::SCREEN_MAGNETIC_STATE_CHANGED_LISTENER)) {
8139 agent->NotifyScreenMagneticStateChanged(isMagneticState);
8140 }
8141 }
8142 }
8143
SetDisplayNodeScreenId(ScreenId screenId,ScreenId displayNodeScreenId)8144 void ScreenSessionManager::SetDisplayNodeScreenId(ScreenId screenId, ScreenId displayNodeScreenId)
8145 {
8146 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " displayNodeScreenId: %{public}" PRIu64,
8147 screenId, displayNodeScreenId);
8148 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:SetDisplayNodeScreenId");
8149 auto clientProxy = GetClientProxy();
8150 if (!clientProxy) {
8151 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8152 return;
8153 }
8154 clientProxy->SetDisplayNodeScreenId(screenId, displayNodeScreenId);
8155 #ifdef DEVICE_STATUS_ENABLE
8156 SetDragWindowScreenId(screenId, displayNodeScreenId);
8157 #endif // DEVICE_STATUS_ENABLE
8158 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SetMultiWindowScreenId");
8159 MMI::InputManager::GetInstance()->SetMultiWindowScreenId(screenId, displayNodeScreenId);
8160 }
8161
8162 #ifdef DEVICE_STATUS_ENABLE
SetDragWindowScreenId(ScreenId screenId,ScreenId displayNodeScreenId)8163 void ScreenSessionManager::SetDragWindowScreenId(ScreenId screenId, ScreenId displayNodeScreenId)
8164 {
8165 auto interactionManager = Msdp::DeviceStatus::InteractionManager::GetInstance();
8166 if (interactionManager != nullptr) {
8167 interactionManager->SetDragWindowScreenId(screenId, displayNodeScreenId);
8168 }
8169 }
8170 #endif // DEVICE_STATUS_ENABLE
8171
OnPropertyChange(const ScreenProperty & newProperty,ScreenPropertyChangeReason reason,ScreenId screenId)8172 void ScreenSessionManager::OnPropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason,
8173 ScreenId screenId)
8174 {
8175 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " reason: %{public}d", screenId, static_cast<int>(reason));
8176 auto clientProxy = GetClientProxy();
8177 if (!clientProxy) {
8178 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8179 if (foldScreenController_ != nullptr && !FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
8180 foldScreenController_->SetdisplayModeChangeStatus(false);
8181 }
8182 return;
8183 }
8184 clientProxy->OnPropertyChanged(screenId, newProperty, reason);
8185 }
8186
OnPowerStatusChange(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)8187 void ScreenSessionManager::OnPowerStatusChange(DisplayPowerEvent event, EventStatus status,
8188 PowerStateChangeReason reason)
8189 {
8190 TLOGI(WmsLogTag::DMS, "[UL_POWER]event: %{public}d, status: %{public}d, reason: %{public}d",
8191 static_cast<int>(event),
8192 static_cast<int>(status), static_cast<int>(reason));
8193 auto clientProxy = GetClientProxy();
8194 if (!clientProxy) {
8195 TLOGI(WmsLogTag::DMS, "[UL_POWER] clientProxy_ is null");
8196 return;
8197 }
8198 clientProxy->OnPowerStatusChanged(event, status, reason);
8199 }
8200
OnSensorRotationChange(float sensorRotation,ScreenId screenId)8201 void ScreenSessionManager::OnSensorRotationChange(float sensorRotation, ScreenId screenId)
8202 {
8203 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " sensorRotation: %{public}f", screenId, sensorRotation);
8204 auto clientProxy = GetClientProxy();
8205 if (!clientProxy) {
8206 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8207 return;
8208 }
8209 clientProxy->OnSensorRotationChanged(screenId, sensorRotation);
8210 }
8211
OnHoverStatusChange(int32_t hoverStatus,bool needRotate,ScreenId screenId)8212 void ScreenSessionManager::OnHoverStatusChange(int32_t hoverStatus, bool needRotate, ScreenId screenId)
8213 {
8214 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " hoverStatus: %{public}d", screenId, hoverStatus);
8215 auto clientProxy = GetClientProxy();
8216 if (!clientProxy) {
8217 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8218 return;
8219 }
8220 clientProxy->OnHoverStatusChanged(screenId, hoverStatus, needRotate);
8221 }
8222
OnScreenOrientationChange(float screenOrientation,ScreenId screenId)8223 void ScreenSessionManager::OnScreenOrientationChange(float screenOrientation, ScreenId screenId)
8224 {
8225 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " screenOrientation: %{public}f", screenId, screenOrientation);
8226 auto clientProxy = GetClientProxy();
8227 if (!clientProxy) {
8228 TLOGI(WmsLogTag::DMS, "ClientProxy_ is null");
8229 return;
8230 }
8231 clientProxy->OnScreenOrientationChanged(screenId, screenOrientation);
8232 }
8233
OnScreenRotationLockedChange(bool isLocked,ScreenId screenId)8234 void ScreenSessionManager::OnScreenRotationLockedChange(bool isLocked, ScreenId screenId)
8235 {
8236 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " isLocked: %{public}d", screenId, isLocked);
8237 auto clientProxy = GetClientProxy();
8238 if (!clientProxy) {
8239 TLOGI(WmsLogTag::DMS, "ClientProxy_ is null");
8240 return;
8241 }
8242 clientProxy->OnScreenRotationLockedChanged(screenId, isLocked);
8243 }
8244
OnCameraBackSelfieChange(bool isCameraBackSelfie,ScreenId screenId)8245 void ScreenSessionManager::OnCameraBackSelfieChange(bool isCameraBackSelfie, ScreenId screenId)
8246 {
8247 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " isCameraBackSelfie: %{public}d", screenId, isCameraBackSelfie);
8248 auto clientProxy = GetClientProxy();
8249 if (!clientProxy) {
8250 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
8251 return;
8252 }
8253 clientProxy->OnCameraBackSelfieChanged(screenId, isCameraBackSelfie);
8254 }
8255
NotifyClientProxyUpdateFoldDisplayMode(FoldDisplayMode displayMode)8256 void ScreenSessionManager::NotifyClientProxyUpdateFoldDisplayMode(FoldDisplayMode displayMode)
8257 {
8258 auto clientProxy = GetClientProxy();
8259 if (clientProxy) {
8260 TLOGI(WmsLogTag::DMS, "displayMode = %{public}d",
8261 static_cast<int>(displayMode));
8262 clientProxy->OnUpdateFoldDisplayMode(displayMode);
8263 }
8264 }
8265
ScbClientDeathCallback(int32_t deathScbPid)8266 void ScreenSessionManager::ScbClientDeathCallback(int32_t deathScbPid)
8267 {
8268 std::unique_lock<std::mutex> lock(oldScbPidsMutex_);
8269 if (deathScbPid == currentScbPId_ || currentScbPId_ == INVALID_SCB_PID) {
8270 SetClientProxy(nullptr);
8271 TLOGE(WmsLogTag::DMS, "death callback and set clientProxy null");
8272 }
8273 if (scbSwitchCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_SCBSWITCH_MS))
8274 == std::cv_status::timeout) {
8275 TLOGE(WmsLogTag::DMS, "set client task deathScbPid:%{public}d, timeout: %{public}d",
8276 deathScbPid, CV_WAIT_SCBSWITCH_MS);
8277 }
8278 std::ostringstream oss;
8279 oss << "Scb client death: " << deathScbPid;
8280 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
8281 screenEventTracker_.RecordEvent(oss.str());
8282 oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), deathScbPid), oldScbPids_.end());
8283 }
8284
AddScbClientDeathRecipient(const sptr<IScreenSessionManagerClient> & scbClient,int32_t scbPid)8285 void ScreenSessionManager::AddScbClientDeathRecipient(const sptr<IScreenSessionManagerClient>& scbClient,
8286 int32_t scbPid)
8287 {
8288 sptr<ScbClientListenerDeathRecipient> scbClientDeathListener =
8289 new (std::nothrow) ScbClientListenerDeathRecipient(scbPid);
8290 if (scbClientDeathListener == nullptr) {
8291 TLOGE(WmsLogTag::DMS, "add scb: %{public}d death listener failed", scbPid);
8292 return;
8293 }
8294 if (scbClient != nullptr && scbClient->AsObject() != nullptr) {
8295 TLOGI(WmsLogTag::DMS, "add scb: %{public}d death listener", scbPid);
8296 scbClient->AsObject()->AddDeathRecipient(scbClientDeathListener);
8297 }
8298 }
8299
SwitchUser()8300 void ScreenSessionManager::SwitchUser()
8301 {
8302 #ifdef WM_MULTI_USR_ABILITY_ENABLE
8303 if (!SessionPermission::IsSystemCalling()) {
8304 TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
8305 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8306 return;
8307 }
8308 auto userId = GetUserIdByCallingUid();
8309 auto newScbPid = IPCSkeleton::GetCallingPid();
8310 currentUserIdForSettings_ = userId;
8311 if (g_isPcDevice && userSwitching_) {
8312 std::unique_lock<std::mutex> lock(switchUserMutex_);
8313 if (switchUserCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_USERSWITCH_MS)) == std::cv_status::timeout) {
8314 TLOGI(WmsLogTag::DMS, "wait switchUserCV_ timeout");
8315 userSwitching_ = false;
8316 }
8317 }
8318 SwitchScbNodeHandle(userId, newScbPid, false);
8319 MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, GetDefaultScreenId(), false);
8320 #endif
8321 }
8322
SetDefaultMultiScreenModeWhenSwitchUser()8323 void ScreenSessionManager::SetDefaultMultiScreenModeWhenSwitchUser()
8324 {
8325 if (!SessionPermission::IsSystemCalling()) {
8326 TLOGE(WmsLogTag::DMS, "permission denied!");
8327 return;
8328 }
8329 TLOGI(WmsLogTag::DMS, "switching user, change screen mode.");
8330 if (!g_isPcDevice) {
8331 TLOGW(WmsLogTag::DMS, "not pc device");
8332 return;
8333 }
8334 #ifdef WM_MULTI_USR_ABILITY_ENABLE
8335 sptr<ScreenSession> innerSession = nullptr;
8336 sptr<ScreenSession> externalSession = nullptr;
8337 GetInternalAndExternalSession(innerSession, externalSession);
8338 if (!innerSession || !externalSession) {
8339 TLOGE(WmsLogTag::DMS, "screen session is null.");
8340 return;
8341 }
8342 userSwitching_ = true;
8343 std::ostringstream oss;
8344 oss << "innerScreen screenId: " << innerSession->GetScreenId()
8345 << ", rsId: " << innerSession->GetRSScreenId()
8346 << ", externalScreen screenId: " << externalSession->GetScreenId()
8347 << ", rsId: " << externalSession->GetRSScreenId();
8348 oss << std::endl;
8349 TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
8350 if (externalSession->GetScreenCombination() != ScreenCombination::SCREEN_MIRROR) {
8351 if (GetIsOuterOnlyMode()) {
8352 TLOGI(WmsLogTag::DMS, "exit outer only mode.");
8353 SetIsOuterOnlyMode(false);
8354 ExitOuterOnlyMode(innerSession->GetRSScreenId(), externalSession->GetRSScreenId(),
8355 MultiScreenMode::SCREEN_MIRROR);
8356 switchUserCV_.notify_all();
8357 userSwitching_ = false;
8358 } else {
8359 TLOGI(WmsLogTag::DMS, "change to mirror.");
8360 SetIsOuterOnlyMode(false);
8361 MultiScreenModeChange(innerSession->GetRSScreenId(), externalSession->GetRSScreenId(), SCREEN_MIRROR);
8362 }
8363 } else {
8364 TLOGI(WmsLogTag::DMS, "already mirror.");
8365 switchUserCV_.notify_all();
8366 userSwitching_ = false;
8367 }
8368 #endif
8369 }
8370
ScbStatusRecoveryWhenSwitchUser(std::vector<int32_t> oldScbPids,int32_t newScbPid)8371 void ScreenSessionManager::ScbStatusRecoveryWhenSwitchUser(std::vector<int32_t> oldScbPids, int32_t newScbPid)
8372 {
8373 #ifdef WM_MULTI_USR_ABILITY_ENABLE
8374 sptr<ScreenSession> screenSession = GetDefaultScreenSession();
8375 if (screenSession == nullptr) {
8376 TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
8377 return;
8378 }
8379 if (g_foldScreenFlag) {
8380 NotifyFoldStatusChanged(GetFoldStatus());
8381 NotifyDisplayModeChanged(GetFoldDisplayMode());
8382 }
8383 int64_t delayTime = 0;
8384 if (g_foldScreenFlag && oldScbDisplayMode_ != GetFoldDisplayMode() &&
8385 !FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
8386 delayTime = SWITCH_USER_DISPLAYMODE_CHANGE_DELAY;
8387 auto foldStatus = GetFoldStatus();
8388 TLOGE(WmsLogTag::DMS, "old mode: %{public}u, cur mode: %{public}u", oldScbDisplayMode_, GetFoldDisplayMode());
8389 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
8390 screenSession->UpdatePropertyByFoldControl(screenSession->GetScreenProperty());
8391 OnVerticalChangeBoundsWhenSwitchUser(screenSession);
8392 screenSession->PropertyChange(screenSession->GetScreenProperty(),
8393 FoldDisplayMode::MAIN == GetFoldDisplayMode() ? ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING :
8394 ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
8395 } else if (foldStatus == FoldStatus::EXPAND || foldStatus == FoldStatus::HALF_FOLD) {
8396 screenSession->UpdatePropertyByFoldControl(GetPhyScreenProperty(SCREEN_ID_FULL));
8397 OnBeforeScreenPropertyChange(foldStatus);
8398 screenSession->PropertyChange(screenSession->GetScreenProperty(),
8399 ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
8400 } else if (foldStatus == FoldStatus::FOLDED) {
8401 screenSession->UpdatePropertyByFoldControl(GetPhyScreenProperty(SCREEN_ID_MAIN));
8402 OnBeforeScreenPropertyChange(foldStatus);
8403 screenSession->PropertyChange(screenSession->GetScreenProperty(),
8404 ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING);
8405 } else {
8406 TLOGE(WmsLogTag::DMS, "unsupport foldStatus: %{public}u", foldStatus);
8407 }
8408 } else {
8409 screenSession->UpdateValidRotationToScb();
8410 }
8411 auto task = [=] {
8412 auto clientProxy = GetClientProxy();
8413 if (!clientProxy) {
8414 TLOGNE(WmsLogTag::DMS, "ScbStatusRecoveryWhenSwitchUser clientProxy_ is null");
8415 return;
8416 }
8417 clientProxy->SwitchUserCallback(oldScbPids, newScbPid);
8418 RecoverMultiScreenModeWhenSwitchUser(oldScbPids, newScbPid);
8419 };
8420 taskScheduler_->PostAsyncTask(task, "clientProxy_ SwitchUserCallback task", delayTime);
8421 #endif
8422 }
8423
OnVerticalChangeBoundsWhenSwitchUser(sptr<ScreenSession> screenSession)8424 void ScreenSessionManager::OnVerticalChangeBoundsWhenSwitchUser(sptr<ScreenSession> screenSession)
8425 {
8426 if (screenSession == nullptr) {
8427 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
8428 return;
8429 }
8430 auto rotation = screenSession->GetScreenProperty().GetRotation();
8431 if (std::fabs(rotation - SECONDARY_ROTATION_90) < FLT_EPSILON ||
8432 std::fabs(rotation - SECONDARY_ROTATION_270) < FLT_EPSILON ) {
8433 const RRect& bounds = screenSession->GetScreenProperty().GetBounds();
8434 RRect afterBounds =
8435 RRect({ 0, bounds.rect_.GetTop(), bounds.rect_.GetHeight(), bounds.rect_.GetWidth()}, 0.0f, 0.0f);
8436 screenSession->SetBounds(afterBounds);
8437 TLOGI(WmsLogTag::DMS, "before width:%{public}f, height:%{public}f,after width:%{public}f, height:%{public}f",
8438 bounds.rect_.GetWidth(), bounds.rect_.GetHeight(),
8439 afterBounds.rect_.GetWidth(), afterBounds.rect_.GetHeight());
8440 }
8441 }
8442
RecoverMultiScreenModeWhenSwitchUser(std::vector<int32_t> oldScbPids,int32_t newScbPid)8443 void ScreenSessionManager::RecoverMultiScreenModeWhenSwitchUser(std::vector<int32_t> oldScbPids, int32_t newScbPid)
8444 {
8445 if (!g_isPcDevice) {
8446 TLOGI(WmsLogTag::DMS, "not PC device, return before recover.");
8447 return;
8448 }
8449 bool extendScreenConnected = false;
8450 ScreenId extendScreenId = SCREEN_ID_INVALID;
8451 std::map<ScreenId, sptr<ScreenSession>> screenSessionMap;
8452 {
8453 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8454 screenSessionMap = screenSessionMap_;
8455 }
8456 for (const auto& [screenId, screenSession] : screenSessionMap) {
8457 if (screenSession == nullptr) {
8458 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
8459 continue;
8460 }
8461 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
8462 screenSession->GetIsExtend()) {
8463 TLOGI(WmsLogTag::DMS, "recover extend screen, screenId = %{public}" PRIu64, screenId);
8464 extendScreenConnected = true;
8465 extendScreenId = screenId;
8466 RecoverMultiScreenMode(screenSession);
8467 FlushDisplayNodeWhenSwtichUser(oldScbPids, newScbPid, screenSession);
8468 } else if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
8469 !screenSession->GetIsExtend()) {
8470 SetExtendedScreenFallbackPlan(screenId);
8471 }
8472 }
8473 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
8474 if (extendScreenConnected) {
8475 OnExtendScreenConnectStatusChange(extendScreenId, ExtendScreenConnectStatus::CONNECT);
8476 } else {
8477 OnExtendScreenConnectStatusChange(extendScreenId, ExtendScreenConnectStatus::DISCONNECT);
8478 }
8479 }
8480 }
8481
FlushDisplayNodeWhenSwtichUser(std::vector<int32_t> oldScbPids,int32_t newScbPid,sptr<ScreenSession> screenSession)8482 void ScreenSessionManager::FlushDisplayNodeWhenSwtichUser(std::vector<int32_t> oldScbPids, int32_t newScbPid,
8483 sptr<ScreenSession> screenSession)
8484 {
8485 {
8486 auto displayNode = screenSession->GetDisplayNode();
8487 if (displayNode == nullptr) {
8488 TLOGE(WmsLogTag::DMS, "display node is null");
8489 return;
8490 }
8491 displayNode->SetScbNodePid(oldScbPids, newScbPid);
8492 }
8493 RSTransactionAdapter::FlushImplicitTransaction(screenSession->GetRSUIContext());
8494 }
8495
HandleSwitchPcMode()8496 bool ScreenSessionManager::HandleSwitchPcMode()
8497 {
8498 if (!IS_SUPPORT_PC_MODE) {
8499 return g_isPcDevice;
8500 }
8501 std::lock_guard<std::mutex> lock(pcModeSwitchMutex_);
8502 if (system::GetBoolParameter(IS_PC_MODE_KEY, false)) {
8503 TLOGI(WmsLogTag::DMS, "PcMode change isPcDevice true");
8504 g_isPcDevice = true;
8505 SwitchModeHandleExternalScreen(true);
8506 #ifdef WM_MULTI_SCREEN_CTL_ABILITY_ENABLE
8507 SetMultiScreenFrameControl();
8508 #endif
8509 } else {
8510 TLOGI(WmsLogTag::DMS, "PadMode change isPcDevice false");
8511 g_isPcDevice = false;
8512 SwitchModeHandleExternalScreen(false);
8513 #ifdef WM_MULTI_SCREEN_CTL_ABILITY_ENABLE
8514 TLOGI(WmsLogTag::DMS, "Disable frame rate control");
8515 EventInfo event = { "VOTER_MUTIPHYSICALSCREEN", REMOVE_VOTE };
8516 rsInterface_.NotifyRefreshRateEvent(event);
8517 #endif
8518 }
8519 return g_isPcDevice;
8520 }
8521
SwitchModeHandleExternalScreen(bool isSwitchToPcMode)8522 void ScreenSessionManager::SwitchModeHandleExternalScreen(bool isSwitchToPcMode)
8523 {
8524 std::ostringstream oss;
8525 std::vector<ScreenId> externalScreenIds;
8526 bool hasExternalScreen = false;
8527 {
8528 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8529 for (const auto& iter : screenSessionMap_) {
8530 auto screenSession = iter.second;
8531 if (screenSession == nullptr) {
8532 continue;
8533 }
8534 if (IsDefaultMirrorMode(screenSession->GetScreenId()) && screenSession->GetIsRealScreen()) {
8535 externalScreenIds.emplace_back(screenSession->GetScreenId());
8536 hasExternalScreen = true;
8537 screenSession->SetName(isSwitchToPcMode ? SCREEN_NAME_EXTEND : SCREEN_NAME_CAST);
8538 screenSession->SetVirtualScreenFlag(isSwitchToPcMode ?
8539 VirtualScreenFlag::DEFAULT : VirtualScreenFlag::CAST);
8540 oss << screenSession->GetScreenId() << ",";
8541 }
8542 }
8543 }
8544 TLOGI(WmsLogTag::DMS, "screenIds:%{public}s", oss.str().c_str());
8545 if (hasExternalScreen && !isSwitchToPcMode) {
8546 ScreenId screenGroupId = SCREEN_GROUP_ID_DEFAULT;
8547 MakeMirror(SCREEN_ID_DEFAULT, externalScreenIds, screenGroupId);
8548 TLOGI(WmsLogTag::DMS, "notify cast screen connect");
8549 NotifyCastWhenScreenConnectChange(true);
8550 }
8551 }
8552
SetClient(const sptr<IScreenSessionManagerClient> & client)8553 void ScreenSessionManager::SetClient(const sptr<IScreenSessionManagerClient>& client)
8554 {
8555 if (!SessionPermission::IsSystemCalling()) {
8556 TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
8557 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8558 return;
8559 }
8560 if (!client) {
8561 TLOGE(WmsLogTag::DMS, "SetClient client is null");
8562 return;
8563 }
8564 HandleSwitchPcMode();
8565 if (g_isPcDevice && userSwitching_) {
8566 std::unique_lock<std::mutex> lock(switchUserMutex_);
8567 if (switchUserCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_USERSWITCH_MS)) == std::cv_status::timeout) {
8568 TLOGW(WmsLogTag::DMS, "wait switchUserCV_ timeout");
8569 userSwitching_ = false;
8570 }
8571 }
8572 SetClientProxy(client);
8573 auto userId = GetUserIdByCallingUid();
8574 auto newScbPid = IPCSkeleton::GetCallingPid();
8575
8576 std::ostringstream oss;
8577 oss << "set client userId: " << userId
8578 << " clientName: " << SysCapUtil::GetClientName();
8579 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
8580 screenEventTracker_.RecordEvent(oss.str());
8581 currentUserIdForSettings_ = userId;
8582 MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, GetDefaultScreenId(), true);
8583 NotifyClientProxyUpdateFoldDisplayMode(GetFoldDisplayMode());
8584 SetClientInner();
8585 SwitchScbNodeHandle(userId, newScbPid, true);
8586 AddScbClientDeathRecipient(client, newScbPid);
8587
8588 static bool isNeedSwitchScreen = FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() ||
8589 FoldScreenStateInternel::IsSingleDisplayFoldDevice();
8590 if (isNeedSwitchScreen) {
8591 FoldDisplayMode displayMode = GetFoldDisplayMode();
8592 if (displayMode == FoldDisplayMode::FULL) {
8593 TLOGI(WmsLogTag::DMS, "switch screen to full");
8594 SetDisplayNodeScreenId(SCREEN_ID_FULL, SCREEN_ID_FULL);
8595 } else if (displayMode == FoldDisplayMode::MAIN) {
8596 TLOGI(WmsLogTag::DMS, "switch screen to main");
8597 SetDisplayNodeScreenId(SCREEN_ID_FULL, SCREEN_ID_MAIN);
8598 }
8599 }
8600 }
8601
SwitchScbNodeHandle(int32_t newUserId,int32_t newScbPid,bool coldBoot)8602 void ScreenSessionManager::SwitchScbNodeHandle(int32_t newUserId, int32_t newScbPid, bool coldBoot)
8603 {
8604 #ifdef WM_MULTI_USR_ABILITY_ENABLE
8605 std::ostringstream oss;
8606 oss << "currentUserId: " << currentUserId_
8607 << " currentScbPId: " << currentScbPId_
8608 << " newUserId: " << newUserId
8609 << " newScbPid: " << newScbPid
8610 << " coldBoot: " << static_cast<int32_t>(coldBoot);
8611 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
8612 screenEventTracker_.RecordEvent(oss.str());
8613
8614 std::unique_lock<std::mutex> lock(oldScbPidsMutex_);
8615 if (currentScbPId_ != INVALID_SCB_PID) {
8616 auto pidIter = std::find(oldScbPids_.begin(), oldScbPids_.end(), currentScbPId_);
8617 if (pidIter == oldScbPids_.end() && currentScbPId_ > 0) {
8618 oldScbPids_.emplace_back(currentScbPId_);
8619 }
8620 oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), newScbPid), oldScbPids_.end());
8621 if (oldScbPids_.size() == 0) {
8622 TLOGE(WmsLogTag::DMS, "swicth user failed, oldScbPids is null");
8623 screenEventTracker_.RecordEvent("swicth user failed, oldScbPids is null");
8624 }
8625 }
8626 auto clientProxy = GetClientProxy();
8627 if (!clientProxy) {
8628 TLOGE(WmsLogTag::DMS, "clientProxy is null");
8629 return;
8630 }
8631 if (coldBoot) {
8632 clientProxy->SwitchUserCallback(oldScbPids_, newScbPid);
8633 clientProxyMap_[newUserId] = clientProxy;
8634 } else {
8635 HotSwitch(newUserId, newScbPid);
8636 }
8637 UpdateDisplayScaleState(GetDefaultScreenId());
8638 currentUserId_ = newUserId;
8639 currentScbPId_ = newScbPid;
8640 scbSwitchCV_.notify_all();
8641 oldScbDisplayMode_ = GetFoldDisplayMode();
8642 #endif
8643 }
8644
NotifyCastWhenSwitchScbNode()8645 void ScreenSessionManager::NotifyCastWhenSwitchScbNode()
8646 {
8647 std::map<ScreenId, sptr<ScreenSession>> screenSessionMapCopy;
8648 {
8649 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8650 screenSessionMapCopy = screenSessionMap_;
8651 }
8652 for (const auto& sessionIt : screenSessionMapCopy) {
8653 auto screenSession = sessionIt.second;
8654 if (screenSession == nullptr) {
8655 TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first);
8656 continue;
8657 }
8658 if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL ||
8659 !IsDefaultMirrorMode(screenSession->GetScreenId())) {
8660 TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"", sessionIt.first);
8661 continue;
8662 }
8663 bool isScreenMirror = screenSession ->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR;
8664 NotifyCastWhenScreenConnectChange(isScreenMirror);
8665 return;
8666 }
8667 }
8668
HotSwitch(int32_t newUserId,int32_t newScbPid)8669 void ScreenSessionManager::HotSwitch(int32_t newUserId, int32_t newScbPid)
8670 {
8671 // hot switch
8672 if (clientProxyMap_.count(newUserId) == 0) {
8673 TLOGE(WmsLogTag::DMS, "not found client proxy. userId:%{public}d.", newUserId);
8674 return;
8675 }
8676 if (newUserId == currentUserId_) {
8677 TLOGI(WmsLogTag::DMS, "switch user not change");
8678 return;
8679 }
8680 if (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
8681 // Delete the screen whose ID is 5 generated by Coordination before switching the private space.
8682 SessionOption option = {
8683 .screenId_ = SCREEN_ID_MAIN,
8684 };
8685 auto clientProxy = GetClientProxy();
8686 if (clientProxy) {
8687 clientProxy->OnScreenConnectionChanged(option, ScreenEvent::DISCONNECTED);
8688 }
8689 }
8690 SetClientProxy(clientProxyMap_[newUserId]);
8691 ScbStatusRecoveryWhenSwitchUser(oldScbPids_, newScbPid);
8692 }
8693
GetCurrentUserId()8694 int32_t ScreenSessionManager::GetCurrentUserId()
8695 {
8696 return currentUserIdForSettings_;
8697 }
8698
SetClientInner()8699 void ScreenSessionManager::SetClientInner()
8700 {
8701 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
8702 for (const auto& iter : screenSessionMap_) {
8703 if (!iter.second) {
8704 continue;
8705 }
8706 // In the rotating state, after scb restarts, the screen information needs to be reset.
8707 float phyWidth = 0.0f;
8708 float phyHeight = 0.0f;
8709 bool isReset = true;
8710 int boundaryOffset = 0;
8711 GetCurrentScreenPhyBounds(phyWidth, phyHeight, isReset, iter.first);
8712 auto localRotation = iter.second->GetRotation();
8713 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
8714 FoldDisplayMode displayMode = GetFoldDisplayMode();
8715 if (displayMode == FoldDisplayMode::FULL) {
8716 boundaryOffset = SECONDARY_FULL_OFFSET;
8717 phyWidth = SECONDARY_FULL_STATUS_WIDTH;
8718 } else if (displayMode == FoldDisplayMode::MAIN) {
8719 phyWidth = MAIN_STATUS_DEFAULT_WIDTH;
8720 phyHeight = SCREEN_DEFAULT_HEIGHT;
8721 }
8722 }
8723 TLOGI(WmsLogTag::DMS, "phyWidth = :%{public}f, phyHeight = :%{public}f, localRotation = :%{public}u",
8724 phyWidth, phyHeight, localRotation);
8725 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
8726 bool isModeChanged = localRotation != Rotation::ROTATION_0;
8727 if (isModeChanged && isReset) {
8728 TLOGI(WmsLogTag::DMS, "screen(id:%{public}" PRIu64 ") current is not default mode, reset it",
8729 iter.first);
8730 SetRotation(iter.first, Rotation::ROTATION_0, false);
8731 SetPhysicalRotationClientInner(iter.first, 0);
8732 iter.second->SetDisplayBoundary(RectF(0, boundaryOffset, phyWidth, phyHeight), 0);
8733 }
8734 }
8735 auto clientProxy = GetClientProxy();
8736 if (!clientProxy) {
8737 TLOGE(WmsLogTag::DMS, "clientProxy is null");
8738 return;
8739 }
8740 if (iter.second->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
8741 TLOGI(WmsLogTag::DMS, "current screen is extend and mirror, return before OnScreenConnectionChanged");
8742 RecoverMultiScreenMode(iter.second);
8743 continue;
8744 }
8745 clientProxy->OnScreenConnectionChanged(GetSessionOption(iter.second, iter.first),
8746 ScreenEvent::CONNECTED);
8747 RecoverMultiScreenMode(iter.second);
8748 }
8749 }
8750
SetPhysicalRotationClientInner(ScreenId screenId,int rotation)8751 void ScreenSessionManager::SetPhysicalRotationClientInner(ScreenId screenId, int rotation)
8752 {
8753 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
8754 if (screenSession == nullptr) {
8755 TLOGE(WmsLogTag::DMS, "fail, cannot find screen %{public}" PRIu64"",
8756 screenId);
8757 return;
8758 }
8759 screenSession->SetPhysicalRotation(rotation);
8760 screenSession->SetScreenComponentRotation(rotation);
8761 TLOGI(WmsLogTag::DMS, "SetPhysicalRotationClientInner end");
8762 }
8763
RecoverDefaultScreenModeInner(ScreenId innerRsId,ScreenId externalRsId)8764 void ScreenSessionManager::RecoverDefaultScreenModeInner(ScreenId innerRsId, ScreenId externalRsId)
8765 {
8766 #ifdef FOLD_ABILITY_ENABLE
8767 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
8768 SuperFoldStateManager::GetInstance().GetCurrentStatus() != SuperFoldStatus::EXPANDED) {
8769 SetMultiScreenMode(innerRsId, externalRsId, MultiScreenMode::SCREEN_MIRROR);
8770 ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_MIRROR);
8771 } else {
8772 #endif
8773 SetMultiScreenMode(innerRsId, externalRsId, MultiScreenMode::SCREEN_EXTEND);
8774 ReportHandleScreenEvent(ScreenEvent::CONNECTED, ScreenCombination::SCREEN_EXTEND);
8775 #ifdef FOLD_ABILITY_ENABLE
8776 }
8777 #endif
8778 }
8779
RecoverMultiScreenMode(sptr<ScreenSession> screenSession)8780 void ScreenSessionManager::RecoverMultiScreenMode(sptr<ScreenSession> screenSession)
8781 {
8782 if (screenSession == nullptr) {
8783 TLOGE(WmsLogTag::DMS, "screenSession is null!");
8784 return;
8785 }
8786 if (!g_isPcDevice || screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL) {
8787 TLOGI(WmsLogTag::DMS, "not PC or not real screen, no need recover!");
8788 return;
8789 }
8790 if (isDeviceShutDown_) {
8791 TLOGI(WmsLogTag::DMS, "device shut down, no need recover!");
8792 return;
8793 }
8794 sptr<ScreenSession> internalSession = GetInternalScreenSession();
8795 if (!RecoverRestoredMultiScreenMode(screenSession)) {
8796 if (internalSession == nullptr) {
8797 TLOGE(WmsLogTag::DMS, "internalSession is nullptr");
8798 return;
8799 }
8800 ScreenId innerRsId = internalSession->GetRSScreenId();
8801 ScreenId externalRsId = screenSession->GetRSScreenId();
8802 if (innerRsId == externalRsId) {
8803 TLOGW(WmsLogTag::DMS, "same rsId: %{public}" PRIu64, innerRsId);
8804 return;
8805 }
8806 RecoverDefaultScreenModeInner(innerRsId, externalRsId);
8807 SetMultiScreenDefaultRelativePosition();
8808 }
8809 sptr<ScreenSession> newInternalSession = GetInternalScreenSession();
8810 if (newInternalSession != nullptr && internalSession != nullptr &&
8811 internalSession->GetScreenId() != newInternalSession->GetScreenId()) {
8812 TLOGW(WmsLogTag::DMS, "main screen changed, reset screenSession.");
8813 screenSession = internalSession;
8814 }
8815 SetExtendedScreenFallbackPlan(screenSession->GetScreenId());
8816 if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
8817 screenSession->PropertyChange(screenSession->GetScreenProperty(), ScreenPropertyChangeReason::UNDEFINED);
8818 }
8819 }
8820
GetCurrentScreenPhyBounds(float & phyWidth,float & phyHeight,bool & isReset,const ScreenId & screenid)8821 void ScreenSessionManager::GetCurrentScreenPhyBounds(float& phyWidth, float& phyHeight,
8822 bool& isReset, const ScreenId& screenid)
8823 {
8824 #ifdef FOLD_ABILITY_ENABLE
8825 if (foldScreenController_ != nullptr) {
8826 FoldDisplayMode displayMode = GetFoldDisplayMode();
8827 TLOGI(WmsLogTag::DMS, "fold screen with displayMode = %{public}u", displayMode);
8828 if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
8829 auto phyBounds = GetPhyScreenProperty(screenid).GetPhyBounds();
8830 phyWidth = phyBounds.rect_.width_;
8831 phyHeight = phyBounds.rect_.height_;
8832 if (displayMode == FoldDisplayMode::UNKNOWN) {
8833 isReset = false;
8834 }
8835 return;
8836 }
8837 if (displayMode == FoldDisplayMode::MAIN) {
8838 auto phyBounds = GetPhyScreenProperty(SCREEN_ID_MAIN).GetPhyBounds();
8839 phyWidth = phyBounds.rect_.width_;
8840 phyHeight = phyBounds.rect_.height_;
8841 } else if (displayMode == FoldDisplayMode::FULL || displayMode == FoldDisplayMode::GLOBAL_FULL) {
8842 auto phyBounds = GetPhyScreenProperty(SCREEN_ID_FULL).GetPhyBounds();
8843 phyWidth = phyBounds.rect_.width_;
8844 phyHeight = phyBounds.rect_.height_;
8845 if (g_screenRotationOffSet == ROTATION_90 || g_screenRotationOffSet == ROTATION_270) {
8846 std::swap(phyWidth, phyHeight);
8847 }
8848 } else {
8849 isReset = false;
8850 }
8851 return;
8852 }
8853 #endif
8854 int id = HiviewDFX::XCollie::GetInstance().SetTimer("GetCurrentScreenPhyBounds", XCOLLIE_TIMEOUT_10S, nullptr,
8855 nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
8856 auto remoteScreenMode = rsInterface_.GetScreenActiveMode(screenid);
8857 HiviewDFX::XCollie::GetInstance().CancelTimer(id);
8858 phyWidth = remoteScreenMode.GetScreenWidth();
8859 phyHeight = remoteScreenMode.GetScreenHeight();
8860 }
8861
GetScreenProperty(ScreenId screenId)8862 ScreenProperty ScreenSessionManager::GetScreenProperty(ScreenId screenId)
8863 {
8864 if (!SessionPermission::IsSystemCalling()) {
8865 TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
8866 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8867 return {};
8868 }
8869 DmsXcollie dmsXcollie("DMS:GetScreenProperty", XCOLLIE_TIMEOUT_10S);
8870 auto screenSession = GetScreenSession(screenId);
8871 if (!screenSession) {
8872 TLOGI(WmsLogTag::DMS, "screenSession is null");
8873 return {};
8874 }
8875 return screenSession->GetScreenProperty();
8876 }
8877
GetDisplayNode(ScreenId screenId)8878 std::shared_ptr<RSDisplayNode> ScreenSessionManager::GetDisplayNode(ScreenId screenId)
8879 {
8880 if (!SessionPermission::IsSystemCalling()) {
8881 TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
8882 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
8883 return nullptr;
8884 }
8885 DmsXcollie dmsXcollie("DMS:GetDisplayNode", XCOLLIE_TIMEOUT_10S);
8886 auto screenSession = GetScreenSession(screenId);
8887 if (!screenSession) {
8888 TLOGE(WmsLogTag::DMS, "screenSession is null");
8889 return nullptr;
8890 }
8891 return screenSession->GetDisplayNode();
8892 }
8893
GetScreenCombination(ScreenId screenId)8894 ScreenCombination ScreenSessionManager::GetScreenCombination(ScreenId screenId)
8895 {
8896 DmsXcollie dmsXcollie("DMS:GetScreenCombination", XCOLLIE_TIMEOUT_10S);
8897 auto screenSession = GetScreenSession(screenId);
8898 if (!screenSession) {
8899 TLOGI(WmsLogTag::DMS, "screenSession is null");
8900 return ScreenCombination::SCREEN_ALONE;
8901 }
8902 return screenSession->GetScreenCombination();
8903 }
8904
Dump(int fd,const std::vector<std::u16string> & args)8905 int ScreenSessionManager::Dump(int fd, const std::vector<std::u16string>& args)
8906 {
8907 TLOGI(WmsLogTag::DMS, "Dump begin");
8908 sptr<ScreenSessionDumper> dumper = new ScreenSessionDumper(fd, args);
8909 if (dumper == nullptr) {
8910 TLOGE(WmsLogTag::DMS, "dumper is nullptr");
8911 return -1;
8912 }
8913 {
8914 std::lock_guard<std::mutex> lock(freezedPidListMutex_);
8915 dumper->DumpFreezedPidList(freezedPidList_);
8916 }
8917 dumper->DumpEventTracker(screenEventTracker_);
8918 {
8919 std::lock_guard<std::mutex> lock(oldScbPidsMutex_);
8920 dumper->DumpMultiUserInfo(oldScbPids_, currentUserId_, currentScbPId_);
8921 }
8922 dumper->ExecuteDumpCmd();
8923 TLOGI(WmsLogTag::DMS, "dump end");
8924 return 0;
8925 }
8926
TriggerFoldStatusChange(FoldStatus foldStatus)8927 void ScreenSessionManager::TriggerFoldStatusChange(FoldStatus foldStatus)
8928 {
8929 #ifdef FOLD_ABILITY_ENABLE
8930 TLOGI(WmsLogTag::DMS, "enter foldStatus = %{public}d.", foldStatus);
8931 if (foldScreenController_ == nullptr) {
8932 return;
8933 }
8934 foldScreenController_->SetFoldStatus(foldStatus);
8935 FoldDisplayMode displayMode = foldScreenController_->GetModeMatchStatus();
8936 SetFoldDisplayMode(displayMode);
8937 NotifyFoldStatusChanged(foldStatus);
8938 #endif
8939 }
8940
NotifyFoldStatusChanged(const std::string & statusParam)8941 int ScreenSessionManager::NotifyFoldStatusChanged(const std::string& statusParam)
8942 {
8943 #ifdef FOLD_ABILITY_ENABLE
8944 TLOGI(WmsLogTag::DMS, "is dump log");
8945 if (statusParam.empty()) {
8946 return -1;
8947 }
8948 FoldStatus foldStatus = FoldStatus::UNKNOWN;
8949 FoldDisplayMode displayMode = FoldDisplayMode::UNKNOWN;
8950 if (statusParam == STATUS_FOLD_HALF) {
8951 foldStatus = FoldStatus::HALF_FOLD;
8952 displayMode = FoldDisplayMode::FULL;
8953 } else if (statusParam == STATUS_EXPAND) {
8954 foldStatus = FoldStatus::EXPAND;
8955 displayMode = FoldDisplayMode::FULL;
8956 } else if (statusParam == STATUS_FOLD) {
8957 foldStatus = FoldStatus::FOLDED;
8958 displayMode = FoldDisplayMode::MAIN;
8959 } else {
8960 TLOGW(WmsLogTag::DMS, "status not support");
8961 return -1;
8962 }
8963 SetFoldDisplayMode(displayMode);
8964 if (foldScreenController_ != nullptr) {
8965 foldScreenController_->SetFoldStatus(foldStatus);
8966 }
8967 NotifyFoldStatusChanged(foldStatus);
8968 #endif
8969 return 0;
8970 }
8971
NotifyAvailableAreaChanged(DMRect area,DisplayId displayId)8972 void ScreenSessionManager::NotifyAvailableAreaChanged(DMRect area, DisplayId displayId)
8973 {
8974 auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER);
8975 TLOGI(WmsLogTag::DMS, "entry, agent size: %{public}u", static_cast<uint32_t>(agents.size()));
8976 if (agents.empty()) {
8977 return;
8978 }
8979 TLOGI(WmsLogTag::DMS, "displayId: %{public}" PRIu64
8980 ", AvailableArea: [%{public}d, %{public}d, %{public}u, %{public}u]",
8981 static_cast<DisplayId>(displayId), area.posX_, area.posY_, area.width_, area.height_);
8982 for (auto& agent : agents) {
8983 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
8984 if (!IsFreezed(agentPid,
8985 DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER)) {
8986 agent->NotifyAvailableAreaChanged(area, displayId);
8987 }
8988 }
8989 }
8990
GetAvailableArea(DisplayId displayId,DMRect & area)8991 DMError ScreenSessionManager::GetAvailableArea(DisplayId displayId, DMRect& area)
8992 {
8993 auto displayInfo = GetDisplayInfoById(displayId);
8994 if (displayInfo == nullptr) {
8995 TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
8996 return DMError::DM_ERROR_NULLPTR;
8997 }
8998 sptr<ScreenSession> screenSession;
8999 if (displayId == DISPLAY_ID_FAKE) {
9000 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
9001 return DMError::DM_ERROR_NULLPTR;
9002 }
9003 ScreenId internalScreenId = GetInternalScreenId();
9004 sptr<ScreenSession> internalScreenSession = GetScreenSession(internalScreenId);
9005 if (internalScreenSession == nullptr) {
9006 TLOGE(WmsLogTag::DMS, "internal session is nullptr.");
9007 return DMError::DM_ERROR_NULLPTR;
9008 }
9009 if (!internalScreenSession->GetScreenProperty().GetIsFakeInUse()) {
9010 return DMError::DM_ERROR_NULLPTR;
9011 }
9012 screenSession = internalScreenSession->GetFakeScreenSession();
9013 } else {
9014 screenSession = GetScreenSession(displayInfo->GetScreenId());
9015 }
9016 if (screenSession == nullptr) {
9017 TLOGE(WmsLogTag::DMS, "can not get screen now");
9018 return DMError::DM_ERROR_NULLPTR;
9019 }
9020 area = screenSession->GetAvailableArea();
9021 return DMError::DM_OK;
9022 }
9023
GetExpandAvailableArea(DisplayId displayId,DMRect & area)9024 DMError ScreenSessionManager::GetExpandAvailableArea(DisplayId displayId, DMRect& area)
9025 {
9026 auto displayInfo = GetDisplayInfoById(displayId);
9027 if (displayInfo == nullptr) {
9028 TLOGE(WmsLogTag::DMS, "can not get displayInfo.");
9029 return DMError::DM_ERROR_NULLPTR;
9030 }
9031 sptr<ScreenSession> screenSession;
9032 screenSession = GetScreenSession(displayInfo->GetScreenId());
9033 if (screenSession == nullptr) {
9034 TLOGE(WmsLogTag::DMS, "can not get screen now");
9035 return DMError::DM_ERROR_NULLPTR;
9036 }
9037 area = screenSession->GetExpandAvailableArea();
9038 return DMError::DM_OK;
9039 }
9040
UpdateAvailableArea(ScreenId screenId,DMRect area)9041 void ScreenSessionManager::UpdateAvailableArea(ScreenId screenId, DMRect area)
9042 {
9043 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9044 TLOGE(WmsLogTag::DMS, "update available area permission denied!");
9045 return;
9046 }
9047 if (GetUserIdByCallingUid() != currentUserId_) {
9048 TLOGE(WmsLogTag::DMS, "not currentuser, calling uid:%{public}d, current uid:%{public}d",
9049 GetUserIdByCallingUid(), currentUserId_);
9050 return;
9051 }
9052 auto screenSession = GetScreenSession(screenId);
9053 if (screenSession == nullptr) {
9054 TLOGE(WmsLogTag::DMS, "can not get default screen now");
9055 return;
9056 }
9057 if (!screenSession->UpdateAvailableArea(area)) {
9058 return;
9059 }
9060 if (g_isPcDevice) {
9061 {
9062 std::unique_lock<std::mutex> lock(displayAddMutex_);
9063 if (needWaitAvailableArea_) {
9064 TLOGI(WmsLogTag::DMS, "need notify add display.");
9065 displayAddCV_.notify_all();
9066 needWaitAvailableArea_ = false;
9067 }
9068 }
9069 sptr<ScreenSession> physicalScreen = GetPhysicalScreenSession(screenSession->GetRSScreenId());
9070 if (physicalScreen) {
9071 physicalScreen->UpdateAvailableArea(area);
9072 }
9073 }
9074 NotifyAvailableAreaChanged(area, screenId);
9075 }
9076
UpdateSuperFoldAvailableArea(ScreenId screenId,DMRect bArea,DMRect cArea)9077 void ScreenSessionManager::UpdateSuperFoldAvailableArea(ScreenId screenId, DMRect bArea, DMRect cArea)
9078 {
9079 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9080 TLOGE(WmsLogTag::DMS, "update super fold available area permission denied!");
9081 return;
9082 }
9083
9084 auto screenSession = GetScreenSession(screenId);
9085 if (screenSession == nullptr) {
9086 TLOGE(WmsLogTag::DMS, "can not get default screen now");
9087 return;
9088 }
9089 if (screenSession->UpdateAvailableArea(bArea)) {
9090 if (g_isPcDevice) {
9091 sptr<ScreenSession> physicalScreen = GetPhysicalScreenSession(screenSession->GetRSScreenId());
9092 if (physicalScreen) {
9093 physicalScreen->UpdateAvailableArea(bArea);
9094 }
9095 }
9096 NotifyAvailableAreaChanged(bArea, screenId);
9097 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
9098 DisplayChangeEvent::SUPER_FOLD_AVAILABLE_AREA_UPDATE);
9099 }
9100 if (!screenSession->GetIsFakeInUse()) {
9101 TLOGE(WmsLogTag::DMS, "fake screen session is not in use");
9102 return;
9103 }
9104 auto fakeScreenSession = screenSession->GetFakeScreenSession();
9105 if (fakeScreenSession == nullptr) {
9106 TLOGE(WmsLogTag::DMS, "can not get fake screen now");
9107 return;
9108 }
9109 if (fakeScreenSession->UpdateAvailableArea(cArea) && cArea.width_ > 0) {
9110 NotifyAvailableAreaChanged(cArea, fakeScreenSession->GetScreenId());
9111 NotifyDisplayChanged(fakeScreenSession->ConvertToDisplayInfo(),
9112 DisplayChangeEvent::SUPER_FOLD_AVAILABLE_AREA_UPDATE);
9113 }
9114 }
9115
UpdateSuperFoldExpandAvailableArea(ScreenId screenId,DMRect area)9116 void ScreenSessionManager::UpdateSuperFoldExpandAvailableArea(ScreenId screenId, DMRect area)
9117 {
9118 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9119 TLOGE(WmsLogTag::DMS, "update super fold available area permission denied!");
9120 return;
9121 }
9122
9123 auto screenSession = GetScreenSession(screenId);
9124 if (screenSession == nullptr) {
9125 TLOGE(WmsLogTag::DMS, "can not get default screen now");
9126 return;
9127 }
9128 if (screenSession->UpdateExpandAvailableArea(area)) {
9129 TLOGI(WmsLogTag::DMS,
9130 "ExpandAvailableArea x: %{public}d, y: %{public}d, width: %{public}d, height: %{public}d",
9131 area.posX_, area.posY_, area.width_, area.height_);
9132 }
9133 if (g_isPcDevice) {
9134 sptr<ScreenSession> physicalScreen = GetPhysicalScreenSession(screenSession->GetRSScreenId());
9135 if (physicalScreen) {
9136 physicalScreen->UpdateExpandAvailableArea(area);
9137 }
9138 }
9139 }
9140
NotifyFoldToExpandCompletion(bool foldToExpand)9141 void ScreenSessionManager::NotifyFoldToExpandCompletion(bool foldToExpand)
9142 {
9143 #ifdef FOLD_ABILITY_ENABLE
9144 TLOGI(WmsLogTag::DMS, "ENTER");
9145 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9146 TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
9147 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
9148 return;
9149 }
9150 if (!FoldScreenStateInternel::IsDualDisplayFoldDevice() &&
9151 !FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
9152 !FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
9153 SetDisplayNodeScreenId(SCREEN_ID_FULL, foldToExpand ? SCREEN_ID_FULL : SCREEN_ID_MAIN);
9154 }
9155 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
9156 SetDisplayNodeScreenId(SCREEN_ID_FULL, SCREEN_ID_FULL);
9157 }
9158 /* Avoid fold to expand process queues */
9159 if (foldScreenController_ != nullptr) {
9160 foldScreenController_->SetdisplayModeChangeStatus(false);
9161 }
9162 sptr<ScreenSession> screenSession = GetDefaultScreenSession();
9163 if (screenSession == nullptr) {
9164 TLOGE(WmsLogTag::DMS, "fail to get default screenSession");
9165 return;
9166 }
9167 screenSession->UpdateRotationAfterBoot(foldToExpand);
9168 #endif
9169 }
9170
RecordEventFromScb(std::string description,bool needRecordEvent)9171 void ScreenSessionManager::RecordEventFromScb(std::string description, bool needRecordEvent)
9172 {
9173 TLOGD(WmsLogTag::DMS, "%{public}s", description.c_str());
9174 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9175 TLOGE(WmsLogTag::DMS, "permission denied, clientName: %{public}s, pid: %{public}d",
9176 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
9177 return;
9178 }
9179 if (needRecordEvent) {
9180 screenEventTracker_.RecordEvent(description);
9181 }
9182 }
9183
CheckAndSendHiSysEvent(const std::string & eventName,const std::string & bundleName) const9184 void ScreenSessionManager::CheckAndSendHiSysEvent(const std::string& eventName, const std::string& bundleName) const
9185 {
9186 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CheckAndSendHiSysEvent");
9187 if (eventName != "CREATE_VIRTUAL_SCREEN") {
9188 if (!Permission::CheckIsCallingBundleName(bundleName)) {
9189 TLOGD(WmsLogTag::DMS, "BundleName not in whitelist!");
9190 return;
9191 }
9192 }
9193 int32_t eventRet = HiSysEventWrite(
9194 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
9195 eventName, // CREATE_VIRTUAL_SCREEN, GET_DISPLAY_SNAPSHOT
9196 OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,
9197 "PID", getpid(),
9198 "UID", getuid());
9199 TLOGI(WmsLogTag::DMS, "%{public}s: Write HiSysEvent ret:%{public}d", eventName.c_str(), eventRet);
9200 }
9201
ProxyForFreeze(const std::set<int32_t> & pidList,bool isProxy)9202 DMError ScreenSessionManager::ProxyForFreeze(const std::set<int32_t>& pidList, bool isProxy)
9203 {
9204 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9205 TLOGE(WmsLogTag::DMS, "permission denied!");
9206 return DMError::DM_ERROR_NOT_SYSTEM_APP;
9207 }
9208 {
9209 std::lock_guard<std::mutex> lock(freezedPidListMutex_);
9210 for (auto pid : pidList) {
9211 if (isProxy) {
9212 freezedPidList_.insert(pid);
9213 } else {
9214 freezedPidList_.erase(pid); // set删除不存在的元素不会引发异常
9215 }
9216 }
9217 }
9218 if (isProxy) {
9219 return DMError::DM_OK;
9220 }
9221
9222 // 进程解冻时刷新一次displaychange
9223 sptr<ScreenSession> screenSession = GetScreenSession(GetDefaultScreenId());
9224 if (!screenSession) {
9225 return DMError::DM_ERROR_NULLPTR;
9226 }
9227 auto task = [=] {
9228 NotifyUnfreezed(pidList, screenSession);
9229 };
9230 taskScheduler_->PostAsyncTask(task, "ProxyForUnFreeze NotifyDisplayChanged");
9231 return DMError::DM_OK;
9232 }
9233
NotifyUnfreezedAgents(const int32_t & pid,const std::set<int32_t> & unfreezedPidList,const std::set<DisplayManagerAgentType> & pidAgentTypes,const sptr<ScreenSession> & screenSession)9234 void ScreenSessionManager::NotifyUnfreezedAgents(const int32_t& pid, const std::set<int32_t>& unfreezedPidList,
9235 const std::set<DisplayManagerAgentType>& pidAgentTypes, const sptr<ScreenSession>& screenSession)
9236 {
9237 bool isAgentTypeNotify = false;
9238 for (auto agentType : pidAgentTypes) {
9239 auto agents = dmAgentContainer_.GetAgentsByType(agentType);
9240 for (auto agent : agents) {
9241 int32_t agentPid = dmAgentContainer_.GetAgentPid(agent);
9242 if (agentPid != pid || unfreezedPidList.count(pid) == 0) {
9243 continue;
9244 }
9245 isAgentTypeNotify = true;
9246 if (agentType == DisplayManagerAgentType::DISPLAY_EVENT_LISTENER) {
9247 agent->OnDisplayChange(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_UNFREEZED);
9248 } else if (agentType == DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER) {
9249 FoldDisplayMode displayMode = GetFoldDisplayMode();
9250 agent->NotifyDisplayModeChanged(displayMode);
9251 } else if (agentType == DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER) {
9252 FoldStatus foldStatus = GetFoldStatus();
9253 agent->NotifyFoldStatusChanged(foldStatus);
9254 } else if (agentType == DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER) {
9255 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
9256 agent->NotifyFoldAngleChanged(lastFoldAngles_);
9257 } else if (agentType == DisplayManagerAgentType::SCREEN_EVENT_LISTENER) {
9258 auto displayInfo = screenSession->ConvertToDisplayInfo();
9259 auto screenInfo = GetScreenInfoById(displayInfo->GetScreenId());
9260 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
9261 agent->OnScreenChange(screenInfo, lastScreenChangeEvent_);
9262 } else if (agentType == DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER) {
9263 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
9264 agent->NotifyDisplayChangeInfoChanged(lastDisplayChangeInfo_);
9265 } else if (agentType == DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER) {
9266 auto area = screenSession->GetAvailableArea();
9267 auto displayId = screenSession->ConvertToDisplayInfo()->GetDisplayId();
9268 std::lock_guard<std::mutex> lock(lastStatusUpdateMutex_);
9269 agent->NotifyAvailableAreaChanged(area, displayId);
9270 } else {
9271 isAgentTypeNotify = false;
9272 TLOGI(WmsLogTag::DMS, "Unknown agentType.");
9273 }
9274 }
9275 if (isAgentTypeNotify) {
9276 pidAgentTypeMap_[pid].erase(agentType);
9277 }
9278 }
9279 }
9280
NotifyUnfreezed(const std::set<int32_t> & unfreezedPidList,const sptr<ScreenSession> & screenSession)9281 void ScreenSessionManager::NotifyUnfreezed(const std::set<int32_t>& unfreezedPidList,
9282 const sptr<ScreenSession>& screenSession)
9283 {
9284 std::lock_guard<std::mutex> lock(freezedPidListMutex_);
9285 std::ostringstream oss;
9286 oss << "pid,type:";
9287 for (auto iter = pidAgentTypeMap_.begin(); iter != pidAgentTypeMap_.end();) {
9288 int32_t pid = iter->first;
9289 auto pidAgentTypes = iter->second;
9290 NotifyUnfreezedAgents(pid, unfreezedPidList, pidAgentTypes, screenSession);
9291 if (pidAgentTypeMap_[pid].empty()) {
9292 iter = pidAgentTypeMap_.erase(iter);
9293 } else {
9294 iter++;
9295 }
9296 oss << pid << ",";
9297 for (auto type : pidAgentTypes) {
9298 oss << static_cast<int32_t>(type) << " ";
9299 }
9300 oss << "|";
9301 }
9302 TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
9303 }
9304
ResetAllFreezeStatus()9305 DMError ScreenSessionManager::ResetAllFreezeStatus()
9306 {
9307 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9308 TLOGE(WmsLogTag::DMS, "permission denied!");
9309 return DMError::DM_ERROR_NOT_SYSTEM_APP;
9310 }
9311 std::lock_guard<std::mutex> lock(freezedPidListMutex_);
9312 freezedPidList_.clear();
9313 pidAgentTypeMap_.clear();
9314 TLOGI(WmsLogTag::DMS, "freezedPidList_ has been clear.");
9315 return DMError::DM_OK;
9316 }
9317
GetDeviceScreenConfig()9318 DeviceScreenConfig ScreenSessionManager::GetDeviceScreenConfig()
9319 {
9320 DmsXcollie dmsXcollie("DMS:GetDeviceScreenConfig", XCOLLIE_TIMEOUT_10S);
9321 return deviceScreenConfig_;
9322 }
9323
RegisterApplicationStateObserver()9324 void ScreenSessionManager::RegisterApplicationStateObserver()
9325 {
9326 #if defined(SENSOR_ENABLE) && defined(FOLD_ABILITY_ENABLE)
9327 std::string identify = IPCSkeleton::ResetCallingIdentity();
9328 if (!FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
9329 FoldScreenSensorManager::GetInstance().RegisterApplicationStateObserver();
9330 }
9331 IPCSkeleton::SetCallingIdentity(identify);
9332 #endif
9333 }
9334
SetVirtualScreenBlackList(ScreenId screenId,std::vector<uint64_t> & windowIdList,std::vector<uint64_t> surfaceIdList,std::vector<uint8_t> typeBlackList)9335 void ScreenSessionManager::SetVirtualScreenBlackList(ScreenId screenId, std::vector<uint64_t>& windowIdList,
9336 std::vector<uint64_t> surfaceIdList, std::vector<uint8_t> typeBlackList)
9337 {
9338 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9339 TLOGE(WmsLogTag::DMS, "permission denied!");
9340 return;
9341 }
9342 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64, screenId);
9343 ScreenId rsScreenId = SCREEN_ID_INVALID;
9344 if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
9345 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
9346 return;
9347 }
9348 auto clientProxy = GetClientProxy();
9349 if (!clientProxy) {
9350 TLOGE(WmsLogTag::DMS, "clientProxy_ is nullptr");
9351 return;
9352 }
9353 if (windowIdList.empty()) {
9354 TLOGI(WmsLogTag::DMS, "WindowIdList is empty");
9355 clientProxy->OnSetSurfaceNodeIdsChanged(rsScreenId, surfaceIdList);
9356 rsInterface_.SetVirtualScreenTypeBlackList(rsScreenId, typeBlackList);
9357 return;
9358 }
9359 std::vector<uint64_t> surfaceNodeIdsToRS;
9360 clientProxy->OnGetSurfaceNodeIdsFromMissionIdsChanged(windowIdList, surfaceNodeIdsToRS, true);
9361 if (!surfaceIdList.empty()) {
9362 for (auto surfaceId : surfaceIdList) {
9363 auto it = std::find(surfaceNodeIdsToRS.begin(), surfaceNodeIdsToRS.end(), surfaceId);
9364 if (it != surfaceNodeIdsToRS.end()) {
9365 continue;
9366 }
9367 surfaceNodeIdsToRS.push_back(surfaceId);
9368 }
9369 }
9370 std::ostringstream oss;
9371 oss << "surfaceNodeIdsToRS[" << rsScreenId << "]: ";
9372 for (auto val : surfaceNodeIdsToRS) {
9373 oss << val << " ";
9374 }
9375 TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
9376 rsInterface_.SetVirtualScreenTypeBlackList(rsScreenId, typeBlackList);
9377 clientProxy->OnSetSurfaceNodeIdsChanged(rsScreenId, surfaceNodeIdsToRS);
9378 }
9379
SetVirtualDisplayMuteFlag(ScreenId screenId,bool muteFlag)9380 void ScreenSessionManager::SetVirtualDisplayMuteFlag(ScreenId screenId, bool muteFlag)
9381 {
9382 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9383 TLOGE(WmsLogTag::DMS, "permission denied!");
9384 return;
9385 }
9386 sptr<ScreenSession> virtualScreenSession = GetScreenSession(screenId);
9387 if (!virtualScreenSession) {
9388 TLOGE(WmsLogTag::DMS, "ScreenSession is null");
9389 return;
9390 }
9391 std::shared_ptr<RSDisplayNode> virtualDisplayNode = virtualScreenSession->GetDisplayNode();
9392 if (virtualDisplayNode) {
9393 virtualDisplayNode->SetVirtualScreenMuteStatus(muteFlag);
9394 } else {
9395 TLOGE(WmsLogTag::DMS, "DisplayNode is null");
9396 return;
9397 }
9398 TLOGI(WmsLogTag::DMS, "flush displayNode mute");
9399 RSTransactionAdapter::FlushImplicitTransaction(virtualScreenSession->GetRSUIContext());
9400 TLOGW(WmsLogTag::DMS, "screenId: %{public}" PRIu64 " muteFlag: %{public}d", screenId, muteFlag);
9401 }
9402
DisablePowerOffRenderControl(ScreenId screenId)9403 void ScreenSessionManager::DisablePowerOffRenderControl(ScreenId screenId)
9404 {
9405 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9406 TLOGE(WmsLogTag::DMS, "permission denied!");
9407 return;
9408 }
9409 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64, screenId);
9410 ScreenId rsScreenId = SCREEN_ID_INVALID;
9411 if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
9412 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
9413 return;
9414 }
9415 rsInterface_.DisablePowerOffRenderControl(rsScreenId);
9416 }
9417
ReportFoldStatusToScb(std::vector<std::string> & screenFoldInfo)9418 void ScreenSessionManager::ReportFoldStatusToScb(std::vector<std::string>& screenFoldInfo)
9419 {
9420 auto clientProxy = GetClientProxy();
9421 if (clientProxy) {
9422 auto screenInfo = GetDefaultScreenSession();
9423 int32_t rotation = -1;
9424 if (screenInfo != nullptr) {
9425 rotation = static_cast<int32_t>(screenInfo->GetRotation());
9426 }
9427 screenFoldInfo.emplace_back(std::to_string(rotation));
9428
9429 clientProxy->OnFoldStatusChangedReportUE(screenFoldInfo);
9430 }
9431 }
9432
GetAllDisplayPhysicalResolution()9433 std::vector<DisplayPhysicalResolution> ScreenSessionManager::GetAllDisplayPhysicalResolution()
9434 {
9435 std::lock_guard<std::mutex> lock(allDisplayPhysicalResolutionMutex_);
9436 if (allDisplayPhysicalResolution_.empty()) {
9437 sptr<ScreenSession> defaultScreen = GetDefaultScreenSession();
9438 if (defaultScreen == nullptr) {
9439 TLOGE(WmsLogTag::DMS, "default screen null");
9440 return allDisplayPhysicalResolution_;
9441 }
9442 ScreenProperty defaultScreenProperty = defaultScreen->GetScreenProperty();
9443 DisplayPhysicalResolution defaultSize;
9444 defaultSize.foldDisplayMode_ = FoldDisplayMode::UNKNOWN;
9445 defaultSize.physicalWidth_ = defaultScreenProperty.GetPhyBounds().rect_.width_;
9446 defaultSize.physicalHeight_ = defaultScreenProperty.GetPhyBounds().rect_.height_;
9447 allDisplayPhysicalResolution_.emplace_back(defaultSize);
9448 }
9449 for (auto& info : allDisplayPhysicalResolution_) {
9450 if (info.foldDisplayMode_ == FoldDisplayMode::GLOBAL_FULL) {
9451 info.foldDisplayMode_ = FoldDisplayMode::FULL;
9452 break;
9453 }
9454 }
9455 return allDisplayPhysicalResolution_;
9456 }
9457
InitSecondaryDisplayPhysicalParams()9458 void ScreenSessionManager::InitSecondaryDisplayPhysicalParams()
9459 {
9460 std::vector<DisplayPhysicalResolution> resolutions = ScreenSceneConfig::GetAllDisplayPhysicalConfig();
9461 for (auto &resolution : resolutions) {
9462 if (FoldDisplayMode::MAIN == resolution.foldDisplayMode_) {
9463 screenParams_.push_back(resolution.physicalWidth_);
9464 } else if (FoldDisplayMode::FULL == resolution.foldDisplayMode_) {
9465 screenParams_.push_back(resolution.physicalWidth_);
9466 } else if (FoldDisplayMode::GLOBAL_FULL == resolution.foldDisplayMode_) {
9467 screenParams_.push_back(resolution.physicalWidth_);
9468 screenParams_.push_back(resolution.physicalHeight_);
9469 } else {
9470 TLOGW(WmsLogTag::DMS, "unKnown displayMode");
9471 }
9472 }
9473 if (screenParams_.size() < STATUS_PARAM_VALID_INDEX) {
9474 TLOGE(WmsLogTag::DMS, "invalid param num");
9475 return;
9476 }
9477 screenParams_.push_back(screenParams_[GLOBAL_FULL_STATUS_WIDTH_INDEX] - screenParams_[FULL_STATUS_WIDTH_INDEX]);
9478 TLOGI(WmsLogTag::DMS,
9479 "PhysicalResolution : mainStatusWidth_= %{public}d, fullStatusWidth_= %{public}d, gloablFullStatusWidth_="
9480 "%{public}d, screenHeight_= %{public}d",
9481 screenParams_[MAIN_STATUS_WIDTH_INDEX], screenParams_[FULL_STATUS_WIDTH_INDEX],
9482 screenParams_[GLOBAL_FULL_STATUS_WIDTH_INDEX], screenParams_[SCREEN_HEIGHT_INDEX]);
9483 }
9484
GetCapabilityJson(FoldStatus foldStatus,FoldDisplayMode displayMode,std::vector<std::string> rotation,std::vector<std::string> orientation)9485 nlohmann::ordered_json ScreenSessionManager::GetCapabilityJson(FoldStatus foldStatus, FoldDisplayMode displayMode,
9486 std::vector<std::string> rotation, std::vector<std::string> orientation)
9487 {
9488 nlohmann::ordered_json capabilityInfo;
9489 capabilityInfo["foldStatus"] = std::to_string(static_cast<int32_t>(foldStatus));
9490 capabilityInfo["foldDisplayMode"] = std::to_string(static_cast<int32_t>(displayMode));
9491 capabilityInfo["rotation"] = rotation;
9492 capabilityInfo["orientation"] = orientation;
9493 return capabilityInfo;
9494 }
9495
GetDisplayCapability(std::string & capabilitInfo)9496 DMError ScreenSessionManager::GetDisplayCapability(std::string& capabilitInfo)
9497 {
9498 if (g_foldScreenFlag) {
9499 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
9500 return GetSecondaryDisplayCapability(capabilitInfo);
9501 }
9502 return GetFoldableDeviceCapability(capabilitInfo);
9503 }
9504 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
9505 return GetSuperFoldCapability(capabilitInfo);
9506 }
9507
9508 std::vector<std::string> orientation = ORIENTATION_DEFAULT;
9509 if (g_isPcDevice && !FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
9510 orientation = {"1", "0", "3", "2"};
9511 }
9512 nlohmann::ordered_json jsonDisplayCapabilityList;
9513 jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
9514 nlohmann::ordered_json capabilityInfo = GetCapabilityJson(FoldStatus::UNKNOWN, FoldDisplayMode::UNKNOWN,
9515 ROTATION_DEFAULT, orientation);
9516 jsonDisplayCapabilityList["capability"].push_back(std::move(capabilityInfo));
9517
9518 capabilitInfo = jsonDisplayCapabilityList.dump();
9519 return DMError::DM_OK;
9520 }
9521
GetSecondaryDisplayCapability(std::string & capabilitInfo)9522 DMError ScreenSessionManager::GetSecondaryDisplayCapability(std::string& capabilitInfo)
9523 {
9524 nlohmann::ordered_json jsonDisplayCapabilityList;
9525 jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
9526
9527 nlohmann::ordered_json fCapabilityInfo = GetCapabilityJson(FoldStatus::FOLDED, FoldDisplayMode::MAIN,
9528 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9529 jsonDisplayCapabilityList["capability"].push_back(std::move(fCapabilityInfo));
9530 nlohmann::ordered_json nCapability = GetCapabilityJson(FoldStatus::FOLD_STATE_FOLDED_WITH_SECOND_EXPAND,
9531 FoldDisplayMode::MAIN, ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9532 jsonDisplayCapabilityList["capability"].push_back(std::move(nCapability));
9533 nlohmann::ordered_json mCapabilityInfo = GetCapabilityJson(FoldStatus::EXPAND, FoldDisplayMode::FULL,
9534 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9535 jsonDisplayCapabilityList["capability"].push_back(std::move(mCapabilityInfo));
9536 std::vector<std::string> orientation = {"3", "0", "1", "2"};
9537 nlohmann::ordered_json gCapability = GetCapabilityJson(FoldStatus::FOLD_STATE_EXPAND_WITH_SECOND_EXPAND,
9538 FoldDisplayMode::FULL, ROTATION_DEFAULT, orientation);
9539 jsonDisplayCapabilityList["capability"].push_back(std::move(gCapability));
9540 #ifdef FOLD_ABILITY_ENABLE
9541 if (foldScreenController_) {
9542 nlohmann::ordered_json foldCreaseRegion = foldScreenController_->GetFoldCreaseRegionJson();
9543 jsonDisplayCapabilityList["allCreaseRegion"] = foldCreaseRegion;
9544 }
9545 #endif
9546
9547 capabilitInfo = jsonDisplayCapabilityList.dump();
9548 return DMError::DM_OK;
9549 }
9550
GetFoldableDeviceCapability(std::string & capabilitInfo)9551 DMError ScreenSessionManager::GetFoldableDeviceCapability(std::string& capabilitInfo)
9552 {
9553 nlohmann::ordered_json jsonDisplayCapabilityList;
9554 jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
9555 FoldStatus expandStatus = FoldStatus::EXPAND;
9556 FoldStatus foldStatus = FoldStatus::FOLDED;
9557 FoldDisplayMode expandDisplayMode = FoldDisplayMode::FULL;
9558 FoldDisplayMode foldDisplayMode = FoldDisplayMode::MAIN;
9559 if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
9560 expandDisplayMode = FoldDisplayMode::MAIN;
9561 foldDisplayMode = FoldDisplayMode::SUB;
9562 }
9563 nlohmann::ordered_json expandCapabilityInfo = GetCapabilityJson(expandStatus, expandDisplayMode,
9564 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9565 jsonDisplayCapabilityList["capability"].push_back(std::move(expandCapabilityInfo));
9566 nlohmann::ordered_json foldCapabilityInfo = GetCapabilityJson(foldStatus, foldDisplayMode,
9567 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9568 jsonDisplayCapabilityList["capability"].push_back(std::move(foldCapabilityInfo));
9569 #ifdef FOLD_ABILITY_ENABLE
9570 if (foldScreenController_) {
9571 nlohmann::ordered_json foldCreaseRegion = foldScreenController_->GetFoldCreaseRegionJson();
9572 jsonDisplayCapabilityList["allCreaseRegion"] = foldCreaseRegion;
9573 }
9574 #endif
9575
9576 capabilitInfo = jsonDisplayCapabilityList.dump();
9577 return DMError::DM_OK;
9578 }
9579
GetSuperFoldCapability(std::string & capabilitInfo)9580 DMError ScreenSessionManager::GetSuperFoldCapability(std::string& capabilitInfo)
9581 {
9582 nlohmann::ordered_json jsonDisplayCapabilityList;
9583 jsonDisplayCapabilityList["capability"] = nlohmann::json::array();
9584
9585 nlohmann::ordered_json expandCapabilityInfo = GetCapabilityJson(FoldStatus::EXPAND, FoldDisplayMode::UNKNOWN,
9586 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9587 jsonDisplayCapabilityList["capability"].push_back(std::move(expandCapabilityInfo));
9588 nlohmann::ordered_json foldCapabilityInfo = GetCapabilityJson(FoldStatus::FOLDED, FoldDisplayMode::UNKNOWN,
9589 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9590 jsonDisplayCapabilityList["capability"].push_back(std::move(foldCapabilityInfo));
9591 nlohmann::ordered_json halfFoldCapabilityInfo = GetCapabilityJson(FoldStatus::HALF_FOLD, FoldDisplayMode::UNKNOWN,
9592 ROTATION_DEFAULT, ORIENTATION_DEFAULT);
9593 jsonDisplayCapabilityList["capability"].push_back(std::move(halfFoldCapabilityInfo));
9594 #ifdef FOLD_ABILITY_ENABLE
9595 nlohmann::ordered_json foldCreaseRegion = SuperFoldStateManager::GetInstance().GetFoldCreaseRegionJson();
9596 jsonDisplayCapabilityList["allCreaseRegion"] = foldCreaseRegion;
9597 #endif
9598
9599 capabilitInfo = jsonDisplayCapabilityList.dump();
9600 return DMError::DM_OK;
9601 }
9602
SetVirtualScreenStatus(ScreenId screenId,VirtualScreenStatus screenStatus)9603 bool ScreenSessionManager::SetVirtualScreenStatus(ScreenId screenId, VirtualScreenStatus screenStatus)
9604 {
9605 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9606 TLOGE(WmsLogTag::DMS, "permission denied!");
9607 return false;
9608 }
9609 TLOGI(WmsLogTag::DMS, "ScreenId: %{public}" PRIu64 " screenStatus: %{public}d",
9610 screenId, static_cast<int32_t>(screenStatus));
9611 ScreenId rsScreenId = SCREEN_ID_INVALID;
9612 if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) {
9613 TLOGE(WmsLogTag::DMS, "No corresponding rsId");
9614 return false;
9615 }
9616
9617 return rsInterface_.SetVirtualScreenStatus(rsScreenId, screenStatus);
9618 }
9619
GetOrCreateFakeScreenSession(sptr<ScreenSession> screenSession)9620 sptr<ScreenSession> ScreenSessionManager::GetOrCreateFakeScreenSession(sptr<ScreenSession> screenSession)
9621 {
9622 sptr<ScreenSession> fakeScreenSession = screenSession->GetFakeScreenSession();
9623 if (fakeScreenSession != nullptr) {
9624 TLOGI(WmsLogTag::DMS, "fake screen session has exist");
9625 return fakeScreenSession;
9626 }
9627 ScreenProperty screenProperty = screenSession->GetScreenProperty();
9628 ScreenSessionConfig config = {
9629 .screenId = SCREEN_ID_FAKE,
9630 .defaultScreenId = SCREEN_ID_INVALID,
9631 .property = screenProperty,
9632 };
9633 fakeScreenSession =
9634 new(std::nothrow) ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
9635 if (fakeScreenSession == nullptr) {
9636 return nullptr;
9637 }
9638 return fakeScreenSession;
9639 }
9640
InitFakeScreenSession(sptr<ScreenSession> screenSession)9641 void ScreenSessionManager::InitFakeScreenSession(sptr<ScreenSession> screenSession)
9642 {
9643 if (screenSession == nullptr) {
9644 TLOGE(WmsLogTag::DMS, "screen session is null");
9645 return;
9646 }
9647 sptr<ScreenSession> fakeScreenSession = GetOrCreateFakeScreenSession(screenSession);
9648 if (fakeScreenSession == nullptr) {
9649 TLOGE(WmsLogTag::DMS, "get or create fake screen session failed");
9650 return;
9651 }
9652 ScreenProperty screenProperty = screenSession->GetScreenProperty();
9653 uint32_t screenWidth = screenProperty.GetBounds().rect_.GetWidth();
9654 uint32_t screenHeight = screenProperty.GetBounds().rect_.GetHeight();
9655 uint32_t fakeScreenHeight = screenHeight / HALF_SCREEN_PARAM;
9656 DMRect creaseRect = screenProperty.GetCreaseRect();
9657 if (creaseRect.height_ > 0) {
9658 fakeScreenHeight = screenHeight - (static_cast<uint32_t>(creaseRect.posY_) + creaseRect.height_);
9659 }
9660 fakeScreenSession->SetIsFakeSession(true);
9661 fakeScreenSession->UpdatePropertyByResolution(screenWidth, fakeScreenHeight);
9662 fakeScreenSession->SetXYPosition(0, DISPLAY_B_HEIGHT);
9663 fakeScreenSession->SetScreenCombination(ScreenCombination::SCREEN_EXTEND);
9664 screenSession->UpdatePropertyByFakeBounds(screenWidth, fakeScreenHeight);
9665 screenSession->SetFakeScreenSession(fakeScreenSession);
9666 screenSession->SetIsFakeInUse(true);
9667 }
9668
SetVirtualScreenSecurityExemption(ScreenId screenId,uint32_t pid,std::vector<uint64_t> & windowIdList)9669 DMError ScreenSessionManager::SetVirtualScreenSecurityExemption(ScreenId screenId, uint32_t pid,
9670 std::vector<uint64_t>& windowIdList)
9671 {
9672 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9673 TLOGE(WmsLogTag::DMS, "permission denied!");
9674 return DMError::DM_ERROR_INVALID_CALLING;
9675 }
9676 std::vector<uint64_t> surfaceNodeIds;
9677 if (!windowIdList.empty()) {
9678 MockSessionManagerService::GetInstance().GetProcessSurfaceNodeIdByPersistentId(
9679 pid, windowIdList, surfaceNodeIds);
9680 }
9681 auto rsId = screenIdManager_.ConvertToRsScreenId(screenId);
9682 auto ret = rsInterface_.SetVirtualScreenSecurityExemptionList(rsId, surfaceNodeIds);
9683
9684 std::ostringstream oss;
9685 oss << "screenId:" << screenId << ", rsID: " << rsId << ", pid: " << pid
9686 << ", winListSize:[ ";
9687 for (auto val : windowIdList) {
9688 oss << val << " ";
9689 }
9690 oss << "]" << ", surfaceListSize:[ ";
9691 for (auto val : surfaceNodeIds) {
9692 oss << val << " ";
9693 }
9694 oss << "]" << ", ret: " << ret;
9695 TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
9696 return ret == 0 ? DMError::DM_OK : DMError::DM_ERROR_UNKNOWN;
9697 }
9698
SetDefaultScreenId(ScreenId defaultScreenId)9699 void ScreenSessionManager::SetDefaultScreenId(ScreenId defaultScreenId)
9700 {
9701 defaultScreenId_ = defaultScreenId;
9702 }
9703
GetClientProxy()9704 sptr<IScreenSessionManagerClient> ScreenSessionManager::GetClientProxy()
9705 {
9706 std::lock_guard<std::mutex> lock(clientProxyMutex_);
9707 return clientProxy_;
9708 }
9709
SetClientProxy(const sptr<IScreenSessionManagerClient> & client)9710 void ScreenSessionManager::SetClientProxy(const sptr<IScreenSessionManagerClient>& client)
9711 {
9712 std::lock_guard<std::mutex> lock(clientProxyMutex_);
9713 clientProxy_ = client;
9714 }
9715
SetMultiScreenMode(ScreenId mainScreenId,ScreenId secondaryScreenId,MultiScreenMode screenMode)9716 DMError ScreenSessionManager::SetMultiScreenMode(ScreenId mainScreenId, ScreenId secondaryScreenId,
9717 MultiScreenMode screenMode)
9718 {
9719 #ifdef WM_MULTI_SCREEN_ENABLE
9720 TLOGW(WmsLogTag::DMS, "mainScreenId:%{public}" PRIu64",secondaryScreenId:%{public}" PRIu64",Mode:%{public}u",
9721 mainScreenId, secondaryScreenId, screenMode);
9722 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9723 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
9724 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
9725 return DMError::DM_ERROR_NOT_SYSTEM_APP;
9726 }
9727 if (IsPhysicalExtendScreenInUse(mainScreenId, secondaryScreenId) == DMError::DM_OK) {
9728 return DMError::DM_ERROR_INVALID_MODE_ID;
9729 }
9730 CreateExtendVirtualScreen(secondaryScreenId);
9731 if (mainScreenId == secondaryScreenId && mainScreenId == SCREEN_ID_OUTER_ONLY) {
9732 TLOGW(WmsLogTag::DMS, "set to outer only mode.");
9733 SetIsOuterOnlyMode(true);
9734 MultiScreenModeChange(mainScreenId, mainScreenId, "off");
9735 return DMError::DM_OK;
9736 }
9737 if (GetIsOuterOnlyMode()) {
9738 SetIsOuterOnlyMode(false);
9739 TLOGI(WmsLogTag::DMS, "exit outer only mode.");
9740 ExitOuterOnlyMode(mainScreenId, secondaryScreenId, screenMode);
9741 return DMError::DM_OK;
9742 }
9743 SetMultiScreenModeInner(mainScreenId, secondaryScreenId, screenMode);
9744 auto combination = screenMode == MultiScreenMode::SCREEN_MIRROR ?
9745 ScreenCombination::SCREEN_MIRROR : ScreenCombination::SCREEN_EXPAND;
9746 SetScreenCastInfo(secondaryScreenId, mainScreenId, combination);
9747 NotifyScreenModeChange();
9748 #endif
9749 return DMError::DM_OK;
9750 }
9751
SetMultiScreenModeInner(ScreenId mainScreenId,ScreenId secondaryScreenId,MultiScreenMode screenMode)9752 void ScreenSessionManager::SetMultiScreenModeInner(ScreenId mainScreenId, ScreenId secondaryScreenId,
9753 MultiScreenMode screenMode)
9754 {
9755 TLOGI(WmsLogTag::DMS, "enter");
9756 if (screenMode == MultiScreenMode::SCREEN_MIRROR) {
9757 MultiScreenModeChange(mainScreenId, secondaryScreenId, "mirror");
9758 SetExtendedScreenFallbackPlan(secondaryScreenId);
9759 sptr<ScreenSession> screenSession = GetScreenSession(secondaryScreenId);
9760 if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
9761 MultiScreenPositionOptions defaultOptions = { GetDefaultScreenId(), 0, 0 };
9762 SetRelativePositionForDisconnect(defaultOptions);
9763 NotifyCaptureStatusChanged(true);
9764 }
9765 } else if (screenMode == MultiScreenMode::SCREEN_EXTEND) {
9766 bool lastScreenMirror = false;
9767 sptr<ScreenSession> screenSession = GetScreenSession(secondaryScreenId);
9768 if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
9769 lastScreenMirror = true;
9770 }
9771 MultiScreenModeChange(mainScreenId, secondaryScreenId, "extend");
9772 SetExtendedScreenFallbackPlan(secondaryScreenId);
9773 if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND &&
9774 lastScreenMirror) {
9775 NotifyCaptureStatusChanged(false);
9776 }
9777 } else {
9778 TLOGE(WmsLogTag::DMS, "operate mode error");
9779 }
9780 }
9781
ExitOuterOnlyMode(ScreenId mainScreenId,ScreenId secondaryScreenId,MultiScreenMode screenMode)9782 void ScreenSessionManager::ExitOuterOnlyMode(ScreenId mainScreenId, ScreenId secondaryScreenId,
9783 MultiScreenMode screenMode)
9784 {
9785 #ifdef WM_MULTI_SCREEN_ENABLE
9786 ScreenCombination innerCombination = ScreenCombination::SCREEN_MAIN;
9787 ScreenCombination externalCombination = ScreenCombination::SCREEN_EXTEND;
9788 sptr<ScreenSession> internalSession = GetInternalScreenSession();
9789 if (internalSession == nullptr) {
9790 TLOGE(WmsLogTag::DMS, "internalSession is nullptr");
9791 return;
9792 }
9793 ScreenCombination combination = ScreenCombination::SCREEN_EXTEND;
9794 if (screenMode == MultiScreenMode::SCREEN_MIRROR) {
9795 combination = ScreenCombination::SCREEN_MIRROR;
9796 }
9797 if (internalSession->GetRSScreenId() == mainScreenId) {
9798 innerCombination = ScreenCombination::SCREEN_MAIN;
9799 externalCombination = combination;
9800 } else if (internalSession->GetRSScreenId() == secondaryScreenId) {
9801 innerCombination = combination;
9802 externalCombination = ScreenCombination::SCREEN_MAIN;
9803 } else {
9804 TLOGE(WmsLogTag::DMS, "invalid param, use default mode.");
9805 }
9806 MultiScreenPowerChangeManager::GetInstance().SetInnerAndExternalCombination(innerCombination,
9807 externalCombination);
9808 MultiScreenModeChange(mainScreenId, mainScreenId, "on");
9809 #endif
9810 }
9811
IsPhysicalExtendScreenInUse(ScreenId mainScreenId,ScreenId secondaryScreenId)9812 DMError ScreenSessionManager::IsPhysicalExtendScreenInUse(ScreenId mainScreenId, ScreenId secondaryScreenId)
9813 {
9814 TLOGI(WmsLogTag::DMS, "Enter");
9815 sptr<ScreenSession> mainScreenSession = GetScreenSessionByRsId(mainScreenId);
9816 sptr<ScreenSession> secondaryScreenSession = GetScreenSessionByRsId(secondaryScreenId);
9817 if (mainScreenSession == nullptr || secondaryScreenSession == nullptr) {
9818 TLOGE(WmsLogTag::DMS, "ScreenSession is null");
9819 return DMError::DM_ERROR_NULLPTR;
9820 }
9821 if (mainScreenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL ||
9822 secondaryScreenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
9823 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
9824 for (auto sessionIt : screenSessionMap_) {
9825 auto screenSession = sessionIt.second;
9826 if (screenSession == nullptr) {
9827 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
9828 continue;
9829 }
9830 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL &&
9831 (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR ||
9832 screenSession->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND)) {
9833 TLOGI(WmsLogTag::DMS, "physical extend screen in use screenid: %{public}" PRIu64,
9834 screenSession->GetScreenId());
9835 return DMError::DM_OK;
9836 }
9837 }
9838 }
9839 return DMError::DM_ERROR_UNKNOWN;
9840 }
9841
CreateExtendVirtualScreen(ScreenId screenId)9842 void ScreenSessionManager::CreateExtendVirtualScreen(ScreenId screenId)
9843 {
9844 TLOGI(WmsLogTag::DMS, "Enter");
9845 sptr<ScreenSession> screenSession = GetScreenSessionByRsId(screenId);
9846 if (screenSession == nullptr) {
9847 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
9848 return;
9849 }
9850 if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::VIRTUAL) {
9851 return;
9852 }
9853 if (screenSession->GetDisplayNode() == nullptr) {
9854 Rosen::RSDisplayNodeConfig rsConfig;
9855 ScreenId rsScreenId = screenSession->GetRSScreenId();
9856 rsConfig.screenId = rsScreenId;
9857 screenSession->CreateDisplayNode(rsConfig);
9858 screenSession->SetDisplayNodeScreenId(rsScreenId);
9859 screenSession->SetIsCurrentInUse(true);
9860 screenSession->SetIsExtend(true);
9861 screenSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
9862 screenSession->SetIsExtendVirtual(true);
9863 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64", rsScreenId:%{public}" PRIu64"",
9864 screenId, rsScreenId);
9865 }
9866 }
9867
SetMultiScreenRelativePosition(MultiScreenPositionOptions mainScreenOptions,MultiScreenPositionOptions secondScreenOption)9868 DMError ScreenSessionManager::SetMultiScreenRelativePosition(MultiScreenPositionOptions mainScreenOptions,
9869 MultiScreenPositionOptions secondScreenOption)
9870 {
9871 #ifdef WM_MULTI_SCREEN_ENABLE
9872 TLOGI(WmsLogTag::DMS,
9873 "mID:%{public}" PRIu64", X:%{public}u, Y:%{public}u,sID:%{public}" PRIu64", X:%{public}u, Y:%{public}u",
9874 mainScreenOptions.screenId_, mainScreenOptions.startX_, mainScreenOptions.startY_,
9875 secondScreenOption.screenId_, secondScreenOption.startX_, secondScreenOption.startY_);
9876 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
9877 TLOGE(WmsLogTag::DMS, "permission denied! clientName: %{public}s, pid: %{public}d",
9878 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
9879 return DMError::DM_ERROR_NOT_SYSTEM_APP;
9880 }
9881 sptr<ScreenSession> firstScreenSession = nullptr;
9882 sptr<ScreenSession> secondScreenSession = nullptr;
9883 if (g_isPcDevice) {
9884 firstScreenSession = GetScreenSessionByRsId(mainScreenOptions.screenId_);
9885 secondScreenSession = GetScreenSessionByRsId(secondScreenOption.screenId_);
9886 } else {
9887 firstScreenSession = GetScreenSession(mainScreenOptions.screenId_);
9888 secondScreenSession = GetScreenSession(secondScreenOption.screenId_);
9889 }
9890 if (!firstScreenSession || !secondScreenSession) {
9891 TLOGE(WmsLogTag::DMS, "ScreenSession is null");
9892 return DMError::DM_ERROR_NULLPTR;
9893 }
9894 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
9895 !MultiScreenManager::GetInstance().AreScreensTouching(firstScreenSession, secondScreenSession,
9896 mainScreenOptions, secondScreenOption)) {
9897 TLOGE(WmsLogTag::DMS, "Options incorrect!");
9898 return DMError::DM_ERROR_INVALID_PARAM;
9899 }
9900 SetMultiScreenRelativePositionInner(firstScreenSession, secondScreenSession, mainScreenOptions,
9901 secondScreenOption);
9902 #endif
9903 return DMError::DM_OK;
9904 }
9905
SetMultiScreenRelativePositionInner(sptr<ScreenSession> & firstScreenSession,sptr<ScreenSession> & secondScreenSession,MultiScreenPositionOptions mainScreenOptions,MultiScreenPositionOptions secondScreenOption)9906 void ScreenSessionManager::SetMultiScreenRelativePositionInner(sptr<ScreenSession>& firstScreenSession,
9907 sptr<ScreenSession>& secondScreenSession, MultiScreenPositionOptions mainScreenOptions,
9908 MultiScreenPositionOptions secondScreenOption)
9909 {
9910 #ifdef WM_MULTI_SCREEN_ENABLE
9911 firstScreenSession->SetStartPosition(mainScreenOptions.startX_, mainScreenOptions.startY_);
9912 secondScreenSession->SetStartPosition(secondScreenOption.startX_, secondScreenOption.startY_);
9913 CalculateXYPosition(firstScreenSession, secondScreenSession);
9914 firstScreenSession->PropertyChange(firstScreenSession->GetScreenProperty(),
9915 ScreenPropertyChangeReason::RELATIVE_POSITION_CHANGE);
9916 secondScreenSession->PropertyChange(secondScreenSession->GetScreenProperty(),
9917 ScreenPropertyChangeReason::RELATIVE_POSITION_CHANGE);
9918 if (g_isPcDevice) {
9919 sptr<ScreenSession> firstPhysicalScreen = GetPhysicalScreenSession(firstScreenSession->GetRSScreenId());
9920 sptr<ScreenSession> secondPhysicalScreen = GetPhysicalScreenSession(secondScreenSession->GetRSScreenId());
9921 if (firstPhysicalScreen && secondPhysicalScreen) {
9922 firstPhysicalScreen->SetStartPosition(mainScreenOptions.startX_, mainScreenOptions.startY_);
9923 secondPhysicalScreen->SetStartPosition(secondScreenOption.startX_, secondScreenOption.startY_);
9924 CalculateXYPosition(firstPhysicalScreen, secondPhysicalScreen);
9925 }
9926 }
9927 std::shared_ptr<RSDisplayNode> firstDisplayNode = firstScreenSession->GetDisplayNode();
9928 std::shared_ptr<RSDisplayNode> secondDisplayNode = secondScreenSession->GetDisplayNode();
9929 if (firstDisplayNode && secondDisplayNode) {
9930 SetScreenOffset(firstScreenSession->GetScreenId(), mainScreenOptions.startX_, mainScreenOptions.startY_);
9931 SetScreenOffset(secondScreenSession->GetScreenId(), secondScreenOption.startX_, secondScreenOption.startY_);
9932 } else {
9933 TLOGW(WmsLogTag::DMS, "DisplayNode is null");
9934 }
9935 TLOGI(WmsLogTag::DMS, "free displayNode");
9936 RSTransactionAdapter::FlushImplicitTransaction(
9937 {firstScreenSession->GetRSUIContext(), secondScreenSession->GetRSUIContext()});
9938 #endif
9939 }
9940
SetRelativePositionForDisconnect(MultiScreenPositionOptions defaultScreenOptions)9941 void ScreenSessionManager::SetRelativePositionForDisconnect(MultiScreenPositionOptions defaultScreenOptions)
9942 {
9943 #ifdef WM_MULTI_SCREEN_ENABLE
9944 TLOGI(WmsLogTag::DMS, "mID:%{public}" PRIu64", X:%{public}u, Y:%{public}u",
9945 defaultScreenOptions.screenId_, defaultScreenOptions.startX_, defaultScreenOptions.startY_);
9946 sptr<ScreenSession> defaultScreenSession = GetScreenSession(defaultScreenOptions.screenId_);
9947 if (!defaultScreenSession) {
9948 TLOGE(WmsLogTag::DMS, "ScreenSession is null");
9949 return;
9950 }
9951 defaultScreenSession->SetStartPosition(defaultScreenOptions.startX_, defaultScreenOptions.startY_);
9952 CalculateXYPosition(defaultScreenSession);
9953 defaultScreenSession->PropertyChange(defaultScreenSession->GetScreenProperty(),
9954 ScreenPropertyChangeReason::RELATIVE_POSITION_CHANGE);
9955 std::shared_ptr<RSDisplayNode> defaultDisplayNode = defaultScreenSession->GetDisplayNode();
9956 if (defaultDisplayNode) {
9957 SetScreenOffset(defaultScreenSession->GetScreenId(),
9958 defaultScreenOptions.startX_, defaultScreenOptions.startY_);
9959 } else {
9960 TLOGW(WmsLogTag::DMS, "DisplayNode is null");
9961 }
9962 TLOGI(WmsLogTag::DMS, "free displayNode");
9963 RSTransactionAdapter::FlushImplicitTransaction(defaultScreenSession->GetRSUIContext());
9964 #endif
9965 }
9966
MultiScreenModeChange(ScreenId mainScreenId,ScreenId secondaryScreenId,const std::string & operateMode)9967 void ScreenSessionManager::MultiScreenModeChange(ScreenId mainScreenId, ScreenId secondaryScreenId,
9968 const std::string& operateMode)
9969 {
9970 #ifdef WM_MULTI_SCREEN_ENABLE
9971 std::lock_guard<std::mutex> lock(screenModeChangeMutex_);
9972 TLOGW(WmsLogTag::DMS, "mainId=%{public}" PRIu64" secondId=%{public}" PRIu64" operateType: %{public}s",
9973 mainScreenId, secondaryScreenId, operateMode.c_str());
9974 OnScreenModeChange(ScreenModeChangeEvent::BEGIN);
9975 if (g_isPcDevice) {
9976 std::unique_lock<std::mutex> lock(screenMaskMutex_);
9977 if (screenMaskCV_.wait_for(lock,
9978 std::chrono::milliseconds(CV_WAIT_SCREEN_MASK_MS)) == std::cv_status::timeout) {
9979 TLOGI(WmsLogTag::DMS, "wait screenMaskMutex_ timeout");
9980 }
9981 }
9982 sptr<ScreenSession> firstSession = nullptr;
9983 sptr<ScreenSession> secondarySession = nullptr;
9984 OperateModeChange(mainScreenId, secondaryScreenId, firstSession, secondarySession, operateMode);
9985 if (firstSession != nullptr && secondarySession != nullptr) {
9986 ScreenCombination firstCombination = firstSession->GetScreenCombination();
9987 ScreenCombination secondaryCombination = secondarySession->GetScreenCombination();
9988 MultiScreenManager::GetInstance().MultiScreenModeChange(firstSession, secondarySession, operateMode);
9989 if ((firstCombination == ScreenCombination::SCREEN_MIRROR ||
9990 secondaryCombination == ScreenCombination::SCREEN_MIRROR) &&
9991 operateMode == SCREEN_EXTEND) {
9992 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_MIRROR, MULTI_SCREEN_EXIT_STR);
9993 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_ENTER_STR);
9994 NotifyDisplayChanged(secondarySession->ConvertToDisplayInfo(),
9995 DisplayChangeEvent::SOURCE_MODE_CHANGED);
9996 } else if ((firstCombination == ScreenCombination::SCREEN_EXTEND ||
9997 secondaryCombination == ScreenCombination::SCREEN_EXTEND) &&
9998 operateMode == SCREEN_MIRROR) {
9999 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_EXTEND, MULTI_SCREEN_EXIT_STR);
10000 MultiScreenManager::GetInstance().MultiScreenReportDataToRss(SCREEN_MIRROR, MULTI_SCREEN_ENTER_STR);
10001 NotifyDisplayChanged(secondarySession->ConvertToDisplayInfo(),
10002 DisplayChangeEvent::SOURCE_MODE_CHANGED);
10003 }
10004 } else {
10005 TLOGE(WmsLogTag::DMS, "params error");
10006 }
10007 NotifyScreenModeChange();
10008 OnScreenModeChange(ScreenModeChangeEvent::END);
10009 #endif
10010 }
10011
OperateModeChange(ScreenId mainScreenId,ScreenId secondaryScreenId,sptr<ScreenSession> & firstSession,sptr<ScreenSession> & secondarySession,const std::string & operateMode)10012 void ScreenSessionManager::OperateModeChange(ScreenId mainScreenId, ScreenId secondaryScreenId,
10013 sptr<ScreenSession>& firstSession, sptr<ScreenSession>& secondarySession, const std::string& operateMode)
10014 {
10015 {
10016 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
10017 for (auto sessionIt : screenSessionMap_) {
10018 auto screenSession = sessionIt.second;
10019 if (screenSession == nullptr) {
10020 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
10021 continue;
10022 }
10023 if (!screenSession->GetIsCurrentInUse()) {
10024 TLOGE(WmsLogTag::DMS, "current screen: %{public}" PRIu64" is not in user!", sessionIt.first);
10025 continue;
10026 }
10027 if (screenSession->GetRSScreenId() == mainScreenId) {
10028 firstSession = screenSession;
10029 }
10030 if (screenSession->GetRSScreenId() == secondaryScreenId) {
10031 secondarySession = screenSession;
10032 }
10033 }
10034 }
10035 if (operateMode == "off" || operateMode == "on") {
10036 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
10037 for (auto sessionIt : screenSessionMap_) {
10038 auto screenSession = sessionIt.second;
10039 if (screenSession == nullptr) {
10040 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
10041 continue;
10042 }
10043 if (!screenSession->GetIsCurrentInUse()) {
10044 TLOGW(WmsLogTag::DMS, "current screen: %{public}" PRIu64" is not in user!", sessionIt.first);
10045 continue;
10046 }
10047 if (screenSession->GetRSScreenId() == mainScreenId) {
10048 firstSession = screenSession;
10049 }
10050 if (screenSession->GetRSScreenId() == secondaryScreenId) {
10051 secondarySession = screenSession;
10052 }
10053 }
10054 }
10055 }
10056
SwitchScrollParam(FoldDisplayMode displayMode)10057 void ScreenSessionManager::SwitchScrollParam(FoldDisplayMode displayMode)
10058 {
10059 auto task = [=]() {
10060 std::map<FoldDisplayMode, ScrollableParam> scrollableParams = ScreenSceneConfig::GetAllScrollableParam();
10061 std::string scrollVelocityScale = scrollableParams.count(displayMode) != 0 ?
10062 scrollableParams[displayMode].velocityScale_ : "0";
10063 std::string scrollFriction = scrollableParams.count(displayMode) != 0 ?
10064 scrollableParams[displayMode].friction_ : "0";
10065 system::SetParameter("persist.scrollable.velocityScale", scrollVelocityScale);
10066 system::SetParameter("persist.scrollable.friction", scrollFriction);
10067 };
10068 taskScheduler_->PostAsyncTask(task, "SwitchScrollParam");
10069 }
10070
MultiScreenModeChange(const std::string & firstScreenIdStr,const std::string & secondaryScreenIdStr,const std::string & secondaryChandeMode)10071 void ScreenSessionManager::MultiScreenModeChange(const std::string& firstScreenIdStr,
10072 const std::string& secondaryScreenIdStr, const std::string& secondaryChandeMode)
10073 {
10074 #ifdef WM_MULTI_SCREEN_ENABLE
10075 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
10076 TLOGE(WmsLogTag::DMS, "permission denied! clientName: %{public}s, pid: %{public}d",
10077 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
10078 return;
10079 }
10080 if (!ScreenSettingHelper::IsNumber(firstScreenIdStr) || !ScreenSettingHelper::IsNumber(secondaryScreenIdStr)) {
10081 TLOGE(WmsLogTag::DMS, "param denied!");
10082 return;
10083 }
10084 ScreenId firstScreenId = DISPLAY_ID_INVALID;
10085 ScreenId secondaryScreenId = DISPLAY_ID_INVALID;
10086 if (!ScreenSettingHelper::ConvertStrToUint64(firstScreenIdStr, firstScreenId) ||
10087 !ScreenSettingHelper::ConvertStrToUint64(secondaryScreenIdStr, secondaryScreenId)) {
10088 TLOGE(WmsLogTag::DMS, "dumper screenId params error!");
10089 return;
10090 }
10091 if (secondaryChandeMode == "mirror" || secondaryChandeMode == "extend") {
10092 MultiScreenModeChange(firstScreenId, secondaryScreenId, secondaryChandeMode);
10093 } else {
10094 TLOGE(WmsLogTag::DMS, "dumper params error");
10095 }
10096 #endif
10097 }
10098
OnScreenExtendChange(ScreenId mainScreenId,ScreenId extendScreenId)10099 void ScreenSessionManager::OnScreenExtendChange(ScreenId mainScreenId, ScreenId extendScreenId)
10100 {
10101 auto clientProxy = GetClientProxy();
10102 if (!clientProxy) {
10103 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
10104 return;
10105 }
10106 clientProxy->OnScreenExtendChanged(mainScreenId, extendScreenId);
10107 }
10108
OnTentModeChanged(int tentType,int32_t hall)10109 void ScreenSessionManager::OnTentModeChanged(int tentType, int32_t hall)
10110 {
10111 #ifdef FOLD_ABILITY_ENABLE
10112 if (!foldScreenController_) {
10113 TLOGI(WmsLogTag::DMS, "foldScreenController_ is null");
10114 return;
10115 }
10116 foldScreenController_->OnTentModeChanged(tentType, hall);
10117 #endif
10118 }
10119
SetCoordinationFlag(bool isCoordinationFlag)10120 void ScreenSessionManager::SetCoordinationFlag(bool isCoordinationFlag)
10121 {
10122 TLOGI(WmsLogTag::DMS, "set coordination flag %{public}d", isCoordinationFlag);
10123 isCoordinationFlag_ = isCoordinationFlag;
10124 }
10125
GetCoordinationFlag(void)10126 bool ScreenSessionManager::GetCoordinationFlag(void)
10127 {
10128 return isCoordinationFlag_;
10129 }
10130
SetVirtualScreenMaxRefreshRate(ScreenId id,uint32_t refreshRate,uint32_t & actualRefreshRate)10131 DMError ScreenSessionManager::SetVirtualScreenMaxRefreshRate(ScreenId id, uint32_t refreshRate,
10132 uint32_t& actualRefreshRate)
10133 {
10134 if (!SessionPermission::IsSystemCalling()) {
10135 TLOGE(WmsLogTag::DMS, "permission denied! clientName: %{public}s, pid: %{public}d",
10136 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
10137 return DMError::DM_ERROR_NOT_SYSTEM_APP;
10138 }
10139 TLOGI(WmsLogTag::DMS, "ID:%{public}" PRIu64", refreshRate:%{public}u, actualRefreshRate:%{public}u",
10140 id, refreshRate, actualRefreshRate);
10141 if (id == GetDefaultScreenId()) {
10142 TLOGE(WmsLogTag::DMS, "cannot set refresh main screen id: %{public}" PRIu64".", GetDefaultScreenId());
10143 return DMError::DM_ERROR_INVALID_PARAM;
10144 }
10145 auto screenSession = GetScreenSession(id);
10146 if (screenSession == nullptr) {
10147 TLOGE(WmsLogTag::DMS, "screenSession is null.");
10148 return DMError::DM_ERROR_INVALID_PARAM;
10149 }
10150 ScreenId rsScreenId;
10151 if (!screenIdManager_.ConvertToRsScreenId(id, rsScreenId)) {
10152 TLOGE(WmsLogTag::DMS, "No corresponding rsId.");
10153 return DMError::DM_ERROR_INVALID_PARAM;
10154 }
10155 int32_t res = rsInterface_.SetVirtualScreenRefreshRate(rsScreenId, refreshRate, actualRefreshRate);
10156 TLOGI(WmsLogTag::DMS, "refreshRate:%{public}u, actualRefreshRate:%{public}u", refreshRate, actualRefreshRate);
10157 if (res != StatusCode::SUCCESS) {
10158 TLOGE(WmsLogTag::DMS, "rsInterface error: %{public}d", res);
10159 return DMError::DM_ERROR_INVALID_PARAM;
10160 }
10161 screenSession->UpdateRefreshRate(actualRefreshRate);
10162 screenSession->SetSupportedRefreshRate({actualRefreshRate});
10163 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::UPDATE_REFRESHRATE);
10164 return DMError::DM_OK;
10165 }
10166
OnScreenCaptureNotify(ScreenId mainScreenId,int32_t uid,const std::string & clientName)10167 void ScreenSessionManager::OnScreenCaptureNotify(ScreenId mainScreenId, int32_t uid, const std::string& clientName)
10168 {
10169 auto clientProxy = GetClientProxy();
10170 if (!clientProxy) {
10171 TLOGI(WmsLogTag::DMS, "clientProxy_ is null");
10172 return;
10173 }
10174 clientProxy->ScreenCaptureNotify(mainScreenId, uid, clientName);
10175 }
10176
AddPermissionUsedRecord(const std::string & permission,int32_t successCount,int32_t failCount)10177 void ScreenSessionManager::AddPermissionUsedRecord(const std::string& permission, int32_t successCount,
10178 int32_t failCount)
10179 {
10180 int32_t ret = Security::AccessToken::PrivacyKit::AddPermissionUsedRecord(IPCSkeleton::GetCallingTokenID(),
10181 permission, successCount, failCount);
10182 if (ret != 0) {
10183 TLOGW(WmsLogTag::DMS, "permission:%{public}s, successCount %{public}d, failedCount %{public}d",
10184 permission.c_str(), successCount, failCount);
10185 }
10186 }
10187
GetScreenCapture(const CaptureOption & captureOption,DmErrorCode * errorCode)10188 std::shared_ptr<Media::PixelMap> ScreenSessionManager::GetScreenCapture(const CaptureOption& captureOption,
10189 DmErrorCode* errorCode)
10190 {
10191 TLOGI(WmsLogTag::DMS, "enter!");
10192 if (errorCode == nullptr) {
10193 TLOGE(WmsLogTag::DMS, "param is null.");
10194 return nullptr;
10195 }
10196 if (system::GetBoolParameter("persist.edm.disallow_screenshot", false)) {
10197 TLOGW(WmsLogTag::DMS, "capture disabled by edm!");
10198 *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
10199 return nullptr;
10200 }
10201 if (!ScreenSceneConfig::IsSupportCapture()) {
10202 TLOGW(WmsLogTag::DMS, "device not support capture.");
10203 *errorCode = DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT;
10204 return nullptr;
10205 }
10206 if (!Permission::CheckCallingPermission(CUSTOM_SCREEN_CAPTURE_PERMISSION) && !SessionPermission::IsShellCall()) {
10207 TLOGE(WmsLogTag::DMS, "Permission Denied! clientName: %{public}s, pid: %{public}d.",
10208 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingRealPid());
10209 *errorCode = DmErrorCode::DM_ERROR_NO_PERMISSION;
10210 return nullptr;
10211 }
10212 if (captureOption.displayId_ == DISPLAY_ID_INVALID ||
10213 (captureOption.displayId_ == DISPLAY_ID_FAKE && !IsFakeDisplayExist())) {
10214 TLOGE(WmsLogTag::DMS, "display id invalid.");
10215 *errorCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
10216 return nullptr;
10217 }
10218 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetScreenCapture(%" PRIu64")", captureOption.displayId_);
10219 auto res = GetScreenSnapshot(captureOption.displayId_, false);
10220 AddPermissionUsedRecord(CUSTOM_SCREEN_CAPTURE_PERMISSION,
10221 static_cast<int32_t>(res != nullptr), static_cast<int32_t>(res == nullptr));
10222 if (res == nullptr) {
10223 TLOGE(WmsLogTag::DMS, "get capture null.");
10224 *errorCode = DmErrorCode::DM_ERROR_SYSTEM_INNORMAL;
10225 return nullptr;
10226 }
10227 NotifyScreenshot(captureOption.displayId_);
10228 if (SessionPermission::IsBetaVersion()) {
10229 CheckAndSendHiSysEvent("GET_DISPLAY_SNAPSHOT", "hmos.screenshot");
10230 }
10231 *errorCode = DmErrorCode::DM_OK;
10232 isScreenShot_ = true;
10233 /* notify scb to do toast */
10234 OnScreenCaptureNotify(GetDefaultScreenId(), IPCSkeleton::GetCallingUid(), SysCapUtil::GetClientName());
10235 /* notify application capture happend */
10236 NotifyCaptureStatusChanged();
10237 return res;
10238 }
10239
GetPrimaryDisplayInfo()10240 sptr<DisplayInfo> ScreenSessionManager::GetPrimaryDisplayInfo()
10241 {
10242 sptr<ScreenSession> screenSession = nullptr;
10243 {
10244 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
10245 for (auto sessionIt : screenSessionMap_) {
10246 sptr<ScreenSession> session = sessionIt.second;
10247 if (session == nullptr) {
10248 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
10249 continue;
10250 }
10251 if (!session->GetIsExtend()) {
10252 TLOGD(WmsLogTag::DMS, "find primary %{public}" PRIu64, session->screenId_);
10253 screenSession = session;
10254 break;
10255 }
10256 }
10257 }
10258 if (screenSession == nullptr) {
10259 TLOGW(WmsLogTag::DMS, "get extend screen faild use default!");
10260 screenSession = GetScreenSession(GetDefaultScreenId());
10261 }
10262 if (screenSession) {
10263 std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
10264 sptr<DisplayInfo> displayInfo = screenSession->ConvertToDisplayInfo();
10265 if (displayInfo == nullptr) {
10266 TLOGI(WmsLogTag::DMS, "convert display error.");
10267 return nullptr;
10268 }
10269 displayInfo = HookDisplayInfoByUid(displayInfo, screenSession);
10270 return displayInfo;
10271 } else {
10272 TLOGE(WmsLogTag::DMS, "failed");
10273 return nullptr;
10274 }
10275 }
10276
OnSuperFoldStatusChange(ScreenId screenId,SuperFoldStatus superFoldStatus)10277 void ScreenSessionManager::OnSuperFoldStatusChange(ScreenId screenId, SuperFoldStatus superFoldStatus)
10278 {
10279 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", superFoldStatus: %{public}d", screenId,
10280 static_cast<uint32_t>(superFoldStatus));
10281 auto clientProxy = GetClientProxy();
10282 if (!clientProxy) {
10283 TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
10284 return;
10285 }
10286 clientProxy->OnSuperFoldStatusChanged(screenId, superFoldStatus);
10287 }
10288
OnExtendScreenConnectStatusChange(ScreenId screenId,ExtendScreenConnectStatus extendScreenConnectStatus)10289 void ScreenSessionManager::OnExtendScreenConnectStatusChange(ScreenId screenId,
10290 ExtendScreenConnectStatus extendScreenConnectStatus)
10291 {
10292 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", extendScreenConnectStatus: %{public}d", screenId,
10293 static_cast<uint32_t>(extendScreenConnectStatus));
10294 auto clientProxy = GetClientProxy();
10295 if (!clientProxy) {
10296 TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
10297 return;
10298 }
10299 clientProxy->OnExtendScreenConnectStatusChanged(screenId, extendScreenConnectStatus);
10300 }
10301
OnSecondaryReflexionChange(ScreenId screenId,bool isSecondaryReflexion)10302 void ScreenSessionManager::OnSecondaryReflexionChange(ScreenId screenId, bool isSecondaryReflexion)
10303 {
10304 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", isSecondaryReflexion: %{public}d", screenId,
10305 isSecondaryReflexion);
10306 auto clientProxy = GetClientProxy();
10307 if (!clientProxy) {
10308 TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
10309 return;
10310 }
10311 clientProxy->OnSecondaryReflexionChanged(screenId, isSecondaryReflexion);
10312 }
10313
OnBeforeScreenPropertyChange(FoldStatus foldStatus)10314 void ScreenSessionManager::OnBeforeScreenPropertyChange(FoldStatus foldStatus)
10315 {
10316 TLOGI(WmsLogTag::DMS, "foldstatus: %{public}d", foldStatus);
10317 if (!FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice()) {
10318 return;
10319 }
10320 if (!clientProxy_) {
10321 TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
10322 return;
10323 }
10324 clientProxy_->OnBeforeScreenPropertyChanged(foldStatus);
10325 }
10326
GetCameraStatus()10327 int32_t ScreenSessionManager::GetCameraStatus()
10328 {
10329 return cameraStatus_;
10330 }
10331
GetCameraPosition()10332 int32_t ScreenSessionManager::GetCameraPosition()
10333 {
10334 return cameraPosition_;
10335 }
10336
IsScreenCasting()10337 bool ScreenSessionManager::IsScreenCasting()
10338 {
10339 if (virtualScreenCount_ > 0 || hdmiScreenCount_ > 0) {
10340 TLOGI(WmsLogTag::DMS, "virtualScreenCount_: %{public}" PRIu32 ", hdmiScreenCount_: %{public}d",
10341 virtualScreenCount_, hdmiScreenCount_);
10342 return true;
10343 }
10344 TLOGI(WmsLogTag::DMS, "not casting");
10345 return false;
10346 }
10347
GetSessionOption(sptr<ScreenSession> screenSession)10348 SessionOption ScreenSessionManager::GetSessionOption(sptr<ScreenSession> screenSession)
10349 {
10350 SessionOption option = {
10351 .rsId_ = screenSession->GetRSScreenId(),
10352 .name_ = screenSession->GetName(),
10353 .isExtend_ = screenSession->GetIsExtend(),
10354 .innerName_ = screenSession->GetInnerName(),
10355 .screenId_ = screenSession->GetScreenId(),
10356 };
10357 return option;
10358 }
10359
GetSessionOption(sptr<ScreenSession> screenSession,ScreenId screenId)10360 SessionOption ScreenSessionManager::GetSessionOption(sptr<ScreenSession> screenSession, ScreenId screenId)
10361 {
10362 SessionOption option = {
10363 .rsId_ = screenSession->GetRSScreenId(),
10364 .name_ = screenSession->GetName(),
10365 .isExtend_ = screenSession->GetIsExtend(),
10366 .innerName_ = screenSession->GetInnerName(),
10367 .screenId_ = screenId,
10368 };
10369 return option;
10370 }
10371
SetScreenSkipProtectedWindow(const std::vector<ScreenId> & screenIds,bool isEnable)10372 DMError ScreenSessionManager::SetScreenSkipProtectedWindow(const std::vector<ScreenId>& screenIds, bool isEnable)
10373 {
10374 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
10375 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
10376 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
10377 return DMError::DM_ERROR_NOT_SYSTEM_APP;
10378 }
10379 std::ostringstream oss;
10380 for (ScreenId screenId : screenIds) {
10381 oss << screenId << " ";
10382 }
10383 TLOGI(WmsLogTag::DMS, "screenIds:%{public}s, isEnable:%{public}d", oss.str().c_str(), isEnable);
10384 {
10385 std::lock_guard<std::mutex> lock(shareProtectMutex_);
10386 for (ScreenId screenId : screenIds) {
10387 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
10388 if (screenSession == nullptr) {
10389 continue;
10390 }
10391 if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
10392 ScreenId rsScreenId = INVALID_SCREEN_ID;
10393 if (!screenIdManager_.ConvertToRsScreenId(screenSession->GetScreenId(), rsScreenId) ||
10394 rsScreenId == INVALID_SCREEN_ID) {
10395 TLOGE(WmsLogTag::DMS, "No corresponding rsId:%{public}" PRIu64 "", rsScreenId);
10396 continue;
10397 }
10398 TLOGI(WmsLogTag::DMS, "virtualScreenId:%{public}" PRIu64 "", screenId);
10399 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
10400 "SetCastScreenEnableSkipWindow(%" PRIu64")", screenId);
10401 rsInterface_.SetCastScreenEnableSkipWindow(rsScreenId, isEnable);
10402 }
10403 }
10404 }
10405 return DMError::DM_OK;
10406 }
10407
IsSpecialApp()10408 bool ScreenSessionManager::IsSpecialApp()
10409 {
10410 if (!FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() &&
10411 !FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
10412 return false;
10413 }
10414 static std::chrono::steady_clock::time_point lastRequestTime = std::chrono::steady_clock::now();
10415 auto currentTime = std::chrono::steady_clock::now();
10416 auto interval = std::chrono::duration_cast<std::chrono::microseconds>(currentTime - lastRequestTime).count();
10417 std::string bundleName = NO_EXIST_BUNDLE_MANE;
10418 int32_t currentPid = IPCSkeleton::GetCallingPid();
10419 if (interval < MAX_INTERVAL_US) {
10420 bundleName = g_uidVersionMap.Get(currentPid);
10421 }
10422 if (bundleName == NO_EXIST_BUNDLE_MANE) {
10423 bundleName = SysCapUtil::GetBundleName();
10424 TLOGI(WmsLogTag::DMS, "Get BundleName from IPC pid: %{public}d name: %{public}s",
10425 currentPid, bundleName.c_str());
10426 g_uidVersionMap.Set(currentPid, bundleName);
10427 }
10428 lastRequestTime = currentTime;
10429 TLOGD(WmsLogTag::DMS, "bundleName: %{public}s", bundleName.c_str());
10430 auto it = g_packageNames_.find(bundleName);
10431 if (it != g_packageNames_.end()) {
10432 TLOGI(WmsLogTag::DMS, "Is Special App");
10433 return true;
10434 }
10435 return false;
10436 }
10437
UpdateValidArea(ScreenId screenId,uint32_t validWidth,uint32_t validHeight)10438 void ScreenSessionManager::UpdateValidArea(ScreenId screenId, uint32_t validWidth, uint32_t validHeight)
10439 {
10440 auto screenSession = GetScreenSession(screenId);
10441 if (!screenSession) {
10442 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
10443 return;
10444 }
10445 screenSession->SetValidWidth(validWidth);
10446 screenSession->SetValidHeight(validHeight);
10447 }
10448
GetIsRealScreen(ScreenId screenId)10449 bool ScreenSessionManager::GetIsRealScreen(ScreenId screenId)
10450 {
10451 if (!SessionPermission::IsSystemCalling()) {
10452 TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
10453 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
10454 return false;
10455 }
10456 auto screenSession = GetScreenSession(screenId);
10457 if (!screenSession) {
10458 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
10459 return false;
10460 }
10461 return screenSession->GetIsRealScreen();
10462 }
10463
SetSystemKeyboardStatus(bool isTpKeyboardOn)10464 DMError ScreenSessionManager::SetSystemKeyboardStatus(bool isTpKeyboardOn)
10465 {
10466 if (!SessionPermission::IsSACalling()) {
10467 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
10468 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
10469 return DMError::DM_ERROR_NOT_SYSTEM_APP;
10470 }
10471 #ifdef FOLD_ABILITY_ENABLE
10472 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
10473 SuperFoldStateManager::GetInstance().SetSystemKeyboardStatus(isTpKeyboardOn);
10474 return DMError::DM_OK;
10475 }
10476 #endif // FOLD_ABILITY_ENABLE
10477 return DMError::DM_ERROR_DEVICE_NOT_SUPPORT;
10478 }
10479
WakeUpPictureFrameBlock(DisplayEvent event)10480 void ScreenSessionManager::WakeUpPictureFrameBlock(DisplayEvent event)
10481 {
10482 std::unique_lock <std::mutex> lock(screenWaitPictureFrameMutex_);
10483 if (event == DisplayEvent::SCREEN_LOCK_START_DREAM) {
10484 TLOGI(WmsLogTag::DMS, "[UL_POWER]get pictureFrameReady");
10485 pictureFrameReady_ = true;
10486 } else if (event == DisplayEvent::SCREEN_LOCK_END_DREAM) {
10487 TLOGI(WmsLogTag::DMS, "[UL_POWER]get pictureFrameBreak");
10488 pictureFrameBreak_ = true;
10489 } else {
10490 return;
10491 }
10492 TLOGI(WmsLogTag::DMS, "[UL_POWER]notify block");
10493 screenWaitPictureFrameCV_.notify_all();
10494 }
10495
BlockScreenWaitPictureFrameByCV(bool isStartDream)10496 bool ScreenSessionManager::BlockScreenWaitPictureFrameByCV(bool isStartDream)
10497 {
10498 TLOGI(WmsLogTag::DMS, "[UL_POWER]enter");
10499 std::unique_lock <std::mutex> lock(screenWaitPictureFrameMutex_);
10500 pictureFrameReady_ = false;
10501 pictureFrameBreak_ = false;
10502 if (screenWaitPictureFrameCV_.wait_for(lock, std::chrono::milliseconds(SCREEN_WAIT_PICTURE_FRAME_TIME))
10503 == std::cv_status::timeout) {
10504 TLOGI(WmsLogTag::DMS, "[UL_POWER]wait picture frame timeout");
10505 return true;
10506 }
10507 bool pictureFrameIsOk = isStartDream ? pictureFrameReady_ : pictureFrameBreak_;
10508 TLOGI(WmsLogTag::DMS, "[UL_POWER]pictureFrameIsOk:%{public}d", pictureFrameIsOk);
10509 return pictureFrameIsOk;
10510 }
10511
SetForceCloseHdr(ScreenId screenId,bool isForceCloseHdr)10512 void ScreenSessionManager::SetForceCloseHdr(ScreenId screenId, bool isForceCloseHdr)
10513 {
10514 if (!SessionPermission::IsSystemCalling()) {
10515 TLOGE(WmsLogTag::DMS, "permission denied!");
10516 return;
10517 }
10518 auto screenSession = GetScreenSession(screenId);
10519 if (!screenSession) {
10520 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
10521 return;
10522 }
10523 TLOGI(WmsLogTag::DMS, "[UL_POWER]screenId:%{public}" PRIu64 "isForceCloseHdr:%{public}d",
10524 screenId, isForceCloseHdr);
10525 screenSession->SetForceCloseHdr(isForceCloseHdr);
10526 }
10527
RegisterSettingExtendScreenDpiObserver()10528 void ScreenSessionManager::RegisterSettingExtendScreenDpiObserver()
10529 {
10530 TLOGI(WmsLogTag::DMS, "Register Setting Extend Dpi Observer");
10531 SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetExtendScreenDpi(); };
10532 ScreenSettingHelper::RegisterSettingExtendScreenDpiObserver(updateFunc);
10533 }
10534
SetExtendScreenDpi()10535 void ScreenSessionManager::SetExtendScreenDpi()
10536 {
10537 float extendScreenDpiCoef = EXTEND_SCREEN_DPI_DEFAULT_PARAMETER;
10538 bool ret = ScreenSettingHelper::GetSettingExtendScreenDpi(extendScreenDpiCoef);
10539 if (!ret) {
10540 TLOGE(WmsLogTag::DMS, "get setting extend screen dpi failed");
10541 g_extendScreenDpiCoef = EXTEND_SCREEN_DPI_DEFAULT_PARAMETER;
10542 } else {
10543 g_extendScreenDpiCoef = extendScreenDpiCoef;
10544 }
10545 float dpi = static_cast<float>(cachedSettingDpi_) / BASELINE_DENSITY;
10546 SetExtendPixelRatio(dpi * g_extendScreenDpiCoef);
10547 TLOGI(WmsLogTag::DMS, "get setting extend screen dpi is : %{public}f", g_extendScreenDpiCoef);
10548 }
10549
GetFakePhysicalScreenSession(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)10550 sptr<ScreenSession> ScreenSessionManager::GetFakePhysicalScreenSession(ScreenId screenId, ScreenId defScreenId,
10551 ScreenProperty property)
10552 {
10553 sptr<ScreenSession> screenSession = nullptr;
10554 ScreenSessionConfig config;
10555 if (g_isPcDevice) {
10556 config = {
10557 .screenId = screenId,
10558 .rsId = screenId,
10559 .defaultScreenId = defScreenId,
10560 .property = property,
10561 };
10562 screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
10563 }
10564 return screenSession;
10565 }
10566
CreateFakePhysicalMirrorSessionInner(ScreenId screenId,ScreenId defScreenId,ScreenProperty property)10567 sptr<ScreenSession> ScreenSessionManager::CreateFakePhysicalMirrorSessionInner(ScreenId screenId, ScreenId defScreenId,
10568 ScreenProperty property)
10569 {
10570 #ifdef WM_MULTI_SCREEN_ENABLE
10571 sptr<ScreenSession> screenSession = nullptr;
10572 if (system::GetBoolParameter("persist.edm.disallow_mirror", false)) {
10573 TLOGW(WmsLogTag::DMS, "mirror disabled by edm!");
10574 return screenSession;
10575 }
10576 screenSession = GetFakePhysicalScreenSession(screenId, defScreenId, property);
10577 if (!screenSession) {
10578 TLOGE(WmsLogTag::DMS, "screenSession is null");
10579 return nullptr;
10580 }
10581 if (g_isPcDevice) {
10582 InitExtendScreenProperty(screenId, screenSession, property);
10583 screenSession->SetName(SCREEN_NAME_EXTEND);
10584 screenSession->SetIsExtend(true);
10585 screenSession->SetScreenCombination(ScreenCombination::SCREEN_EXTEND);
10586 } else {
10587 screenSession->SetIsExtend(true);
10588 screenSession->SetName(SCREEN_NAME_CAST);
10589 screenSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR);
10590 screenSession->SetVirtualScreenFlag(VirtualScreenFlag::CAST);
10591 }
10592 GetAndMergeEdidInfo(screenSession);
10593 screenSession->SetMirrorScreenType(MirrorScreenType::PHYSICAL_MIRROR);
10594 screenSession->SetIsPcUse(g_isPcDevice ? true : false);
10595 screenSession->SetIsInternal(false);
10596 screenSession->SetIsRealScreen(true);
10597 screenSession->SetIsCurrentInUse(true);
10598 return screenSession;
10599 #else
10600 return nullptr;
10601 #endif
10602 }
10603
GetPhysicalScreenSessionInner(ScreenId screenId,ScreenProperty property)10604 sptr<ScreenSession> ScreenSessionManager::GetPhysicalScreenSessionInner(ScreenId screenId, ScreenProperty property)
10605 {
10606 ScreenId defScreenId = GetDefaultScreenId();
10607 TLOGW(WmsLogTag::DMS, "screenId:%{public}" PRIu64, screenId);
10608 if (IsDefaultMirrorMode(screenId)) {
10609 #ifdef WM_MULTI_SCREEN_ENABLE
10610 return CreateFakePhysicalMirrorSessionInner(screenId, defScreenId, property);
10611 #else
10612 return nullptr;
10613 #endif
10614 }
10615 std::string screenName = "UNKNOWN";
10616 if (screenId == SCREEN_ID_MAIN) {
10617 screenName = "SubScreen";
10618 }
10619 ScreenSessionConfig config = {
10620 .screenId = screenId,
10621 .defaultScreenId = defScreenId,
10622 .name = screenName,
10623 .property = property,
10624 };
10625 sptr<ScreenSession> screenSession = nullptr;
10626 screenSession = new ScreenSession(config, ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE);
10627 screenSession->SetIsExtend(false);
10628 screenSession->SetScreenCombination(ScreenCombination::SCREEN_MAIN);
10629 screenSession->SetIsInternal(true);
10630 screenSession->SetIsRealScreen(true);
10631 screenSession->SetIsCurrentInUse(true);
10632 screenSession->SetIsPcUse(g_isPcDevice ? true : false);
10633 return screenSession;
10634 }
10635
GetOrCreatePhysicalScreenSession(ScreenId screenId)10636 sptr<ScreenSession> ScreenSessionManager::GetOrCreatePhysicalScreenSession(ScreenId screenId)
10637 {
10638 TLOGW(WmsLogTag::DMS, "ENTER. ScreenId: %{public}" PRIu64, screenId);
10639 sptr<ScreenSession> screenSession = GetPhysicalScreenSession(screenId);
10640 if (screenSession) {
10641 TLOGW(WmsLogTag::DMS, "physical screen Exist ScreenId: %{public}" PRIu64, screenId);
10642 return screenSession;
10643 }
10644
10645 ScreenProperty property;
10646 CreateScreenProperty(screenId, property);
10647 TLOGW(WmsLogTag::DMS, "create screen property end");
10648
10649 sptr<ScreenSession> session = GetPhysicalScreenSessionInner(screenId, property);
10650 if (session == nullptr) {
10651 TLOGE(WmsLogTag::DMS, "get physical screen fail ScreenId: %{public}" PRIu64, screenId);
10652 return session;
10653 }
10654 InitExtendScreenDensity(session, property);
10655 InitAbstractScreenModesInfo(session);
10656 session->groupSmsId_ = 1;
10657 {
10658 std::lock_guard<std::recursive_mutex> lock(physicalScreenSessionMapMutex_);
10659 physicalScreenSessionMap_[screenId] = session;
10660 }
10661 SetHdrFormats(screenId, session);
10662 SetColorSpaces(screenId, session);
10663 SetSupportedRefreshRate(session);
10664 TLOGW(WmsLogTag::DMS, "Create success. ScreenId: %{public}" PRIu64, screenId);
10665 return session;
10666 }
10667
GetScreenSessionByRsId(ScreenId rsScreenId)10668 sptr<ScreenSession> ScreenSessionManager::GetScreenSessionByRsId(ScreenId rsScreenId)
10669 {
10670 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
10671 for (auto sessionIt : screenSessionMap_) {
10672 sptr<ScreenSession> screenSession = sessionIt.second;
10673 if (screenSession == nullptr) {
10674 TLOGE(WmsLogTag::DMS, "screenSession is nullptr!");
10675 continue;
10676 }
10677 if (screenSession->GetRSScreenId() == rsScreenId) {
10678 TLOGI(WmsLogTag::DMS, "found rsScreenId = %{public}" PRIu64, rsScreenId);
10679 return screenSession;
10680 }
10681 }
10682 return nullptr;
10683 }
10684
GetPhysicalScreenSession(ScreenId screenId) const10685 sptr<ScreenSession> ScreenSessionManager::GetPhysicalScreenSession(ScreenId screenId) const
10686 {
10687 {
10688 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
10689 if (screenSessionMap_.empty()) {
10690 screenEventTracker_.LogWarningAllInfos();
10691 }
10692 }
10693
10694 std::lock_guard<std::recursive_mutex> lock(physicalScreenSessionMapMutex_);
10695 auto iter = physicalScreenSessionMap_.find(screenId);
10696 if (iter == physicalScreenSessionMap_.end()) {
10697 TLOGW(WmsLogTag::DMS, "not found screen id: %{public}" PRIu64, screenId);
10698 return nullptr;
10699 }
10700 return iter->second;
10701 }
10702
NotifyExtendScreenCreateFinish()10703 void ScreenSessionManager::NotifyExtendScreenCreateFinish()
10704 {
10705 if (!SessionPermission::IsSystemCalling()) {
10706 TLOGE(WmsLogTag::DMS, "permission denied!");
10707 return;
10708 }
10709 if (!g_isPcDevice) {
10710 TLOGW(WmsLogTag::DMS, "not pc device.");
10711 return;
10712 }
10713 sptr<ScreenSession> mainScreen = nullptr;
10714 sptr<ScreenSession> extendScreen = nullptr;
10715 {
10716 std::lock_guard<std::recursive_mutex> lock(screenSessionMapMutex_);
10717 for (auto sessionIt : screenSessionMap_) {
10718 auto screenSession = sessionIt.second;
10719 if (screenSession == nullptr) {
10720 TLOGE(WmsLogTag::DMS, "screenSession is nullptr.");
10721 continue;
10722 }
10723 if (!screenSession->GetIsCurrentInUse()) {
10724 continue;
10725 }
10726 if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
10727 mainScreen = screenSession;
10728 } else {
10729 extendScreen = screenSession;
10730 }
10731 }
10732 }
10733 if (mainScreen == nullptr) {
10734 TLOGE(WmsLogTag::DMS, "main screen is null");
10735 return;
10736 }
10737 NotifyCreatedScreen(mainScreen);
10738 if (extendScreen == nullptr) {
10739 TLOGE(WmsLogTag::DMS, "extend screen is null");
10740 return;
10741 }
10742 NotifyCreatedScreen(extendScreen);
10743 }
10744
UpdateScreenIdManager(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)10745 void ScreenSessionManager::UpdateScreenIdManager(sptr<ScreenSession>& innerScreen,
10746 sptr<ScreenSession>& externalScreen)
10747 {
10748 ScreenId innerScreenId = innerScreen->GetRSScreenId();
10749 ScreenId externalScreenId = externalScreen->GetRSScreenId();
10750 screenIdManager_.UpdateScreenId(externalScreenId, innerScreen->GetScreenId());
10751 screenIdManager_.UpdateScreenId(innerScreenId, externalScreen->GetScreenId());
10752 }
10753
DumperClientScreenSessions()10754 std::string ScreenSessionManager::DumperClientScreenSessions()
10755 {
10756 std::string clientSessions = "";
10757 auto clientProxy = GetClientProxy();
10758 if (clientProxy) {
10759 clientSessions = clientProxy->OnDumperClientScreenSessions();
10760 }
10761 return clientSessions;
10762 }
10763
SetMultiScreenModeChangeTracker(std::string changeProc)10764 void ScreenSessionManager::SetMultiScreenModeChangeTracker(std::string changeProc)
10765 {
10766 screenEventTracker_.RecordEvent(changeProc);
10767 }
10768
NotifyCreatedScreen(sptr<ScreenSession> screenSession)10769 void ScreenSessionManager::NotifyCreatedScreen(sptr<ScreenSession> screenSession)
10770 {
10771 if (!g_isPcDevice) {
10772 TLOGW(WmsLogTag::DMS, "not pc device.");
10773 return;
10774 }
10775 if (screenSession == nullptr) {
10776 TLOGE(WmsLogTag::DMS, "screenSession is null");
10777 return;
10778 }
10779 std::ostringstream oss;
10780 oss << "screenId: " << screenSession->GetScreenId()
10781 << ", rsId: " << screenSession->GetRSScreenId();
10782 oss << std::endl;
10783 TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
10784 if (screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
10785 TLOGW(WmsLogTag::DMS, "mirror, no need to notify.");
10786 return;
10787 }
10788 ScreenProperty property = screenSession->GetScreenProperty();
10789 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice()) {
10790 TLOGW(WmsLogTag::DMS, "super fold device, change by rotation.");
10791 screenSession->PropertyChange(property, ScreenPropertyChangeReason::ROTATION);
10792 } else {
10793 screenSession->PropertyChange(property, ScreenPropertyChangeReason::UNDEFINED);
10794 }
10795 NotifyScreenChanged(screenSession->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
10796 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
10797 }
10798
NotifyExtendScreenDestroyFinish()10799 void ScreenSessionManager::NotifyExtendScreenDestroyFinish()
10800 {
10801 if (!SessionPermission::IsSystemCalling()) {
10802 TLOGE(WmsLogTag::DMS, "permission denied!");
10803 return;
10804 }
10805 if (!g_isPcDevice) {
10806 TLOGW(WmsLogTag::DMS, "not pc device.");
10807 return;
10808 }
10809 TLOGI(WmsLogTag::DMS, "destroy finish, notify block");
10810 switchUserCV_.notify_all();
10811 userSwitching_ = false;
10812 }
10813
SetRSScreenPowerStatus(ScreenId screenId,ScreenPowerStatus status)10814 void ScreenSessionManager::SetRSScreenPowerStatus(ScreenId screenId, ScreenPowerStatus status)
10815 {
10816 rsInterface_.SetScreenPowerStatus(screenId, status);
10817 if (status == ScreenPowerStatus::POWER_STATUS_ON) {
10818 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
10819 uint32_t ret = DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().NotifyBrightnessManagerScreenPowerStatus(
10820 static_cast<uint32_t>(screenId), static_cast<uint32_t>(status));
10821 TLOGI(WmsLogTag::DMS, "notify brightness, screenId:%{public}" PRIu64 ", status:%{public}u, ret = %{public}u",
10822 screenId, static_cast<uint32_t>(status), ret);
10823 #endif
10824 }
10825 }
10826
OnScreenModeChange(ScreenModeChangeEvent screenModeChangeEvent)10827 void ScreenSessionManager::OnScreenModeChange(ScreenModeChangeEvent screenModeChangeEvent)
10828 {
10829 TLOGI(WmsLogTag::DMS, "screenModeChangeEvent: %{public}d", static_cast<uint32_t>(screenModeChangeEvent));
10830 auto clientProxy = GetClientProxy();
10831 if (!clientProxy) {
10832 TLOGE(WmsLogTag::DMS, "clientProxy_ is null");
10833 return;
10834 }
10835 clientProxy->OnScreenModeChanged(screenModeChangeEvent);
10836 }
10837
NotifyScreenMaskAppear()10838 void ScreenSessionManager::NotifyScreenMaskAppear()
10839 {
10840 if (!SessionPermission::IsSystemCalling()) {
10841 TLOGE(WmsLogTag::DMS, "Permission Denied.calling: %{public}s, pid: %{public}d",
10842 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
10843 return;
10844 }
10845 if (!g_isPcDevice) {
10846 TLOGW(WmsLogTag::DMS, "not pc device.");
10847 return;
10848 }
10849 TLOGI(WmsLogTag::DMS, "screen mask appeared, notify block");
10850 screenMaskCV_.notify_all();
10851 }
10852
GetKeyboardState()10853 bool ScreenSessionManager::GetKeyboardState()
10854 {
10855 #ifdef FOLD_ABILITY_ENABLE
10856 return SuperFoldStateManager::GetInstance().GetKeyboardState();
10857 #endif
10858 return false;
10859 }
10860
GetScreenAreaOfDisplayArea(DisplayId displayId,const DMRect & displayArea,ScreenId & screenId,DMRect & screenArea)10861 DMError ScreenSessionManager::GetScreenAreaOfDisplayArea(DisplayId displayId, const DMRect& displayArea,
10862 ScreenId& screenId, DMRect& screenArea)
10863 {
10864 TLOGI(WmsLogTag::DMS, "displayId:%{public}" PRIu64 ",displayArea:%{public}d,%{public}d,%{public}d,%{public}d",
10865 displayId, displayArea.posX_, displayArea.posY_, displayArea.width_, displayArea.height_);
10866 auto displayInfo = GetDisplayInfoById(displayId);
10867 if (displayInfo == nullptr) {
10868 TLOGE(WmsLogTag::DMS, "can not get displayInfo");
10869 return DMError::DM_ERROR_NULLPTR;
10870 }
10871 DMRect displayRegion =
10872 { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(), displayInfo->GetWidth(), displayInfo->GetHeight() };
10873 if (!displayArea.IsInsideOf(displayRegion)) {
10874 TLOGE(WmsLogTag::DMS, "displayArea is outSide of displayRegion");
10875 return DMError::DM_ERROR_INVALID_PARAM;
10876 }
10877 screenId = displayInfo->GetScreenId();
10878 auto screenSession = GetScreenSession(screenId);
10879 if (screenSession == nullptr) {
10880 TLOGE(WmsLogTag::DMS, "screenSession is nullptr");
10881 return DMError::DM_ERROR_INVALID_PARAM;
10882 }
10883 RRect bounds = screenSession->GetScreenProperty().GetPhyBounds();
10884 DMRect screenRegion =
10885 { bounds.rect_.GetLeft(), bounds.rect_.GetTop(), bounds.rect_.GetWidth(), bounds.rect_.GetHeight() };
10886 DMRect displayAreaFixed = displayArea;
10887 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && GetFoldStatus() == FoldStatus::HALF_FOLD) {
10888 if (displayId == DISPLAY_ID_FAKE) {
10889 displayAreaFixed.posY_ += screenRegion.height_ - displayRegion.height_;
10890 }
10891 displayRegion.height_ = screenRegion.height_;
10892 } else if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice() && GetFoldDisplayMode() == FoldDisplayMode::FULL) {
10893 switch (displayInfo->GetRotation()) {
10894 case Rotation::ROTATION_0:
10895 displayRegion.posX_ = FULL_STATUS_OFFSET_X;
10896 displayAreaFixed.posX_ += FULL_STATUS_OFFSET_X;
10897 break;
10898 case Rotation::ROTATION_90:
10899 displayRegion.posY_ = FULL_STATUS_OFFSET_X;
10900 displayAreaFixed.posY_ += FULL_STATUS_OFFSET_X;
10901 break;
10902 default:
10903 break;
10904 }
10905 }
10906 CalculateRotatedDisplay(displayInfo->GetRotation(), screenRegion, displayRegion, displayAreaFixed);
10907 CalculateScreenArea(displayRegion, displayAreaFixed, screenRegion, screenArea);
10908 TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 ",screenArea:%{public}d,%{public}d,%{public}d,%{public}d",
10909 screenId, screenArea.posX_, screenArea.posY_, screenArea.width_, screenArea.height_);
10910 return DMError::DM_OK;
10911 }
10912
CalculateRotatedDisplay(Rotation rotation,const DMRect & screenRegion,DMRect & displayRegion,DMRect & displayArea)10913 void ScreenSessionManager::CalculateRotatedDisplay(Rotation rotation, const DMRect& screenRegion,
10914 DMRect& displayRegion, DMRect& displayArea)
10915 {
10916 std::vector<std::string> phyOffsets = FoldScreenStateInternel::GetPhyRotationOffset();
10917 int32_t phyOffset = 0;
10918 if (phyOffsets.size() > 1 &&
10919 (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice() || GetFoldStatus() != FoldStatus::FOLDED)) {
10920 if (!ScreenSettingHelper::ConvertStrToInt32(phyOffsets[1], phyOffset)) {
10921 TLOGE(WmsLogTag::DMS, "transfer phyOffset1 failed.");
10922 return;
10923 }
10924 } else if (phyOffsets.size() > 0) {
10925 if (!ScreenSettingHelper::ConvertStrToInt32(phyOffsets[0], phyOffset)) {
10926 TLOGE(WmsLogTag::DMS, "transfer phyOffset0 failed.");
10927 return;
10928 }
10929 }
10930 Rotation phyOffsetRotation = ConvertIntToRotation(phyOffset);
10931 uint32_t correctedRotation = (static_cast<uint32_t>(rotation) + static_cast<uint32_t>(phyOffsetRotation)) %
10932 ROTATION_MOD;
10933 DMRect displayRegionCopy = displayRegion;
10934 DMRect displayAreaCopy = displayArea;
10935 switch (static_cast<Rotation>(correctedRotation)) {
10936 case Rotation::ROTATION_90:
10937 displayRegion.width_ = displayRegionCopy.height_;
10938 displayRegion.height_ = displayRegionCopy.width_;
10939 displayArea.width_ = displayAreaCopy.height_;
10940 displayArea.height_ = displayAreaCopy.width_;
10941 displayRegion.posX_ = displayRegionCopy.posY_;
10942 displayRegion.posY_ = static_cast<int32_t>(screenRegion.width_) -
10943 (displayRegionCopy.posX_ + static_cast<int32_t>(displayRegionCopy.width_));
10944 displayArea.posX_ = displayAreaCopy.posY_;
10945 displayArea.posY_ = static_cast<int32_t>(screenRegion.width_) -
10946 (displayAreaCopy.posX_ + static_cast<int32_t>(displayAreaCopy.width_));
10947 break;
10948 case Rotation::ROTATION_180:
10949 displayRegion.posX_ = static_cast<int32_t>(screenRegion.width_) -
10950 (displayRegionCopy.posX_ + static_cast<int32_t>(displayRegionCopy.width_));
10951 displayRegion.posY_ = static_cast<int32_t>(screenRegion.height_) -
10952 (displayRegionCopy.posY_ + static_cast<int32_t>(displayRegionCopy.height_));
10953 displayArea.posX_ = static_cast<int32_t>(screenRegion.width_) -
10954 (displayAreaCopy.posX_ + static_cast<int32_t>(displayAreaCopy.width_));
10955 displayArea.posY_ = static_cast<int32_t>(screenRegion.height_) -
10956 (displayAreaCopy.posY_ + static_cast<int32_t>(displayAreaCopy.height_));
10957 break;
10958 case Rotation::ROTATION_270:
10959 displayRegion.width_ = displayRegionCopy.height_;
10960 displayRegion.height_ = displayRegionCopy.width_;
10961 displayArea.width_ = displayAreaCopy.height_;
10962 displayArea.height_ = displayAreaCopy.width_;
10963 displayRegion.posX_ = static_cast<int32_t>(screenRegion.height_) -
10964 (displayRegionCopy.posY_ + static_cast<int32_t>(displayRegionCopy.height_));
10965 displayRegion.posY_ = displayRegionCopy.posX_;
10966 displayArea.posX_ = static_cast<int32_t>(screenRegion.height_) -
10967 (displayAreaCopy.posY_ + static_cast<int32_t>(displayAreaCopy.height_));
10968 displayArea.posY_ = displayAreaCopy.posX_;
10969 break;
10970 default:
10971 break;
10972 }
10973 }
10974
CalculateScreenArea(const DMRect & displayRegion,const DMRect & displayArea,const DMRect & screenRegion,DMRect & screenArea)10975 void ScreenSessionManager::CalculateScreenArea(const DMRect& displayRegion, const DMRect& displayArea,
10976 const DMRect& screenRegion, DMRect& screenArea)
10977 {
10978 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
10979 screenArea = displayArea;
10980 return;
10981 }
10982 if (displayRegion == screenRegion) {
10983 screenArea = displayArea;
10984 return;
10985 }
10986 float ratioX = static_cast<float>(displayArea.posX_ - displayRegion.posX_) /
10987 static_cast<float>(displayRegion.width_);
10988 float ratioY = static_cast<float>(displayArea.posY_ - displayRegion.posY_) /
10989 static_cast<float>(displayRegion.height_);
10990 float ratioWidth = static_cast<float>(displayArea.width_) / static_cast<float>(displayRegion.width_);
10991 float ratioHeight = static_cast<float>(displayArea.height_) / static_cast<float>(displayRegion.height_);
10992 screenArea.posX_ = screenRegion.posX_ + static_cast<int32_t>(ratioX * screenRegion.width_);
10993 screenArea.posY_ = screenRegion.posY_ + static_cast<int32_t>(ratioY * screenRegion.height_);
10994 screenArea.width_ = static_cast<uint32_t>(ratioWidth * screenRegion.width_);
10995 screenArea.height_ = static_cast<uint32_t>(ratioHeight * screenRegion.height_);
10996 }
10997
SetPrimaryDisplaySystemDpi(float virtualPixelRatio)10998 DMError ScreenSessionManager::SetPrimaryDisplaySystemDpi(float virtualPixelRatio)
10999 {
11000 sptr<DisplayInfo> displayInfo = GetPrimaryDisplayInfo();
11001 if (displayInfo == nullptr) {
11002 TLOGE(WmsLogTag::DMS, "displayInfo is null.");
11003 return DMError::DM_ERROR_NULLPTR;
11004 }
11005 ScreenId screenId = displayInfo->GetScreenId();
11006 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
11007 if (screenSession == nullptr) {
11008 TLOGE(WmsLogTag::DMS, "screenSession is null.");
11009 return DMError::DM_ERROR_NULLPTR;
11010 }
11011 TLOGI(WmsLogTag::DMS, "displayId: %{public}" PRIu64 " densityInCurResolution: %{public}f",
11012 displayInfo->GetDisplayId(), screenSession->GetDensityInCurResolution());
11013 screenSession->SetDensityInCurResolution(virtualPixelRatio);
11014 return DMError::DM_OK;
11015 }
11016
SetVirtualScreenAutoRotation(ScreenId screenId,bool enable)11017 DMError ScreenSessionManager::SetVirtualScreenAutoRotation(ScreenId screenId, bool enable)
11018 {
11019 TLOGI(WmsLogTag::DMS, "enter");
11020 if (!SessionPermission::IsSystemCalling()) {
11021 TLOGE(WmsLogTag::DMS, "permission denied!");
11022 return DMError::DM_ERROR_INVALID_PERMISSION;
11023 }
11024
11025 ScreenId rsScreenId = SCREEN_ID_INVALID;
11026 bool res = ConvertScreenIdToRsScreenId(screenId, rsScreenId);
11027 if (!res) {
11028 TLOGE(WmsLogTag::DMS, "convert screenId to rsScreenId failed");
11029 return DMError::DM_ERROR_INVALID_PARAM;
11030 }
11031 TLOGI(WmsLogTag::DMS, "unique screenId: %{public}" PRIu64 " rsScreenId: %{public}" PRIu64, screenId, rsScreenId);
11032
11033 auto ret = rsInterface_.SetVirtualScreenAutoRotation(rsScreenId, enable);
11034 if (ret != StatusCode::SUCCESS) {
11035 TLOGE(WmsLogTag::DMS, "rsInterface error: %{public}d", ret);
11036 return DMError::DM_ERROR_INVALID_PARAM;
11037 }
11038 return DMError::DM_OK;
11039 }
11040
SetScreenOffset(ScreenId screenId,float offsetX,float offsetY)11041 bool ScreenSessionManager::SetScreenOffset(ScreenId screenId, float offsetX, float offsetY)
11042 {
11043 sptr<ScreenSession> screenSession = GetScreenSession(screenId);
11044 if (screenSession == nullptr) {
11045 TLOGE(WmsLogTag::DMS, "screenSession is null.");
11046 return false;
11047 }
11048 TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 " rsId_:%{public}" PRIu64 \
11049 " GetRSScreenId:%{public}" PRIu64 " offsetX:%{public}f, offsetY:%{public}f",
11050 screenId, screenSession->rsId_, screenSession->GetRSScreenId(), offsetX, offsetY);
11051 RSInterfaces::GetInstance().SetScreenOffset(screenSession->rsId_, offsetX, offsetY);
11052 return true;
11053 }
11054
SetScreenPrivacyWindowTagSwitch(ScreenId screenId,const std::vector<std::string> & privacyWindowTag,bool enable)11055 DMError ScreenSessionManager::SetScreenPrivacyWindowTagSwitch(ScreenId screenId,
11056 const std::vector<std::string>& privacyWindowTag, bool enable)
11057 {
11058 if (!SessionPermission::IsSystemCalling()) {
11059 TLOGE(WmsLogTag::DMS, "Permission Denied! calling: %{public}s, pid: %{public}d",
11060 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
11061 return DMError::DM_ERROR_NOT_SYSTEM_APP;
11062 }
11063 auto screenSession = GetScreenSession(screenId);
11064 if (screenSession == nullptr) {
11065 TLOGE(WmsLogTag::DMS, "cannot find screenInfo: %{public}" PRIu64, screenId);
11066 return DMError::DM_ERROR_NULLPTR;
11067 }
11068 MockSessionManagerService::GetInstance().SetScreenPrivacyWindowTagSwitch(
11069 screenIdManager_.ConvertToRsScreenId(screenId), privacyWindowTag, enable);
11070 std::ostringstream oss;
11071 for (auto tag : privacyWindowTag) {
11072 oss << tag << ",";
11073 }
11074 TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 " privacyWindowTag:%{public}s, enable:%{public}d", screenId,
11075 oss.str().c_str(), enable);
11076 return DMError::DM_OK;
11077 }
11078 // LCOV_EXCL_STOP
11079
GetPhyScreenId(ScreenId screenId)11080 ScreenId ScreenSessionManager::GetPhyScreenId(ScreenId screenId)
11081 {
11082 if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice() &&
11083 GetCoordinationFlag() && screenId == SCREEN_ID_MAIN) {
11084 TLOGW(WmsLogTag::DMS, "Coordination phyScreen SCREEN_ID_FULL");
11085 return SCREEN_ID_FULL;
11086 }
11087 return screenId;
11088 }
11089
UpdateCoordinationRefreshRate(uint32_t refreshRate)11090 void ScreenSessionManager::UpdateCoordinationRefreshRate(uint32_t refreshRate)
11091 {
11092 if (!FoldScreenStateInternel::IsSecondaryDisplayFoldDevice() || !GetCoordinationFlag()) {
11093 return;
11094 }
11095 sptr<ScreenSession> screenSession = GetScreenSession(SCREEN_ID_MAIN);
11096 if (!screenSession) {
11097 TLOGE(WmsLogTag::DMS, "screenSession SCREEN_ID_MAIN is null");
11098 return;
11099 }
11100 screenSession->UpdateRefreshRate(refreshRate);
11101 NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::UPDATE_REFRESHRATE);
11102 }
11103
SynchronizePowerStatus(ScreenPowerState state)11104 bool ScreenSessionManager::SynchronizePowerStatus(ScreenPowerState state)
11105 {
11106 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
11107 TLOGE(WmsLogTag::DMS, "permission denied! calling: %{public}s, pid: %{public}d",
11108 SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid());
11109 return false;
11110 }
11111 TLOGI(WmsLogTag::DMS, "[UL_POWER] Synchronize power state: %{public}u", static_cast<uint32_t>(state));
11112 #ifdef FOLD_ABILITY_ENABLE
11113 ScreenPowerStatus status = ScreenPowerStatus::INVALID_POWER_STATUS;
11114 if (!GetPowerStatus(state, PowerStateChangeReason::STATE_CHANGE_REASON_SYNCHRONIZE_POWER_STATE, status)) {
11115 TLOGE(WmsLogTag::DMS, "GetPowerStatus failed");
11116 return false;
11117 }
11118 if (foldScreenController_ == nullptr) {
11119 TLOGE(WmsLogTag::DMS, "foldScreenController_ is null");
11120 return false;
11121 }
11122 ScreenId screenId = foldScreenController_->GetCurrentScreenId();
11123 auto rsSetScreenPowerStatusTask = [this, screenId, status] {
11124 SetRSScreenPowerStatus(screenId, status);
11125 };
11126 screenPowerTaskScheduler_->PostVoidSyncTask(rsSetScreenPowerStatusTask, "rsInterface_.SetScreenPowerStatus task");
11127 #endif
11128 return true;
11129 }
11130
GetPowerTaskScheduler() const11131 std::shared_ptr<TaskScheduler> ScreenSessionManager::GetPowerTaskScheduler() const
11132 {
11133 return screenPowerTaskScheduler_;
11134 }
11135
GetCancelSuspendStatus() const11136 bool ScreenSessionManager::GetCancelSuspendStatus() const
11137 {
11138 if (!sessionDisplayPowerController_) {
11139 TLOGE(WmsLogTag::DMS, "sessionDisplayPowerController_ is null");
11140 return false;
11141 }
11142 std::lock_guard<std::mutex> notifyLock(sessionDisplayPowerController_->notifyMutex_);
11143 return sessionDisplayPowerController_->needCancelNotify_ ||
11144 sessionDisplayPowerController_->canceledSuspend_;
11145 }
11146
RegisterSettingDuringCallStateObserver()11147 void ScreenSessionManager::RegisterSettingDuringCallStateObserver()
11148 {
11149 TLOGI(WmsLogTag::DMS, "Register Setting During Call State Observer");
11150 SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { UpdateDuringCallState(); };
11151 ScreenSettingHelper::RegisterSettingDuringCallStateObserver(updateFunc);
11152 }
11153
UpdateDuringCallState()11154 void ScreenSessionManager::UpdateDuringCallState()
11155 {
11156 TLOGI(WmsLogTag::DMS, "update during call state, current state: %{public}d", duringCallState_);
11157 bool ret = ScreenSettingHelper::GetSettingDuringCallState(duringCallState_);
11158 if (!ret) {
11159 TLOGE(WmsLogTag::DMS, "get setting during call state failed");
11160 return;
11161 }
11162 TLOGI(WmsLogTag::DMS, "get setting during call state: %{public}d", duringCallState_);
11163 #ifdef FOLD_ABILITY_ENABLE
11164 if (ScreenSceneConfig::IsSupportDuringCall() && !duringCallState_ && foldScreenController_ != nullptr &&
11165 foldScreenController_->GetDisplayMode() == FoldDisplayMode::SUB) {
11166 TLOGI(WmsLogTag::DMS, "duringcallstate exit, recover displaymode");
11167 foldScreenController_->RecoverDisplayMode();
11168 }
11169 #endif
11170 }
11171
SetDuringCallState(bool value)11172 void ScreenSessionManager::SetDuringCallState(bool value)
11173 {
11174 bool ret = ScreenSettingHelper::SetSettingDuringCallState("during_call_state", value);
11175 TLOGI(WmsLogTag::DMS, "set during call state to %{public}d, ret:%{public}d", value, ret);
11176 }
11177 } // namespace OHOS::Rosen
11178