• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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