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