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