1 /*
2 * Copyright (c) 2024 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 <hisysevent.h>
17 #include <hitrace_meter.h>
18 #include <transaction/rs_interfaces.h>
19 #include "dm_common.h"
20 #include "fold_screen_controller/dual_display_fold_policy.h"
21 #include "rs_adapter.h"
22 #include "session/screen/include/screen_session.h"
23 #include "screen_session_manager.h"
24
25 #include "window_manager_hilog.h"
26 #include "parameters.h"
27 #include "fold_screen_state_internel.h"
28
29 #ifdef POWER_MANAGER_ENABLE
30 #include <power_mgr_client.h>
31 #endif
32
33 namespace OHOS::Rosen {
34 namespace {
35 const ScreenId SCREEN_ID_MAIN = 0;
36 const ScreenId SCREEN_ID_SUB = 5;
37 const bool IS_COORDINATION_SUPPORT =
38 OHOS::system::GetBoolParameter("const.window.foldabledevice.is_coordination_support", false);
39 const std::string g_FoldScreenRect = system::GetParameter("const.display.foldscreen.crease_region", "");
40 const std::string FOLD_CREASE_DELIMITER = ",;";
41 constexpr int32_t FOLD_CREASE_RECT_SIZE = 4; //numbers of parameter on the current device is 4
42 #ifdef TP_FEATURE_ENABLE
43 const int32_t TP_TYPE = 12;
44 #endif
45 const std::string MAIN_TP = "0";
46 const std::string SUB_TP = "1";
47 const int32_t REMOVE_DISPLAY_NODE = 0;
48 const int32_t ADD_DISPLAY_NODE = 1;
49 const uint32_t CHANGE_MODE_TASK_NUM = 3;
50 constexpr float VERTICAL_ROTATION = 0.0F;
51 constexpr float VERTICAL_ROTATION_REVERSE = 180.0F;
52 } // namespace
53
DualDisplayFoldPolicy(std::recursive_mutex & displayInfoMutex,std::shared_ptr<TaskScheduler> screenPowerTaskScheduler)54 DualDisplayFoldPolicy::DualDisplayFoldPolicy(std::recursive_mutex& displayInfoMutex,
55 std::shared_ptr<TaskScheduler> screenPowerTaskScheduler): screenPowerTaskScheduler_(screenPowerTaskScheduler)
56 {
57 TLOGI(WmsLogTag::DMS, "DualDisplayFoldPolicy created");
58
59 ScreenId screenIdMain = 0;
60 int32_t foldCreaseRegionPosX = 0;
61 int32_t foldCreaseRegionPosY = 1256;
62 int32_t foldCreaseRegionPosWidth = 1136;
63 int32_t foldCreaseRegionPosHeight = 184;
64
65 std::vector<DMRect> rect = {
66 {
67 foldCreaseRegionPosX, foldCreaseRegionPosY,
68 foldCreaseRegionPosWidth, foldCreaseRegionPosHeight
69 }
70 };
71 currentFoldCreaseRegion_ = new FoldCreaseRegion(screenIdMain, rect);
72 }
73
GetFoldCreaseRegion(bool isVertical) const74 FoldCreaseRegion DualDisplayFoldPolicy::GetFoldCreaseRegion(bool isVertical) const
75 {
76 std::vector<int32_t> foldRect = FoldScreenStateInternel::StringFoldRectSplitToInt(g_FoldScreenRect,
77 FOLD_CREASE_DELIMITER);
78 if (foldRect.size() != FOLD_CREASE_RECT_SIZE) {
79 TLOGE(WmsLogTag::DMS, "foldRect is invalid");
80 return FoldCreaseRegion(0, {});
81 }
82
83 ScreenId screenIdFull = 0;
84 std::vector<DMRect> foldCreaseRect;
85 GetFoldCreaseRect(isVertical, foldRect, foldCreaseRect);
86 return FoldCreaseRegion(screenIdFull, foldCreaseRect);
87 }
88
GetFoldCreaseRect(bool isVertical,const std::vector<int32_t> & foldRect,std::vector<DMRect> & foldCreaseRect) const89 void DualDisplayFoldPolicy::GetFoldCreaseRect(bool isVertical,
90 const std::vector<int32_t>& foldRect, std::vector<DMRect>& foldCreaseRect) const
91 {
92 int32_t liveCreaseRegionPosX; // live Crease Region PosX
93 int32_t liveCreaseRegionPosY; // live Crease Region PosY
94 uint32_t liveCreaseRegionPosWidth; // live Crease Region PosWidth
95 uint32_t liveCreaseRegionPosHeight; // live Crease Region PosHeight
96 if (isVertical) {
97 TLOGI(WmsLogTag::DMS, "the current FoldCreaseRect is vertical");
98 liveCreaseRegionPosX = foldRect[1];
99 liveCreaseRegionPosY = foldRect[0];
100 liveCreaseRegionPosWidth = static_cast<uint32_t>(foldRect[3]);
101 liveCreaseRegionPosHeight = static_cast<uint32_t>(foldRect[2]);
102 } else {
103 TLOGI(WmsLogTag::DMS, "the current FoldCreaseRect is horizontal");
104 liveCreaseRegionPosX = foldRect[0];
105 liveCreaseRegionPosY = foldRect[1];
106 liveCreaseRegionPosWidth = static_cast<uint32_t>(foldRect[2]);
107 liveCreaseRegionPosHeight = static_cast<uint32_t>(foldRect[3]);
108 }
109 foldCreaseRect = {
110 {
111 liveCreaseRegionPosX, liveCreaseRegionPosY,
112 liveCreaseRegionPosWidth, liveCreaseRegionPosHeight
113 }
114 };
115 return;
116 }
117
SetdisplayModeChangeStatus(bool status,bool isOnBootAnimation)118 void DualDisplayFoldPolicy::SetdisplayModeChangeStatus(bool status, bool isOnBootAnimation)
119 {
120 if (status) {
121 pengdingTask_ = CHANGE_MODE_TASK_NUM;
122 startTimePoint_ = std::chrono::steady_clock::now();
123 displayModeChangeRunning_ = status;
124 } else {
125 pengdingTask_ --;
126 if (pengdingTask_ != 0) {
127 return;
128 }
129 displayModeChangeRunning_ = false;
130 endTimePoint_ = std::chrono::steady_clock::now();
131 if (lastCachedisplayMode_.load() != GetScreenDisplayMode()) {
132 TLOGI(WmsLogTag::DMS, "start change displaymode to lastest mode");
133 ChangeScreenDisplayMode(lastCachedisplayMode_.load());
134 }
135 }
136 }
137
CheckDisplayMode(FoldDisplayMode displayMode)138 bool DualDisplayFoldPolicy::CheckDisplayMode(FoldDisplayMode displayMode)
139 {
140 if (displayMode == FoldDisplayMode::COORDINATION && !IS_COORDINATION_SUPPORT) {
141 TLOGI(WmsLogTag::DMS, "Current device is not support coordination");
142 return false;
143 }
144 if (currentDisplayMode_ == displayMode) {
145 TLOGW(WmsLogTag::DMS, "ChangeScreenDisplayMode already in displayMode %{public}d", displayMode);
146 return false;
147 }
148 return true;
149 }
150
GetScreenIdByDisplayMode(FoldDisplayMode displayMode)151 ScreenId DualDisplayFoldPolicy::GetScreenIdByDisplayMode(FoldDisplayMode displayMode)
152 {
153 ScreenId screenId = SCREEN_ID_MAIN;
154 if (displayMode == FoldDisplayMode::SUB) {
155 screenId = SCREEN_ID_SUB;
156 }
157 return screenId;
158 }
159
ChangeScreenDisplayMode(FoldDisplayMode displayMode,DisplayModeChangeReason reason)160 void DualDisplayFoldPolicy::ChangeScreenDisplayMode(FoldDisplayMode displayMode, DisplayModeChangeReason reason)
161 {
162 SetLastCacheDisplayMode(displayMode);
163 if (GetModeChangeRunningStatus()) {
164 TLOGW(WmsLogTag::DMS, "last process not complete, skip mode: %{public}d", displayMode);
165 return;
166 }
167 TLOGI(WmsLogTag::DMS, "start change displaymode: %{public}d, lastElapsedMs: %{public}" PRId64 "ms",
168 displayMode, getFoldingElapsedMs());
169 ScreenId screenId = GetScreenIdByDisplayMode(displayMode);
170 sptr<ScreenSession> screenSession = ScreenSessionManager::GetInstance().GetScreenSession(screenId);
171 if (screenSession == nullptr) {
172 TLOGE(WmsLogTag::DMS, "default screenSession is null");
173 return;
174 }
175 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:ChangeScreenDisplayMode(displayMode= %" PRIu64")", displayMode);
176 {
177 std::lock_guard<std::recursive_mutex> lock_mode(displayModeMutex_);
178 if (!CheckDisplayMode(displayMode)) {
179 return;
180 }
181 }
182 SetdisplayModeChangeStatus(true);
183 {
184 std::lock_guard<std::recursive_mutex> lock_mode(displayModeMutex_);
185 lastDisplayMode_ = displayMode;
186 }
187 ReportFoldDisplayModeChange(displayMode);
188 ScreenSessionManager::GetInstance().SwitchScrollParam(displayMode);
189 ChangeScreenDisplayModeProc(screenSession, displayMode);
190 {
191 std::lock_guard<std::recursive_mutex> lock_mode(displayModeMutex_);
192 currentDisplayMode_ = displayMode;
193 }
194 ScreenSessionManager::GetInstance().NotifyDisplayModeChanged(displayMode);
195 SetdisplayModeChangeStatus(false);
196 }
197
ChangeScreenDisplayModeProc(sptr<ScreenSession> screenSession,FoldDisplayMode displayMode)198 void DualDisplayFoldPolicy::ChangeScreenDisplayModeProc(sptr<ScreenSession> screenSession,
199 FoldDisplayMode displayMode)
200 {
201 switch (displayMode) {
202 case FoldDisplayMode::SUB: {
203 ChangeScreenDisplayModeInner(screenSession, SCREEN_ID_MAIN, SCREEN_ID_SUB);
204 break;
205 }
206 case FoldDisplayMode::MAIN: {
207 ChangeScreenDisplayModeInner(screenSession, SCREEN_ID_SUB, SCREEN_ID_MAIN);
208 break;
209 }
210 case FoldDisplayMode::COORDINATION: {
211 ChangeScreenDisplayModeToCoordination();
212 break;
213 }
214 default: {
215 break;
216 }
217 }
218 }
219
SendSensorResult(FoldStatus foldStatus)220 void DualDisplayFoldPolicy::SendSensorResult(FoldStatus foldStatus)
221 {
222 TLOGI(WmsLogTag::DMS, "FoldStatus: %{public}d", foldStatus);
223 FoldDisplayMode displayMode = GetModeMatchStatus();
224 bool isScreenOn = PowerMgr::PowerMgrClient::GetInstance().IsFoldScreenOn();
225 if (currentDisplayMode_ == FoldDisplayMode::COORDINATION && isScreenOn &&
226 displayMode == FoldDisplayMode::MAIN) {
227 TLOGI(WmsLogTag::DMS, "CurrentDisplayMode is coordination, HalfFold no need to change displaympde");
228 return;
229 }
230 ChangeScreenDisplayMode(displayMode);
231 }
232
GetCurrentFoldCreaseRegion()233 sptr<FoldCreaseRegion> DualDisplayFoldPolicy::GetCurrentFoldCreaseRegion()
234 {
235 TLOGI(WmsLogTag::DMS, "GetCurrentFoldCreaseRegion");
236 return currentFoldCreaseRegion_;
237 }
238
GetLiveCreaseRegion()239 FoldCreaseRegion DualDisplayFoldPolicy::GetLiveCreaseRegion()
240 {
241 TLOGI(WmsLogTag::DMS, "enter");
242 std::lock_guard<std::mutex> lock_mode(liveCreaseRegionMutex_);
243 FoldDisplayMode displayMode = GetScreenDisplayMode();
244 if (displayMode == FoldDisplayMode::UNKNOWN || displayMode == FoldDisplayMode::SUB) {
245 return FoldCreaseRegion(0, {});
246 }
247 sptr<ScreenSession> screenSession = ScreenSessionManager::GetInstance().GetScreenSession(SCREEN_ID_MAIN);
248 if (screenSession == nullptr) {
249 TLOGE(WmsLogTag::DMS, "default screenSession is null");
250 return FoldCreaseRegion(0, {});
251 }
252 DisplayOrientation displayOrientation = screenSession->GetScreenProperty().GetDisplayOrientation();
253 if (displayMode == FoldDisplayMode::MAIN || displayMode == FoldDisplayMode::COORDINATION) {
254 switch (displayOrientation) {
255 case DisplayOrientation::PORTRAIT:
256 case DisplayOrientation::PORTRAIT_INVERTED: {
257 liveCreaseRegion_ = GetFoldCreaseRegion(false);
258 break;
259 }
260 case DisplayOrientation::LANDSCAPE:
261 case DisplayOrientation::LANDSCAPE_INVERTED: {
262 liveCreaseRegion_ = GetFoldCreaseRegion(true);
263 break;
264 }
265 default: {
266 TLOGE(WmsLogTag::DMS, "displayOrientation is invalid");
267 }
268 }
269 }
270 return liveCreaseRegion_;
271 }
272
GetAllCreaseRegion(std::vector<FoldCreaseRegionItem> & foldCreaseRegionItems) const273 void DualDisplayFoldPolicy::GetAllCreaseRegion(std::vector<FoldCreaseRegionItem>& foldCreaseRegionItems) const
274 {
275 FoldCreaseRegionItem SCreaseItem{DisplayOrientation::LANDSCAPE, FoldDisplayMode::SUB,
276 FoldCreaseRegion(0, {})};
277 FoldCreaseRegionItem MPorCreaseItem{DisplayOrientation::PORTRAIT, FoldDisplayMode::MAIN,
278 GetFoldCreaseRegion(false)};
279 FoldCreaseRegionItem MLandCreaseItem{DisplayOrientation::LANDSCAPE, FoldDisplayMode::MAIN,
280 GetFoldCreaseRegion(true)};
281 FoldCreaseRegionItem CPorCreaseItem{DisplayOrientation::PORTRAIT, FoldDisplayMode::COORDINATION,
282 GetFoldCreaseRegion(false)};
283 FoldCreaseRegionItem CLandCreaseItem{DisplayOrientation::LANDSCAPE, FoldDisplayMode::COORDINATION,
284 GetFoldCreaseRegion(true)};
285 foldCreaseRegionItems.push_back(SCreaseItem);
286 foldCreaseRegionItems.push_back(MPorCreaseItem);
287 foldCreaseRegionItems.push_back(MLandCreaseItem);
288 foldCreaseRegionItems.push_back(CPorCreaseItem);
289 foldCreaseRegionItems.push_back(CLandCreaseItem);
290 }
291
LockDisplayStatus(bool locked)292 void DualDisplayFoldPolicy::LockDisplayStatus(bool locked)
293 {
294 TLOGI(WmsLogTag::DMS, "locked: %{public}d", locked);
295 lockDisplayStatus_ = locked;
296 }
297
SetOnBootAnimation(bool onBootAnimation)298 void DualDisplayFoldPolicy::SetOnBootAnimation(bool onBootAnimation)
299 {
300 TLOGI(WmsLogTag::DMS, "onBootAnimation: %{public}d", onBootAnimation);
301 onBootAnimation_ = onBootAnimation;
302 if (!onBootAnimation_) {
303 TLOGI(WmsLogTag::DMS, "when boot animation finished, change display mode");
304 RecoverWhenBootAnimationExit();
305 }
306 }
307
RecoverWhenBootAnimationExit()308 void DualDisplayFoldPolicy::RecoverWhenBootAnimationExit()
309 {
310 TLOGI(WmsLogTag::DMS, "CurrentScreen(%{public}" PRIu64 ")", screenId_);
311 FoldDisplayMode displayMode = GetModeMatchStatus();
312 if (currentDisplayMode_ != displayMode) {
313 ChangeScreenDisplayMode(displayMode);
314 } else {
315 TriggerScreenDisplayModeUpdate(displayMode);
316 }
317 }
318
TriggerScreenDisplayModeUpdate(FoldDisplayMode displayMode)319 void DualDisplayFoldPolicy::TriggerScreenDisplayModeUpdate(FoldDisplayMode displayMode)
320 {
321 TLOGI(WmsLogTag::DMS, "displayMode = %{public}d", displayMode);
322 sptr<ScreenSession> screenSession = nullptr;
323 if (displayMode == FoldDisplayMode::SUB) {
324 screenSession = ScreenSessionManager::GetInstance().GetScreenSession(SCREEN_ID_SUB);
325 } else {
326 screenSession = ScreenSessionManager::GetInstance().GetScreenSession(SCREEN_ID_MAIN);
327 }
328 if (screenSession == nullptr) {
329 TLOGE(WmsLogTag::DMS, "default screenSession is null");
330 return;
331 }
332 switch (displayMode) {
333 case FoldDisplayMode::SUB: {
334 ChangeScreenDisplayModeInner(screenSession, SCREEN_ID_MAIN, SCREEN_ID_SUB);
335 break;
336 }
337 case FoldDisplayMode::MAIN: {
338 ChangeScreenDisplayModeInner(screenSession, SCREEN_ID_SUB, SCREEN_ID_MAIN);
339 break;
340 }
341 case FoldDisplayMode::UNKNOWN: {
342 TLOGI(WmsLogTag::DMS, "displayMode is unknown");
343 break;
344 }
345 default: {
346 TLOGI(WmsLogTag::DMS, "displayMode is invalid");
347 break;
348 }
349 }
350 }
351
UpdateForPhyScreenPropertyChange()352 void DualDisplayFoldPolicy::UpdateForPhyScreenPropertyChange()
353 {
354 TLOGI(WmsLogTag::DMS, "currentScreen(%{public}" PRIu64 ")", screenId_);
355 FoldDisplayMode displayMode = GetModeMatchStatus();
356 if (currentDisplayMode_ != displayMode) {
357 ChangeScreenDisplayMode(displayMode);
358 }
359 }
360
GetModeMatchStatus()361 FoldDisplayMode DualDisplayFoldPolicy::GetModeMatchStatus()
362 {
363 FoldDisplayMode displayMode = FoldDisplayMode::UNKNOWN;
364 switch (currentFoldStatus_) {
365 case FoldStatus::EXPAND: {
366 displayMode = FoldDisplayMode::MAIN;
367 break;
368 }
369 case FoldStatus::FOLDED: {
370 displayMode = FoldDisplayMode::SUB;
371 break;
372 }
373 case FoldStatus::HALF_FOLD: {
374 displayMode = FoldDisplayMode::MAIN;
375 break;
376 }
377 default: {
378 TLOGI(WmsLogTag::DMS, "FoldStatus is invalid");
379 }
380 }
381 return displayMode;
382 }
383
ReportFoldDisplayModeChange(FoldDisplayMode displayMode)384 void DualDisplayFoldPolicy::ReportFoldDisplayModeChange(FoldDisplayMode displayMode)
385 {
386 int32_t mode = static_cast<int32_t>(displayMode);
387 TLOGI(WmsLogTag::DMS, "displayMode: %{public}d", mode);
388 int32_t ret = HiSysEventWrite(
389 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
390 "DISPLAY_MODE",
391 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
392 "FOLD_DISPLAY_MODE", mode);
393 if (ret != 0) {
394 TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d", ret);
395 }
396 }
397
ReportFoldStatusChangeBegin(int32_t offScreen,int32_t onScreen)398 void DualDisplayFoldPolicy::ReportFoldStatusChangeBegin(int32_t offScreen, int32_t onScreen)
399 {
400 TLOGI(WmsLogTag::DMS, "offScreen: %{public}d, onScreen: %{public}d",
401 offScreen, onScreen);
402 int32_t ret = HiSysEventWrite(
403 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
404 "FOLD_STATE_CHANGE_BEGIN",
405 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
406 "POWER_OFF_SCREEN", offScreen,
407 "POWER_ON_SCREEN", onScreen);
408 if (ret != 0) {
409 TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d", ret);
410 }
411 }
412
ChangeScreenDisplayModeInner(sptr<ScreenSession> screenSession,ScreenId offScreenId,ScreenId onScreenId)413 void DualDisplayFoldPolicy::ChangeScreenDisplayModeInner(sptr<ScreenSession> screenSession, ScreenId offScreenId,
414 ScreenId onScreenId)
415 {
416 if (onBootAnimation_) {
417 ChangeScreenDisplayModeOnBootAnimation(screenSession, onScreenId);
418 return;
419 }
420 std::string tp = MAIN_TP;
421 if (onScreenId == SCREEN_ID_SUB) {
422 tp = SUB_TP;
423 }
424 #ifdef TP_FEATURE_ENABLE
425 RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE, tp.c_str());
426 #endif
427 ReportFoldStatusChangeBegin((int32_t)SCREEN_ID_MAIN, (int32_t)SCREEN_ID_SUB);
428 bool isScreenOn = PowerMgr::PowerMgrClient::GetInstance().IsFoldScreenOn();
429 TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToCoordination, isScreenOn= %{public}d", isScreenOn);
430 auto taskScreenOff = [=] {
431 TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayMode: off screenId: %{public}" PRIu64 "", offScreenId);
432 screenId_ = offScreenId;
433 ScreenSessionManager::GetInstance().SetKeyguardDrawnDoneFlag(false);
434 ScreenSessionManager::GetInstance().SetScreenPowerForFold(ScreenPowerStatus::POWER_STATUS_OFF);
435 SetdisplayModeChangeStatus(false);
436 };
437 if (screenPowerTaskScheduler_ == nullptr) {
438 TLOGE(WmsLogTag::DMS, "screenPowerTaskScheduler_ is nullpter");
439 return;
440 }
441 screenPowerTaskScheduler_->PostAsyncTask(taskScreenOff, "screenOffTask");
442 AddOrRemoveDisplayNodeToTree(offScreenId, REMOVE_DISPLAY_NODE);
443
444 auto taskScreenOn = [=] {
445 TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayMode: on screenId: %{public}" PRIu64 "", onScreenId);
446 screenId_ = onScreenId;
447 if (isScreenOn) {
448 ScreenSessionManager::GetInstance().SetKeyguardDrawnDoneFlag(false);
449 ScreenSessionManager::GetInstance().SetScreenPowerForFold(ScreenPowerStatus::POWER_STATUS_ON);
450 } else {
451 PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
452 }
453 SetdisplayModeChangeStatus(false);
454 };
455 screenPowerTaskScheduler_->PostAsyncTask(taskScreenOn, "screenOnTask");
456 AddOrRemoveDisplayNodeToTree(onScreenId, ADD_DISPLAY_NODE);
457 TriggerSensorInSub(screenSession);
458 }
459
ChangeScreenDisplayModeToCoordination()460 void DualDisplayFoldPolicy::ChangeScreenDisplayModeToCoordination()
461 {
462 bool isScreenOn = PowerMgr::PowerMgrClient::GetInstance().IsFoldScreenOn();
463 TLOGI(WmsLogTag::DMS, "isScreenOn= %{public}d", isScreenOn);
464 #ifdef TP_FEATURE_ENABLE
465 RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE, MAIN_TP.c_str());
466 #endif
467 // on main screen
468 auto taskScreenOnMain = [=] {
469 TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayMode: on main screenId");
470 screenId_ = SCREEN_ID_MAIN;
471 if (isScreenOn) {
472 ScreenSessionManager::GetInstance().SetKeyguardDrawnDoneFlag(false);
473 ScreenSessionManager::GetInstance().SetScreenPower(ScreenPowerStatus::POWER_STATUS_ON,
474 PowerStateChangeReason::STATE_CHANGE_REASON_DISPLAY_SWITCH);
475 } else {
476 PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
477 }
478 SetdisplayModeChangeStatus(false);
479 };
480 if (screenPowerTaskScheduler_ == nullptr) {
481 TLOGE(WmsLogTag::DMS, "screenPowerTaskScheduler_ is nullpter");
482 return;
483 }
484 screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnMain, "taskScreenOnMain");
485 // on sub screen
486 auto taskScreenOnSub = [=] {
487 TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayMode: on sub screenId");
488 if (isScreenOn) {
489 ScreenSessionManager::GetInstance().SetKeyguardDrawnDoneFlag(false);
490 ScreenSessionManager::GetInstance().SetScreenPowerForFold(SCREEN_ID_SUB,
491 ScreenPowerStatus::POWER_STATUS_ON);
492 }
493 SetdisplayModeChangeStatus(false);
494 };
495 screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnSub, "taskScreenOnSub");
496 AddOrRemoveDisplayNodeToTree(SCREEN_ID_SUB, ADD_DISPLAY_NODE);
497 }
498
ChangeScreenDisplayModeOnBootAnimation(sptr<ScreenSession> screenSession,ScreenId screenId)499 void DualDisplayFoldPolicy::ChangeScreenDisplayModeOnBootAnimation(sptr<ScreenSession> screenSession, ScreenId screenId)
500 {
501 TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToFullOnBootAnimation");
502 if (screenSession == nullptr) {
503 TLOGE(WmsLogTag::DMS, "ScreenSession is nullpter");
504 return;
505 }
506 screenProperty_ = ScreenSessionManager::GetInstance().GetPhyScreenProperty(screenId);
507 ScreenPropertyChangeReason reason = ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND;
508 if (screenId == SCREEN_ID_SUB) {
509 reason = ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING;
510 }
511 screenSession->UpdatePropertyByFoldControl(screenProperty_);
512 screenSession->PropertyChange(screenSession->GetScreenProperty(), reason);
513 TLOGI(WmsLogTag::DMS, "screenBounds : width_= %{public}f, height_= %{public}f",
514 screenSession->GetScreenProperty().GetBounds().rect_.width_,
515 screenSession->GetScreenProperty().GetBounds().rect_.height_);
516 screenId_ = screenId;
517 }
518
AddOrRemoveDisplayNodeToTree(ScreenId screenId,int32_t command)519 void DualDisplayFoldPolicy::AddOrRemoveDisplayNodeToTree(ScreenId screenId, int32_t command)
520 {
521 TLOGI(WmsLogTag::DMS, "screenId: %{public}" PRIu64 ", command: %{public}d",
522 screenId, command);
523 sptr<ScreenSession> screenSession = ScreenSessionManager::GetInstance().GetScreenSession(screenId);
524 if (screenSession == nullptr) {
525 TLOGE(WmsLogTag::DMS, "screenSession is null");
526 return;
527 }
528 std::shared_ptr<RSDisplayNode> displayNode = screenSession->GetDisplayNode();
529 if (displayNode == nullptr) {
530 TLOGE(WmsLogTag::DMS, "displayNode is null");
531 return;
532 }
533 if (command == ADD_DISPLAY_NODE) {
534 displayNode->AddDisplayNodeToTree();
535 } else if (command == REMOVE_DISPLAY_NODE) {
536 displayNode->RemoveDisplayNodeFromTree();
537 }
538 TLOGI(WmsLogTag::DMS, "add or remove displayNode");
539 RSTransactionAdapter::FlushImplicitTransaction(screenSession->GetRSUIContext());
540 }
541
ExitCoordination()542 void DualDisplayFoldPolicy::ExitCoordination()
543 {
544 ScreenSessionManager::GetInstance().SetScreenPowerForFold(SCREEN_ID_SUB,
545 ScreenPowerStatus::POWER_STATUS_OFF);
546 AddOrRemoveDisplayNodeToTree(SCREEN_ID_SUB, REMOVE_DISPLAY_NODE);
547 FoldDisplayMode displayMode = GetModeMatchStatus();
548 currentDisplayMode_ = displayMode;
549 lastDisplayMode_ = displayMode;
550 TLOGI(WmsLogTag::DMS, "CurrentDisplayMode:%{public}d", displayMode);
551 ScreenSessionManager::GetInstance().NotifyDisplayModeChanged(displayMode);
552 }
553
ChangeOnTentMode(FoldStatus currentState)554 void DualDisplayFoldPolicy::ChangeOnTentMode(FoldStatus currentState)
555 {
556 TLOGI(WmsLogTag::DMS, "Enter tent mode, current state:%{public}d, change display mode to MAIN", currentState);
557 if (currentState == FoldStatus::EXPAND || currentState == FoldStatus::HALF_FOLD) {
558 ChangeScreenDisplayMode(FoldDisplayMode::SUB);
559 } else if (currentState == FoldStatus::FOLDED) {
560 ChangeScreenDisplayMode(FoldDisplayMode::SUB);
561 PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
562 } else {
563 TLOGE(WmsLogTag::DMS, "current state:%{public}d invalid", currentState);
564 }
565 }
566
ChangeOffTentMode()567 void DualDisplayFoldPolicy::ChangeOffTentMode()
568 {
569 PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
570 FoldDisplayMode displayMode = GetModeMatchStatus();
571 TLOGW(WmsLogTag::DMS, "CurrentDisplayMode:%{public}d, CurrentFoldStatus:%{public}d",
572 currentDisplayMode_, currentFoldStatus_);
573 ChangeScreenDisplayMode(displayMode);
574 }
575
TriggerSensorInSub(const sptr<ScreenSession> & screenSession)576 void DualDisplayFoldPolicy::TriggerSensorInSub(const sptr<ScreenSession>& screenSession)
577 {
578 if (screenSession->GetScreenId() != SCREEN_ID_SUB) {
579 return;
580 }
581 sptr<ScreenSession> screenSessionMain = ScreenSessionManager::GetInstance().GetScreenSession(SCREEN_ID_MAIN);
582 if (screenSessionMain == nullptr) {
583 TLOGE(WmsLogTag::DMS, "screenSessionMain is null");
584 return;
585 }
586 float sensorRotation = screenSessionMain->GetSensorRotation();
587 TLOGI(WmsLogTag::DMS, "sensorRotation = %{public}f", sensorRotation);
588 if (FoldScreenStateInternel::FloatEqualAbs(sensorRotation, VERTICAL_ROTATION) ||
589 FoldScreenStateInternel::FloatEqualAbs(sensorRotation, VERTICAL_ROTATION_REVERSE)) {
590 screenSession->HandleSensorRotation(sensorRotation);
591 }
592 }
593 } // namespace OHOS::Rosen