• 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, "RecoverWhenBootAnimationExit 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, "UpdateForPhyScreenPropertyChange 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         TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToMain: IsFoldScreenOn is true, screenIdFull OFF.");
272         screenId_ = SCREEN_ID_FULL;
273         ChangeScreenDisplayModePower(ScreenPowerStatus::POWER_STATUS_OFF);
274         SetdisplayModeChangeStatus(false);
275 
276         // on main screen
277         TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToMain: IsFoldScreenOn is true, screenIdMain ON.");
278         screenId_ = SCREEN_ID_MAIN;
279         ChangeScreenDisplayModePower(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         TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToMain: IsFoldScreenOn is false, screenIdFull OFF.");
292         screenId_ = SCREEN_ID_FULL;
293         ChangeScreenDisplayModePower(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         TLOGI(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         }
308         SetdisplayModeChangeStatus(false);
309     };
310     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnMainChangeScreenId, "taskScreenOnMainChangeScreenId");
311 }
312 
313 
ChangeScreenDisplayModeToMain(sptr<ScreenSession> screenSession,DisplayModeChangeReason reason)314 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToMain(sptr<ScreenSession> screenSession,
315     DisplayModeChangeReason reason)
316 {
317     SetdisplayModeChangeStatus(true);
318     if (onBootAnimation_) {
319         SetdisplayModeChangeStatus(true, true);
320         ChangeScreenDisplayModeToMainOnBootAnimation(screenSession);
321         return;
322     }
323     #ifdef TP_FEATURE_ENABLE
324     RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE, MAIN_TP.c_str());
325     #endif
326     if (PowerMgr::PowerMgrClient::GetInstance().IsFoldScreenOn()) {
327         ChangeScreenDisplayModeToMainWhenFoldScreenOn(screenSession);
328     } else { // When the screen is off and folded, it is not powered on
329         ScreenSessionManager::GetInstance().ForceSkipScreenOffAnimation();
330         ChangeScreenDisplayModeToMainWhenFoldScreenOff(screenSession);
331     }
332 }
333 
ChangeScreenDisplayModeToFullWhenFoldScreenOn(sptr<ScreenSession> screenSession)334 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToFullWhenFoldScreenOn(sptr<ScreenSession> screenSession)
335 {
336     TLOGI(WmsLogTag::DMS, "IsFoldScreenOn is true, begin.");
337     auto taskScreenOnFull = [=] {
338         // off main screen
339         TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToFull: IsFoldScreenOn is true, screenIdMain OFF.");
340         screenId_ = SCREEN_ID_MAIN;
341         ChangeScreenDisplayModePower(ScreenPowerStatus::POWER_STATUS_OFF);
342         SetdisplayModeChangeStatus(false);
343 
344         // on full screen
345         TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToFull: IsFoldScreenOn is true, screenIdFull ON.");
346         screenId_ = SCREEN_ID_FULL;
347         ChangeScreenDisplayModePower(ScreenPowerStatus::POWER_STATUS_ON);
348         SetdisplayModeChangeStatus(false);
349     };
350     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnFull, "screenOnFullTask");
351     SendPropertyChangeResult(screenSession, SCREEN_ID_FULL, ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
352 }
353 
ChangeScreenDisplayModeToFullWhenFoldScreenOff(sptr<ScreenSession> screenSession,DisplayModeChangeReason reason)354 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToFullWhenFoldScreenOff(sptr<ScreenSession> screenSession,
355     DisplayModeChangeReason reason)
356 {
357     TLOGI(WmsLogTag::DMS, "IsFoldScreenOn is false, begin.");
358     // off main screen
359     auto taskScreenOffFullOff = [=] {
360         TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToFull: IsFoldScreenOn is false, screenIdMain OFF.");
361         screenId_ = SCREEN_ID_MAIN;
362         ChangeScreenDisplayModePower(ScreenPowerStatus::POWER_STATUS_OFF);
363         SetdisplayModeChangeStatus(false);
364     };
365     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOffFullOff, "screenOffFullOffTask");
366     SendPropertyChangeResult(screenSession, SCREEN_ID_FULL, ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
367     // on full screen
368     auto taskScreenOnFullOn = [=] {
369         TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToFull: IsFoldScreenOn is false, screenIdFull ON.");
370         screenId_ = SCREEN_ID_FULL;
371         if (reason == DisplayModeChangeReason::RECOVER) {
372 #ifdef TP_FEATURE_ENABLE
373             RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE_POWER_CTRL, FULL_TP_OFF.c_str());
374 #endif
375         } else {
376             PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
377         }
378         SetdisplayModeChangeStatus(false);
379     };
380     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnFullOn, "screenOnFullOnTask");
381 }
382 
ChangeScreenDisplayModeToFull(sptr<ScreenSession> screenSession,DisplayModeChangeReason reason)383 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToFull(sptr<ScreenSession> screenSession,
384     DisplayModeChangeReason reason)
385 {
386     SetdisplayModeChangeStatus(true);
387     if (onBootAnimation_) {
388         SetdisplayModeChangeStatus(true, true);
389         ChangeScreenDisplayModeToFullOnBootAnimation(screenSession);
390         return;
391     }
392     ScreenSessionManager::GetInstance().UpdateCameraBackSelfie(false);
393     ReportFoldStatusChangeBegin((int32_t)SCREEN_ID_MAIN, (int32_t)SCREEN_ID_FULL);
394 #ifdef TP_FEATURE_ENABLE
395     RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE, FULL_TP.c_str());
396 #endif
397     if (PowerMgr::PowerMgrClient::GetInstance().IsFoldScreenOn()) {
398         ChangeScreenDisplayModeToFullWhenFoldScreenOn(screenSession);
399     } else { //AOD scene
400         if (ScreenSessionManager::GetInstance().TryToCancelScreenOff()) {
401             ChangeScreenDisplayModeToFullWhenFoldScreenOn(screenSession);
402         } else {
403             ChangeScreenDisplayModeToFullWhenFoldScreenOff(screenSession, reason);
404         }
405     }
406 }
407 
ChangeScreenDisplayModePower(ScreenPowerStatus screenPowerStatus)408 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModePower(ScreenPowerStatus screenPowerStatus)
409 {
410     ScreenSessionManager::GetInstance().SetKeyguardDrawnDoneFlag(false);
411     ScreenSessionManager::GetInstance().SetScreenPowerForFold(screenPowerStatus);
412 }
413 
SendPropertyChangeResult(sptr<ScreenSession> screenSession,ScreenId screenId,ScreenPropertyChangeReason reason)414 void SingleDisplayPocketFoldPolicy::SendPropertyChangeResult(sptr<ScreenSession> screenSession, ScreenId screenId,
415     ScreenPropertyChangeReason reason)
416 {
417     std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
418     screenProperty_ = ScreenSessionManager::GetInstance().GetPhyScreenProperty(screenId);
419     screenSession->UpdatePropertyByFoldControl(screenProperty_);
420     screenSession->PropertyChange(screenSession->GetScreenProperty(), reason);
421     screenSession->SetRotationAndScreenRotationOnly(Rotation::ROTATION_0);
422     TLOGI(WmsLogTag::DMS, "screenBounds : width_= %{public}f, height_= %{public}f",
423         screenSession->GetScreenProperty().GetBounds().rect_.width_,
424         screenSession->GetScreenProperty().GetBounds().rect_.height_);
425     ScreenSessionManager::GetInstance().NotifyDisplayChanged(screenSession->ConvertToDisplayInfo(),
426         DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
427 }
428 
ChangeScreenDisplayModeToMainOnBootAnimation(sptr<ScreenSession> screenSession)429 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToMainOnBootAnimation(sptr<ScreenSession> screenSession)
430 {
431     TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToMainOnBootAnimation");
432     screenProperty_ = ScreenSessionManager::GetInstance().GetPhyScreenProperty(SCREEN_ID_MAIN);
433     screenSession->UpdatePropertyByFoldControl(screenProperty_);
434     screenSession->PropertyChange(screenSession->GetScreenProperty(),
435         ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING);
436     TLOGI(WmsLogTag::DMS, "screenBounds : width_= %{public}f, height_= %{public}f",
437         screenSession->GetScreenProperty().GetBounds().rect_.width_,
438         screenSession->GetScreenProperty().GetBounds().rect_.height_);
439     screenId_ = SCREEN_ID_MAIN;
440 }
441 
ChangeScreenDisplayModeToFullOnBootAnimation(sptr<ScreenSession> screenSession)442 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToFullOnBootAnimation(sptr<ScreenSession> screenSession)
443 {
444     TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToFullOnBootAnimation");
445     screenProperty_ = ScreenSessionManager::GetInstance().GetPhyScreenProperty(SCREEN_ID_FULL);
446     screenSession->UpdatePropertyByFoldControl(screenProperty_);
447     screenSession->PropertyChange(screenSession->GetScreenProperty(),
448         ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND);
449     TLOGI(WmsLogTag::DMS, "screenBounds : width_= %{public}f, height_= %{public}f",
450         screenSession->GetScreenProperty().GetBounds().rect_.width_,
451         screenSession->GetScreenProperty().GetBounds().rect_.height_);
452     screenId_ = SCREEN_ID_FULL;
453 }
454 
BootAnimationFinishPowerInit()455 void SingleDisplayPocketFoldPolicy::BootAnimationFinishPowerInit()
456 {
457     int64_t timeStamp = 50;
458     if (RSInterfaces::GetInstance().GetActiveScreenId() == SCREEN_ID_FULL) {
459         // 同显切内屏:外屏下电
460         TLOGI(WmsLogTag::DMS, "Fold Screen Power main screen off.");
461         RSInterfaces::GetInstance().SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
462     } else if (RSInterfaces::GetInstance().GetActiveScreenId() == SCREEN_ID_MAIN) {
463         // 同显切外屏:双屏都灭再外屏上电
464         TLOGI(WmsLogTag::DMS, "Fold Screen Power all screen off.");
465         RSInterfaces::GetInstance().SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_OFF);
466         RSInterfaces::GetInstance().SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
467         std::this_thread::sleep_for(std::chrono::milliseconds(timeStamp));
468         TLOGI(WmsLogTag::DMS, "Fold Screen Power main screen on.");
469         RSInterfaces::GetInstance().SetScreenPowerStatus(SCREEN_ID_MAIN, ScreenPowerStatus::POWER_STATUS_ON);
470     } else {
471         TLOGI(WmsLogTag::DMS, "Fold Screen Power Init, invalid active screen id");
472     }
473 }
474 
ChangeOnTentMode(FoldStatus currentState)475 void SingleDisplayPocketFoldPolicy::ChangeOnTentMode(FoldStatus currentState)
476 {
477     TLOGI(WmsLogTag::DMS, "Enter tent mode, current state:%{public}d, change display mode to MAIN", currentState);
478     if (currentState == FoldStatus::EXPAND || currentState == FoldStatus::HALF_FOLD) {
479         ChangeScreenDisplayMode(FoldDisplayMode::MAIN);
480     } else if (currentState == FoldStatus::FOLDED) {
481         RSInterfaces::GetInstance().SetScreenPowerStatus(SCREEN_ID_FULL, ScreenPowerStatus::POWER_STATUS_OFF);
482         ChangeScreenDisplayMode(FoldDisplayMode::MAIN);
483         PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
484     } else {
485         TLOGE(WmsLogTag::DMS, "current state:%{public}d invalid", currentState);
486     }
487 }
488 
ChangeOffTentMode()489 void SingleDisplayPocketFoldPolicy::ChangeOffTentMode()
490 {
491     PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
492     FoldDisplayMode displayMode = GetModeMatchStatus();
493     ChangeScreenDisplayMode(displayMode);
494 }
495 
AddOrRemoveDisplayNodeToTree(ScreenId screenId,int32_t command)496 void SingleDisplayPocketFoldPolicy::AddOrRemoveDisplayNodeToTree(ScreenId screenId, int32_t command)
497 {
498     TLOGI(WmsLogTag::DMS, "AddOrRemoveDisplayNodeToTree, screenId: %{public}" PRIu64 ", command: %{public}d",
499         screenId, command);
500     sptr<ScreenSession> screenSession = ScreenSessionManager::GetInstance().GetScreenSession(screenId);
501     if (screenSession == nullptr) {
502         TLOGE(WmsLogTag::DMS, "AddOrRemoveDisplayNodeToTree, screenSession is null");
503         return;
504     }
505     std::shared_ptr<RSDisplayNode> displayNode = screenSession->GetDisplayNode();
506     if (displayNode == nullptr) {
507         TLOGE(WmsLogTag::DMS, "AddOrRemoveDisplayNodeToTree, displayNode is null");
508         return;
509     }
510     if (command == ADD_DISPLAY_NODE) {
511         displayNode->AddDisplayNodeToTree();
512     } else if (command == REMOVE_DISPLAY_NODE) {
513         displayNode->RemoveDisplayNodeFromTree();
514     }
515     displayNode = nullptr;
516     auto transactionProxy = RSTransactionProxy::GetInstance();
517     if (transactionProxy != nullptr) {
518         TLOGI(WmsLogTag::DMS, "add or remove displayNode");
519         transactionProxy->FlushImplicitTransaction();
520     }
521 }
522 
ChangeScreenDisplayModeToCoordination()523 void SingleDisplayPocketFoldPolicy::ChangeScreenDisplayModeToCoordination()
524 {
525     TLOGI(WmsLogTag::DMS, "change displaymode to coordination current mode=%{public}d", currentDisplayMode_);
526 
527     ScreenSessionManager::GetInstance().SetCoordinationFlag(true);
528     ScreenSessionManager::GetInstance().OnScreenChange(SCREEN_ID_MAIN, ScreenEvent::CONNECTED);
529 
530     // on main screen
531     auto taskScreenOnMainOn = [=] {
532         TLOGI(WmsLogTag::DMS, "ChangeScreenDisplayModeToCoordination: screenIdMain ON.");
533         NotifyRefreshRateEvent(true);
534         ScreenSessionManager::GetInstance().SetKeyguardDrawnDoneFlag(false);
535         ScreenSessionManager::GetInstance().SetScreenPowerForFold(SCREEN_ID_MAIN,
536             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         TLOGI(WmsLogTag::DMS, "CloseCoordinationScreen: screenIdMain OFF.");
550         ScreenSessionManager::GetInstance().SetKeyguardDrawnDoneFlag(false);
551         ScreenSessionManager::GetInstance().SetScreenPowerForFold(SCREEN_ID_MAIN,
552             ScreenPowerStatus::POWER_STATUS_OFF);
553         NotifyRefreshRateEvent(false);
554     };
555     screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnMainOFF, "CloseCoordinationScreenTask");
556     AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, REMOVE_DISPLAY_NODE);
557 
558     ScreenSessionManager::GetInstance().OnScreenChange(SCREEN_ID_MAIN, ScreenEvent::DISCONNECTED);
559     ScreenSessionManager::GetInstance().SetCoordinationFlag(false);
560 }
561 
ExitCoordination()562 void SingleDisplayPocketFoldPolicy::ExitCoordination()
563 {
564     ScreenSessionManager::GetInstance().SetKeyguardDrawnDoneFlag(false);
565     ScreenSessionManager::GetInstance().SetScreenPowerForFold(SCREEN_ID_MAIN,
566         ScreenPowerStatus::POWER_STATUS_OFF);
567     AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, REMOVE_DISPLAY_NODE);
568     ScreenSessionManager::GetInstance().OnScreenChange(SCREEN_ID_MAIN, ScreenEvent::DISCONNECTED);
569     ScreenSessionManager::GetInstance().SetCoordinationFlag(false);
570     NotifyRefreshRateEvent(false);
571     FoldDisplayMode displayMode = GetModeMatchStatus();
572     currentDisplayMode_ = displayMode;
573     lastDisplayMode_ = displayMode;
574     TLOGI(WmsLogTag::DMS, "Exit coordination, current display mode:%{public}d", displayMode);
575     ScreenSessionManager::GetInstance().NotifyDisplayModeChanged(displayMode);
576 }
577 
NotifyRefreshRateEvent(bool isEventStatus)578 void SingleDisplayPocketFoldPolicy::NotifyRefreshRateEvent(bool isEventStatus)
579 {
580     EventInfo eventInfo = {
581         .eventName = "VOTER_MULTISELFOWNEDSCREEN",
582         .eventStatus = isEventStatus,
583         .minRefreshRate = 60,
584         .maxRefreshRate = 60,
585     };
586     RSInterfaces::GetInstance().NotifyRefreshRateEvent(eventInfo);
587 }
588 } // namespace OHOS::Rosen