• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <hisysevent.h>
17 #include <hitrace_meter.h>
18 #include <transaction/rs_interfaces.h>
19 #include "fold_screen_controller/single_display_pocket_fold_policy.h"
20 #include "session/screen/include/screen_session.h"
21 #include "screen_session_manager.h"
22 
23 #include "window_manager_hilog.h"
24 
25 #ifdef POWER_MANAGER_ENABLE
26 #include <power_mgr_client.h>
27 #endif
28 
29 namespace OHOS::Rosen {
30 namespace {
31 const ScreenId SCREEN_ID_FULL = 0;
32 const ScreenId SCREEN_ID_MAIN = 5;
33 
34 const int32_t REMOVE_DISPLAY_NODE = 0;
35 const int32_t ADD_DISPLAY_NODE = 1;
36 
37 #ifdef TP_FEATURE_ENABLE
38 const int32_t TP_TYPE = 12;
39 const int32_t TP_TYPE_POWER_CTRL = 18;
40 const std::string FULL_TP = "0";
41 const std::string MAIN_TP = "1";
42 const std::string MAIN_TP_OFF = "1,1";
43 const std::string FULL_TP_OFF = "0.1";
44 #endif
45 } // namespace
46 
SingleDisplayPocketFoldPolicy(std::recursive_mutex & displayInfoMutex,std::shared_ptr<TaskScheduler> screenPowerTaskScheduler)47 SingleDisplayPocketFoldPolicy::SingleDisplayPocketFoldPolicy(std::recursive_mutex& displayInfoMutex,
48     std::shared_ptr<TaskScheduler> screenPowerTaskScheduler)
49     : displayInfoMutex_(displayInfoMutex), screenPowerTaskScheduler_(screenPowerTaskScheduler)
50 {
51     TLOGI(WmsLogTag::DMS, "SingleDisplayPocketFoldPolicy created");
52 
53     ScreenId screenIdFull = 0;
54     int32_t foldCreaseRegionPosX = 0;
55     int32_t foldCreaseRegionPosY = 1064;
56     int32_t foldCreaseRegionPosWidth = 2496;
57     int32_t foldCreaseRegionPosHeight = 171;
58 
59     std::vector<DMRect> rect = {
60         {
61             foldCreaseRegionPosX, foldCreaseRegionPosY,
62             foldCreaseRegionPosWidth, foldCreaseRegionPosHeight
63         }
64     };
65     currentFoldCreaseRegion_ = new FoldCreaseRegion(screenIdFull, rect);
66 }
67 
SetdisplayModeChangeStatus(bool status,bool isOnBootAnimation)68 void SingleDisplayPocketFoldPolicy::SetdisplayModeChangeStatus(bool status, bool isOnBootAnimation)
69 {
70     if (status) {
71         pengdingTask_ = isOnBootAnimation ? FOLD_TO_EXPAND_ONBOOTANIMATION_TASK_NUM : FOLD_TO_EXPAND_TASK_NUM;
72         startTimePoint_ = std::chrono::steady_clock::now();
73         displayModeChangeRunning_ = status;
74     } else {
75         pengdingTask_ --;
76         if (pengdingTask_ != 0) {
77             return;
78         }
79         displayModeChangeRunning_ = false;
80         endTimePoint_ = std::chrono::steady_clock::now();
81         if (lastCachedisplayMode_.load() != GetScreenDisplayMode()) {
82             ScreenSessionManager::GetInstance().TriggerDisplayModeUpdate(lastCachedisplayMode_.load());
83         }
84     }
85 }
86 
ChangeScreenDisplayMode(FoldDisplayMode displayMode,DisplayModeChangeReason reason)87 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayMode(FoldDisplayMode displayMode,
88     DisplayModeChangeReason reason)
89 {
90     SetLastCacheDisplayMode(displayMode);
91     if (GetModeChangeRunningStatus()) {
92         TLOGW(WmsLogTag::DMS, "last process not complete, skip mode: %{public}d", displayMode);
93         return;
94     }
95     TLOGI(WmsLogTag::DMS, "start change displaymode: %{public}d, lastElapsedMs: %{public}" PRId64 "ms",
96         displayMode, getFoldingElapsedMs());
97 
98     sptr<ScreenSession> screenSession = ScreenSessionManager::GetInstance().GetScreenSession(SCREEN_ID_FULL);
99     if (screenSession == nullptr) {
100         TLOGE(WmsLogTag::DMS, "default screenSession is null");
101         return;
102     }
103     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:ChangeScreenDisplayMode(displayMode = %" PRIu64")", displayMode);
104     {
105         std::lock_guard<std::recursive_mutex> lock_mode(displayModeMutex_);
106         if (currentDisplayMode_ == displayMode) {
107             TLOGW(WmsLogTag::DMS, "ChangeScreenDisplayMode already in displayMode %{public}d", displayMode);
108             return;
109         }
110     }
111     ReportFoldDisplayModeChange(displayMode);
112     {
113         std::lock_guard<std::recursive_mutex> lock_mode(displayModeMutex_);
114         lastDisplayMode_ = displayMode;
115     }
116     ChangeScreenDisplayModeProc(screenSession, displayMode, reason);
117     {
118         std::lock_guard<std::recursive_mutex> lock_mode(displayModeMutex_);
119         currentDisplayMode_ = displayMode;
120     }
121     ScreenSessionManager::GetInstance().NotifyDisplayModeChanged(displayMode);
122     ScreenSessionManager::GetInstance().SwitchScrollParam(displayMode);
123 }
124 
ChangeScreenDisplayModeProc(sptr<ScreenSession> screenSession,FoldDisplayMode displayMode,DisplayModeChangeReason reason)125 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeProc(sptr<ScreenSession> screenSession,
126     FoldDisplayMode displayMode, DisplayModeChangeReason reason)
127 {
128     switch (displayMode) {
129         case FoldDisplayMode::MAIN: {
130             if (currentDisplayMode_ == FoldDisplayMode::COORDINATION) {
131                 CloseCoordinationScreen();
132             }
133             ChangeScreenDisplayModeToMain(screenSession);
134             break;
135         }
136         case FoldDisplayMode::FULL: {
137             if (currentDisplayMode_ == FoldDisplayMode::COORDINATION) {
138                 CloseCoordinationScreen();
139             } else {
140                 ChangeScreenDisplayModeToFull(screenSession, reason);
141             }
142             break;
143         }
144         case FoldDisplayMode::COORDINATION: {
145             ChangeScreenDisplayModeToCoordination();
146             break;
147         }
148         case FoldDisplayMode::UNKNOWN: {
149             TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayMode displayMode is unknown");
150             break;
151         }
152         default: {
153             TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayMode displayMode is invalid");
154             break;
155         }
156     }
157 }
158 
SendSensorResult(FoldStatus foldStatus)159 void SingleDisplayPocketFoldPolicy::SendSensorResult(FoldStatus foldStatus)
160 {
161     TLOGI(WmsLogTag::DMS, "SendSensorResult FoldStatus: %{public}d", foldStatus);
162     FoldDisplayMode displayMode = GetModeMatchStatus();
163     if (!(currentDisplayMode_ == FoldDisplayMode::COORDINATION &&
164         displayMode == FoldDisplayMode::FULL)) {
165         ChangeScreenDisplayMode(displayMode);
166     }
167 }
168 
GetCurrentFoldCreaseRegion()169 sptr<FoldCreaseRegion> SingleDisplayPocketFoldPolicy::GetCurrentFoldCreaseRegion()
170 {
171     TLOGI(WmsLogTag::DMS, "GetCurrentFoldCreaseRegion");
172     return currentFoldCreaseRegion_;
173 }
174 
LockDisplayStatus(bool locked)175 void SingleDisplayPocketFoldPolicy::LockDisplayStatus(bool locked)
176 {
177     TLOGI(WmsLogTag::DMS, "LockDisplayStatus locked: %{public}d", locked);
178     lockDisplayStatus_ = locked;
179 }
180 
SetOnBootAnimation(bool onBootAnimation)181 void SingleDisplayPocketFoldPolicy::SetOnBootAnimation(bool onBootAnimation)
182 {
183     TLOGI(WmsLogTag::DMS, "SetOnBootAnimation onBootAnimation: %{public}d", onBootAnimation);
184     onBootAnimation_ = onBootAnimation;
185     if (!onBootAnimation_) {
186         TLOGI(WmsLogTag::DMS, "SetOnBootAnimation when boot animation finished, change display mode");
187         RecoverWhenBootAnimationExit();
188         NotifyRefreshRateEvent(false);
189     } else {
190         NotifyRefreshRateEvent(true);
191     }
192 }
193 
RecoverWhenBootAnimationExit()194 void SingleDisplayPocketFoldPolicy::RecoverWhenBootAnimationExit()
195 {
196     TLOGI(WmsLogTag::DMS, "CurrentScreen(%{public}" PRIu64 ")", screenId_);
197     FoldDisplayMode displayMode = GetModeMatchStatus();
198     if (currentDisplayMode_ != displayMode) {
199         ChangeScreenDisplayMode(displayMode);
200     }
201 }
202 
UpdateForPhyScreenPropertyChange()203 void SingleDisplayPocketFoldPolicy::UpdateForPhyScreenPropertyChange()
204 {
205     TLOGI(WmsLogTag::DMS, "CurrentScreen(%{public}" PRIu64 ")", screenId_);
206     FoldDisplayMode displayMode = GetModeMatchStatus();
207     if (currentDisplayMode_ != displayMode) {
208         ChangeScreenDisplayMode(displayMode);
209     }
210 }
211 
GetModeMatchStatus()212 FoldDisplayMode SingleDisplayPocketFoldPolicy::GetModeMatchStatus()
213 {
214     FoldDisplayMode displayMode = FoldDisplayMode::UNKNOWN;
215     switch (currentFoldStatus_) {
216         case FoldStatus::EXPAND: {
217             displayMode = FoldDisplayMode::FULL;
218             break;
219         }
220         case FoldStatus::FOLDED: {
221             displayMode = FoldDisplayMode::MAIN;
222             break;
223         }
224         case FoldStatus::HALF_FOLD: {
225             displayMode = FoldDisplayMode::FULL;
226             break;
227         }
228         default: {
229             TLOGI(WmsLogTag::DMS, "GetModeMatchStatus FoldStatus is invalid");
230         }
231     }
232     return displayMode;
233 }
234 
ReportFoldDisplayModeChange(FoldDisplayMode displayMode)235 void SingleDisplayPocketFoldPolicy::ReportFoldDisplayModeChange(FoldDisplayMode displayMode)
236 {
237     int32_t mode = static_cast<int32_t>(displayMode);
238     TLOGI(WmsLogTag::DMS, "ReportFoldDisplayModeChange displayMode: %{public}d", mode);
239     int32_t ret = HiSysEventWrite(
240         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
241         "DISPLAY_MODE",
242         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
243         "FOLD_DISPLAY_MODE", mode);
244     if (ret != 0) {
245         TLOGE(WmsLogTag::DMS, "ReportFoldDisplayModeChange Write HiSysEvent error, ret: %{public}d", ret);
246     }
247 }
248 
ReportFoldStatusChangeBegin(int32_t offScreen,int32_t onScreen)249 void SingleDisplayPocketFoldPolicy::ReportFoldStatusChangeBegin(int32_t offScreen, int32_t onScreen)
250 {
251     TLOGI(WmsLogTag::DMS, "ReportFoldStatusChangeBegin offScreen: %{public}d, onScreen: %{public}d",
252         offScreen, onScreen);
253     int32_t ret = HiSysEventWrite(
254         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
255         "FOLD_STATE_CHANGE_BEGIN",
256         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
257         "POWER_OFF_SCREEN", offScreen,
258         "POWER_ON_SCREEN", onScreen);
259     if (ret != 0) {
260         TLOGE(WmsLogTag::DMS, "ReportFoldStatusChangeBegin Write HiSysEvent error, ret: %{public}d", ret);
261     }
262 }
263 
ChangeScreenDisplayModeToMainWhenFoldScreenOn(sptr<ScreenSession> screenSession)264 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToMainWhenFoldScreenOn(sptr<ScreenSession> screenSession)
265 {
266     TLOGI(WmsLogTag::DMS, "IsFoldScreenOn is true, begin.");
267     ReportFoldStatusChangeBegin(static_cast<int32_t>(SCREEN_ID_FULL),
268         static_cast<int32_t>(SCREEN_ID_MAIN));
269     auto taskScreenOnMain = [=] {
270         // off full screen
271         TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayModeToMain: IsFoldScreenOn is true, screenIdFull OFF.");
272         screenId_ = SCREEN_ID_FULL;
273         ChangeScreenDisplayModePower(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
274         SetdisplayModeChangeStatus(false);
275 
276         // on main screen
277         TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayModeToMain: IsFoldScreenOn is true, screenIdMain ON.");
278         screenId_ = SCREEN_ID_MAIN;
279         ChangeScreenDisplayModePower(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
280         SetdisplayModeChangeStatus(false);
281     };
282     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnMain, "screenOnMainTask");
283     SendPropertyChangeResult(screenSession, SCREEN_ID_MAIN, ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING);
284 }
285 
ChangeScreenDisplayModeToMainWhenFoldScreenOff(sptr<ScreenSession> screenSession)286 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToMainWhenFoldScreenOff(sptr<ScreenSession> screenSession)
287 {
288     TLOGI(WmsLogTag::DMS, "IsFoldScreenOn is false, begin.");
289     // off full screen
290     auto taskScreenOffMainOff = [=] {
291         TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayModeToMain: IsFoldScreenOn is false, screenIdFull OFF.");
292         screenId_ = SCREEN_ID_FULL;
293         ChangeScreenDisplayModePower(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
294         SetdisplayModeChangeStatus(false);
295     };
296     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOffMainOff, "screenOffMainOffTask");
297     SendPropertyChangeResult(screenSession, SCREEN_ID_MAIN, ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING);
298     bool ifTentMode = ScreenSessionManager::GetInstance().GetTentMode();
299     auto taskScreenOnMainChangeScreenId = [=] {
300         TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayModeToMain: IsFoldScreenOn is false, Change ScreenId to Main.");
301         screenId_ = SCREEN_ID_MAIN;
302 #ifdef TP_FEATURE_ENABLE
303         RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE_POWER_CTRL, MAIN_TP_OFF.c_str());
304 #endif
305         if (ifTentMode) {
306             PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync(
307                 PowerMgr::WakeupDeviceType::WAKEUP_DEVICE_TENT_MODE_CHANGE);
308         }
309         SetdisplayModeChangeStatus(false);
310     };
311     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnMainChangeScreenId, "taskScreenOnMainChangeScreenId");
312 }
313 
314 
ChangeScreenDisplayModeToMain(sptr<ScreenSession> screenSession,DisplayModeChangeReason reason)315 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToMain(sptr<ScreenSession> screenSession,
316     DisplayModeChangeReason reason)
317 {
318     SetdisplayModeChangeStatus(true);
319     if (onBootAnimation_) {
320         SetdisplayModeChangeStatus(true, true);
321         ChangeScreenDisplayModeToMainOnBootAnimation(screenSession);
322         return;
323     }
324     RSInterfaces::GetInstance().NotifyScreenSwitched();
325 #ifdef TP_FEATURE_ENABLE
326     RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE, MAIN_TP.c_str());
327 #endif
328     if (PowerMgr::PowerMgrClient::GetInstance().IsFoldScreenOn()) {
329         ChangeScreenDisplayModeToMainWhenFoldScreenOn(screenSession);
330     } else { // When the screen is off and folded, it is not powered on
331         ScreenSessionManager::GetInstance().ForceSkipScreenOffAnimation();
332         ChangeScreenDisplayModeToMainWhenFoldScreenOff(screenSession);
333     }
334 }
335 
ChangeScreenDisplayModeToFullWhenFoldScreenOn(sptr<ScreenSession> screenSession)336 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToFullWhenFoldScreenOn(sptr<ScreenSession> screenSession)
337 {
338     TLOGI(WmsLogTag::DMS, "IsFoldScreenOn is true, begin.");
339     auto taskScreenOnFull = [=] {
340         // off main screen
341         TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayModeToFull: IsFoldScreenOn is true, screenIdMain OFF.");
342         screenId_ = SCREEN_ID_MAIN;
343         ChangeScreenDisplayModePower(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
344         SetdisplayModeChangeStatus(false);
345 
346         // on full screen
347         TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayModeToFull: IsFoldScreenOn is true, screenIdFull ON.");
348         screenId_ = SCREEN_ID_FULL;
349         ChangeScreenDisplayModePower(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_ON);
350         SetdisplayModeChangeStatus(false);
351     };
352     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnFull, "screenOnFullTask");
353     SendPropertyChangeResult(screenSession, SCREEN_ID_FULL, ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
354 }
355 
ChangeScreenDisplayModeToFullWhenFoldScreenOff(sptr<ScreenSession> screenSession,DisplayModeChangeReason reason)356 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToFullWhenFoldScreenOff(sptr<ScreenSession> screenSession,
357     DisplayModeChangeReason reason)
358 {
359     TLOGI(WmsLogTag::DMS, "IsFoldScreenOn is false, begin.");
360     // off main screen
361     auto taskScreenOffFullOff = [=] {
362         TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayModeToFull: IsFoldScreenOn is false, screenIdMain OFF.");
363         screenId_ = SCREEN_ID_MAIN;
364         ChangeScreenDisplayModePower(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
365         SetdisplayModeChangeStatus(false);
366     };
367     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOffFullOff, "screenOffFullOffTask");
368     SendPropertyChangeResult(screenSession, SCREEN_ID_FULL, ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
369     // on full screen
370     auto taskScreenOnFullOn = [=] {
371         TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayModeToFull: IsFoldScreenOn is false, screenIdFull ON.");
372         screenId_ = SCREEN_ID_FULL;
373         if (reason == DisplayModeChangeReason::RECOVER) {
374 #ifdef TP_FEATURE_ENABLE
375             RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE_POWER_CTRL, FULL_TP_OFF.c_str());
376 #endif
377         } else {
378             PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
379         }
380         SetdisplayModeChangeStatus(false);
381     };
382     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnFullOn, "screenOnFullOnTask");
383 }
384 
ChangeScreenDisplayModeToFull(sptr<ScreenSession> screenSession,DisplayModeChangeReason reason)385 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToFull(sptr<ScreenSession> screenSession,
386     DisplayModeChangeReason reason)
387 {
388     SetdisplayModeChangeStatus(true);
389     if (onBootAnimation_) {
390         SetdisplayModeChangeStatus(true, true);
391         ChangeScreenDisplayModeToFullOnBootAnimation(screenSession);
392         return;
393     }
394     ScreenSessionManager::GetInstance().UpdateCameraBackSelfie(false);
395     RSInterfaces::GetInstance().NotifyScreenSwitched();
396     ReportFoldStatusChangeBegin((int32_t)SCREEN_ID_MAIN, (int32_t)SCREEN_ID_FULL);
397 #ifdef TP_FEATURE_ENABLE
398     RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE, FULL_TP.c_str());
399 #endif
400     if (PowerMgr::PowerMgrClient::GetInstance().IsFoldScreenOn()) {
401         ChangeScreenDisplayModeToFullWhenFoldScreenOn(screenSession);
402     } else { //AOD scene
403         if (ScreenSessionManager::GetInstance().TryToCancelScreenOff()) {
404             ChangeScreenDisplayModeToFullWhenFoldScreenOn(screenSession);
405         } else {
406             ChangeScreenDisplayModeToFullWhenFoldScreenOff(screenSession, reason);
407         }
408     }
409 }
410 
ChangeScreenDisplayModePower(ScreenId screenId,ScreenPowerStatus screenPowerStatus)411 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModePower(ScreenId screenId, ScreenPowerStatus screenPowerStatus)
412 {
413     ScreenSessionManager::GetInstance().SetKeyguardDrawnDoneFlag(false);
414     ScreenSessionManager::GetInstance().SetScreenPowerForFold(screenId, screenPowerStatus);
415 }
416 
SendPropertyChangeResult(sptr<ScreenSession> screenSession,ScreenId screenId,ScreenPropertyChangeReason reason)417 void SingleDisplayPocketFoldPolicy::SendPropertyChangeResult(sptr<ScreenSession> screenSession, ScreenId screenId,
418     ScreenPropertyChangeReason reason)
419 {
420     std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
421     screenProperty_ = ScreenSessionManager::GetInstance().GetPhyScreenProperty(screenId);
422     ScreenProperty property = screenSession->UpdatePropertyByFoldControl(screenProperty_);
423     screenSession->PropertyChange(property, reason);
424     screenSession->SetRotationAndScreenRotationOnly(Rotation::ROTATION_0);
425     TLOGI(WmsLogTag::DMS, "screenBounds : width_= %{public}f, height_= %{public}f",
426         screenSession->GetScreenProperty().GetBounds().rect_.width_,
427         screenSession->GetScreenProperty().GetBounds().rect_.height_);
428     ScreenSessionManager::GetInstance().NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
429         DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
430 }
431 
ChangeScreenDisplayModeToMainOnBootAnimation(sptr<ScreenSession> screenSession)432 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToMainOnBootAnimation(sptr<ScreenSession> screenSession)
433 {
434     TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToMainOnBootAnimation");
435     screenProperty_ = ScreenSessionManager::GetInstance().GetPhyScreenProperty(SCREEN_ID_MAIN);
436     screenSession->UpdatePropertyByFoldControl(screenProperty_);
437     screenSession->PropertyChange(screenSession->GetScreenProperty(),
438         ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING);
439     TLOGI(WmsLogTag::DMS, "screenBounds : width_= %{public}f, height_= %{public}f",
440         screenSession->GetScreenProperty().GetBounds().rect_.width_,
441         screenSession->GetScreenProperty().GetBounds().rect_.height_);
442     screenId_ = SCREEN_ID_MAIN;
443 }
444 
ChangeScreenDisplayModeToFullOnBootAnimation(sptr<ScreenSession> screenSession)445 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToFullOnBootAnimation(sptr<ScreenSession> screenSession)
446 {
447     TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToFullOnBootAnimation");
448     screenProperty_ = ScreenSessionManager::GetInstance().GetPhyScreenProperty(SCREEN_ID_FULL);
449     screenSession->UpdatePropertyByFoldControl(screenProperty_);
450     screenSession->PropertyChange(screenSession->GetScreenProperty(),
451         ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
452     TLOGI(WmsLogTag::DMS, "screenBounds : width_= %{public}f, height_= %{public}f",
453         screenSession->GetScreenProperty().GetBounds().rect_.width_,
454         screenSession->GetScreenProperty().GetBounds().rect_.height_);
455     screenId_ = SCREEN_ID_FULL;
456 }
457 
BootAnimationFinishPowerInit()458 void SingleDisplayPocketFoldPolicy::BootAnimationFinishPowerInit()
459 {
460     int64_t timeStamp = 50;
461     if (RSInterfaces::GetInstance().GetActiveScreenId() == SCREEN_ID_FULL) {
462         // 同显切内屏:外屏下电
463         TLOGI(WmsLogTag::DMS, "Fold Screen Power main screen off.");
464         RSInterfaces::GetInstance().SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
465     } else if (RSInterfaces::GetInstance().GetActiveScreenId() == SCREEN_ID_MAIN) {
466         // 同显切外屏:双屏都灭再外屏上电
467         TLOGI(WmsLogTag::DMS, "Fold Screen Power all screen off.");
468         RSInterfaces::GetInstance().SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
469         RSInterfaces::GetInstance().SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
470         std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
471         TLOGI(WmsLogTag::DMS, "Fold Screen Power main screen on.");
472         RSInterfaces::GetInstance().SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
473     } else {
474         TLOGI(WmsLogTag::DMS, "Fold Screen Power Init, invalid active screen id");
475     }
476 }
477 
ChangeOnTentMode(FoldStatus currentState)478 void SingleDisplayPocketFoldPolicy::ChangeOnTentMode(FoldStatus currentState)
479 {
480     TLOGI(WmsLogTag::DMS, "Enter tent mode, current state:%{public}d, change display mode to MAIN", currentState);
481     if (currentState == FoldStatus::EXPAND || currentState == FoldStatus::HALF_FOLD) {
482         ChangeScreenDisplayMode(FoldDisplayMode::MAIN);
483     } else if (currentState == FoldStatus::FOLDED) {
484         ChangeScreenDisplayMode(FoldDisplayMode::MAIN);
485         PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
486     } else {
487         TLOGE(WmsLogTag::DMS, "current state:%{public}d invalid", currentState);
488     }
489 }
490 
ChangeOffTentMode()491 void SingleDisplayPocketFoldPolicy::ChangeOffTentMode()
492 {
493     PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
494     FoldDisplayMode displayMode = GetModeMatchStatus();
495     ChangeScreenDisplayMode(displayMode);
496 }
497 
AddOrRemoveDisplayNodeToTree(ScreenId screenId,int32_t command)498 void SingleDisplayPocketFoldPolicy::AddOrRemoveDisplayNodeToTree(ScreenId screenId, int32_t command)
499 {
500     TLOGI(WmsLogTag::DMS, "AddOrRemoveDisplayNodeToTree, screenId: %{public}" PRIu64 ", command: %{public}d",
501         screenId, command);
502     sptr<ScreenSession> screenSession = ScreenSessionManager::GetInstance().GetScreenSession(screenId);
503     if (screenSession == nullptr) {
504         TLOGE(WmsLogTag::DMS, "AddOrRemoveDisplayNodeToTree, screenSession is null");
505         return;
506     }
507     std::shared_ptr<RSDisplayNode> displayNode = screenSession->GetDisplayNode();
508     if (displayNode == nullptr) {
509         TLOGE(WmsLogTag::DMS, "AddOrRemoveDisplayNodeToTree, displayNode is null");
510         return;
511     }
512     if (command == ADD_DISPLAY_NODE) {
513         displayNode->AddDisplayNodeToTree();
514     } else if (command == REMOVE_DISPLAY_NODE) {
515         displayNode->RemoveDisplayNodeFromTree();
516     }
517     displayNode = nullptr;
518     auto transactionProxy = RSTransactionProxy::GetInstance();
519     if (transactionProxy != nullptr) {
520         TLOGI(WmsLogTag::DMS, "add or remove displayNode");
521         transactionProxy->FlushImplicitTransaction();
522     }
523 }
524 
ChangeScreenDisplayModeToCoordination()525 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToCoordination()
526 {
527     TLOGI(WmsLogTag::DMS, "change displaymode to coordination current mode=%{public}d", currentDisplayMode_);
528 
529     ScreenSessionManager::GetInstance().SetCoordinationFlag(true);
530     ScreenSessionManager::GetInstance().OnScreenChange(SCREEN_ID_MAIN, ScreenEvent::CONNECTED);
531 
532     // on main screen
533     auto taskScreenOnMainOn = [=] {
534         TLOGNI(WmsLogTag::DMS, "ChangeScreenDisplayModeToCoordination: screenIdMain ON.");
535         NotifyRefreshRateEvent(true);
536         ChangeScreenDisplayModePower(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
537         PowerMgr::PowerMgrClient::GetInstance().RefreshActivity();
538     };
539     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnMainOn, "ScreenToCoordinationTask");
540     AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, ADD_DISPLAY_NODE);
541 }
542 
CloseCoordinationScreen()543 void SingleDisplayPocketFoldPolicy::CloseCoordinationScreen()
544 {
545     TLOGI(WmsLogTag::DMS, "Close Coordination Screen current mode=%{public}d", currentDisplayMode_);
546 
547     // on main screen
548     auto taskScreenOnMainOFF = [=] {
549         TLOGNI(WmsLogTag::DMS, "CloseCoordinationScreen: screenIdMain OFF.");
550         ChangeScreenDisplayModePower(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
551         NotifyRefreshRateEvent(false);
552     };
553     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnMainOFF, "CloseCoordinationScreenTask");
554     AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, REMOVE_DISPLAY_NODE);
555 
556     ScreenSessionManager::GetInstance().OnScreenChange(SCREEN_ID_MAIN, ScreenEvent::DISCONNECTED);
557     ScreenSessionManager::GetInstance().SetCoordinationFlag(false);
558 }
559 
ExitCoordination()560 void SingleDisplayPocketFoldPolicy::ExitCoordination()
561 {
562     ChangeScreenDisplayModePower(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
563     AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, REMOVE_DISPLAY_NODE);
564     ScreenSessionManager::GetInstance().OnScreenChange(SCREEN_ID_MAIN, ScreenEvent::DISCONNECTED);
565     ScreenSessionManager::GetInstance().SetCoordinationFlag(false);
566     NotifyRefreshRateEvent(false);
567     FoldDisplayMode displayMode = GetModeMatchStatus();
568     currentDisplayMode_ = displayMode;
569     lastDisplayMode_ = displayMode;
570     TLOGI(WmsLogTag::DMS, "Exit coordination, current display mode:%{public}d", displayMode);
571     ScreenSessionManager::GetInstance().NotifyDisplayModeChanged(displayMode);
572 }
573 
NotifyRefreshRateEvent(bool isEventStatus)574 void SingleDisplayPocketFoldPolicy::NotifyRefreshRateEvent(bool isEventStatus)
575 {
576     EventInfo eventInfo = {
577         .eventName = "VOTER_MULTISELFOWNEDSCREEN",
578         .eventStatus = isEventStatus,
579         .minRefreshRate = 60,
580         .maxRefreshRate = 60,
581     };
582     RSInterfaces::GetInstance().NotifyRefreshRateEvent(eventInfo);
583 }
584 } // namespace OHOS::Rosen