1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "fold_screen_controller/secondary_display_fold_policy.h"
16 #include "fold_screen_state_internel.h"
17 #include <hisysevent.h>
18 #include <hitrace_meter.h>
19 #include <transaction/rs_interfaces.h>
20 #include <parameters.h>
21 #include "rs_adapter.h"
22 #include "session/screen/include/screen_session.h"
23 #include "screen_session_manager.h"
24 #include "screen_scene_config.h"
25 #include "sensor_agent.h"
26 #include "sensor_agent_type.h"
27
28 #include "window_manager_hilog.h"
29
30 #ifdef POWER_MANAGER_ENABLE
31 #include <power_mgr_client.h>
32 #endif
33
34 namespace OHOS::Rosen {
35 namespace {
36 const ScreenId SCREEN_ID_FULL = 0;
37 const ScreenId SCREEN_ID_MAIN = 5;
38 const int32_t REMOVE_DISPLAY_NODE = 0;
39 const int32_t ADD_DISPLAY_NODE = 1;
40 const int32_t MAIN_STATUS_WIDTH = 0;
41 const int32_t FULL_STATUS_WIDTH = 1;
42 const int32_t GLOBAL_FULL_STATUS_WIDTH = 2;
43 const int32_t SCREEN_HEIGHT = 3;
44 const int32_t FULL_STATUS_OFFSET_X = 4;
45 constexpr uint32_t HALF_DIVIDER = 2;
46 constexpr float MAIN_DISPLAY_ROTATION_DEGREE = 180;
47 constexpr float ROTATION_TRANSLATE_X = 612;
48 constexpr float ROTATION_TRANSLATE_Y = -612;
49 constexpr float FULL_NODE_POSITION_Z = 0.0f;
50 constexpr float MAIN_NODE_POSITION_Z = 1.0f;
51 constexpr int32_t FOLD_CREASE_RECT_SIZE = 8; // numbers of parameter on the current device is 8
52 const std::string g_FoldScreenRect = system::GetParameter("const.display.foldscreen.crease_region", "");
53 const std::string FOLD_CREASE_DELIMITER = ",;";
54 #ifdef TP_FEATURE_ENABLE
55 const int32_t TP_TYPE = 12;
56 const char* STATUS_MAIN = "version:3+main";
57 const char* STATUS_GLOBAL_FULL = "version:3+whole";
58 const char* STATUS_FULL = "version:3+minor";
59 #endif
60 } // namespace
61
SecondaryDisplayFoldPolicy(std::recursive_mutex & displayInfoMutex,std::shared_ptr<TaskScheduler> screenPowerTaskScheduler)62 SecondaryDisplayFoldPolicy::SecondaryDisplayFoldPolicy(std::recursive_mutex& displayInfoMutex,
63 std::shared_ptr<TaskScheduler> screenPowerTaskScheduler)
64 : displayInfoMutex_(displayInfoMutex), screenPowerTaskScheduler_(screenPowerTaskScheduler)
65 {
66 InitScreenParams();
67 std::vector<int32_t> screenParamsSigned;
68 for (uint32_t ele : screenParams_) {
69 screenParamsSigned.emplace_back(static_cast<int32_t>(ele));
70 }
71 ScreenId screenIdFull = 0;
72 int32_t foldCreaseRegionABPosX = 0;
73 int32_t foldCreaseRegionABPosY = screenParamsSigned[MAIN_STATUS_WIDTH]; // 1008
74 int32_t foldCreaseRegionABPosHeight = screenParamsSigned[GLOBAL_FULL_STATUS_WIDTH] -
75 screenParamsSigned[FULL_STATUS_WIDTH] - screenParamsSigned[MAIN_STATUS_WIDTH]; // 128
76 int32_t foldCreaseRegionABPosWidth = screenParamsSigned[SCREEN_HEIGHT]; // 2232
77 int32_t foldCreaseRegionBCPosX = 0;
78 // 2224
79 int32_t foldCreaseRegionBCPosY =
80 screenParamsSigned[GLOBAL_FULL_STATUS_WIDTH] -
81 ((screenParamsSigned[FULL_STATUS_WIDTH] / HALF_DIVIDER) - (foldCreaseRegionABPosHeight / HALF_DIVIDER));
82 int32_t foldCreaseRegionBCPosWidth = screenParamsSigned[SCREEN_HEIGHT]; // 2232
83 int32_t foldCreaseRegionBCPosHeight = foldCreaseRegionABPosHeight; // 128
84 TLOGW(WmsLogTag::DMS, "created, screenIdFull = %{public}" PRIu64", foldCreaseRegionABPosX = %{public}d,\
85 foldCreaseRegionABPosY = %{public}d, foldCreaseRegionABPosHeight = %{public}d,\
86 foldCreaseRegionABPosWidth = %{public}d, foldCreaseRegionBCPosX = %{public}d,\
87 foldCreaseRegionBCPosY = %{public}d, foldCreaseRegionBCPosWidth = %{public}d,\
88 foldCreaseRegionBCPosHeight = %{public}d", screenIdFull, foldCreaseRegionABPosX, foldCreaseRegionABPosY,
89 foldCreaseRegionABPosHeight, foldCreaseRegionABPosWidth, foldCreaseRegionBCPosX, foldCreaseRegionBCPosY,
90 foldCreaseRegionBCPosWidth, foldCreaseRegionBCPosHeight);
91 std::vector<DMRect> rect = {
92 {
93 foldCreaseRegionABPosX, foldCreaseRegionABPosY,
94 static_cast<uint32_t>(foldCreaseRegionABPosWidth), static_cast<uint32_t>(foldCreaseRegionABPosHeight)
95 },
96 {
97 foldCreaseRegionBCPosX, foldCreaseRegionBCPosY,
98 static_cast<uint32_t>(foldCreaseRegionBCPosWidth), static_cast<uint32_t>(foldCreaseRegionBCPosHeight)
99 }
100 };
101 currentFoldCreaseRegion_ = new FoldCreaseRegion(screenIdFull, rect);
102 }
103
GetAllCreaseRegion(std::vector<FoldCreaseRegionItem> & foldCreaseRegionItems) const104 void SecondaryDisplayFoldPolicy::GetAllCreaseRegion(std::vector<FoldCreaseRegionItem>& foldCreaseRegionItems) const
105 {
106 FoldCreaseRegionItem MLandCreaseItem{DisplayOrientation::LANDSCAPE, FoldDisplayMode::MAIN,
107 FoldCreaseRegion(0, {})};
108 FoldCreaseRegionItem MPorCreaseItem{DisplayOrientation::PORTRAIT, FoldDisplayMode::MAIN,
109 FoldCreaseRegion(0, {})};
110 FoldCreaseRegionItem FLandCreaseItem{DisplayOrientation::LANDSCAPE, FoldDisplayMode::FULL,
111 GetStatusFullFoldCreaseRegion(false)};
112 FoldCreaseRegionItem FPorCreaseItem{DisplayOrientation::PORTRAIT, FoldDisplayMode::FULL,
113 GetStatusFullFoldCreaseRegion(true)};
114 FoldCreaseRegionItem GLandCreaseItem{DisplayOrientation::LANDSCAPE, FoldDisplayMode::GLOBAL_FULL,
115 GetStatusGlobalFullFoldCreaseRegion(false)};
116 FoldCreaseRegionItem GPorCreaseItem{DisplayOrientation::PORTRAIT, FoldDisplayMode::GLOBAL_FULL,
117 GetStatusGlobalFullFoldCreaseRegion(true)};
118 foldCreaseRegionItems.push_back(MLandCreaseItem);
119 foldCreaseRegionItems.push_back(MPorCreaseItem);
120 foldCreaseRegionItems.push_back(FLandCreaseItem);
121 foldCreaseRegionItems.push_back(FPorCreaseItem);
122 foldCreaseRegionItems.push_back(GLandCreaseItem);
123 foldCreaseRegionItems.push_back(GPorCreaseItem);
124 }
125
GetStatusFullFoldCreaseRegion(bool isVertical) const126 FoldCreaseRegion SecondaryDisplayFoldPolicy::GetStatusFullFoldCreaseRegion(bool isVertical) const
127 {
128 std::vector<int32_t> foldRect = FoldScreenStateInternel::StringFoldRectSplitToInt(g_FoldScreenRect,
129 FOLD_CREASE_DELIMITER);
130 if (foldRect.size() != FOLD_CREASE_RECT_SIZE) {
131 TLOGE(WmsLogTag::DMS, "foldRect is invalid");
132 return FoldCreaseRegion(0, {});
133 }
134
135 ScreenId screenIdFull = 0;
136 std::vector<DMRect> foldCreaseRect;
137 GetStatusFullFoldCreaseRect(isVertical, foldRect, foldCreaseRect);
138 return FoldCreaseRegion(screenIdFull, foldCreaseRect);
139 }
140
GetStatusFullFoldCreaseRect(bool isVertical,const std::vector<int32_t> & foldRect,std::vector<DMRect> & foldCreaseRect) const141 void SecondaryDisplayFoldPolicy::GetStatusFullFoldCreaseRect(bool isVertical,
142 const std::vector<int32_t>& foldRect, std::vector<DMRect>& foldCreaseRect) const
143 {
144 int32_t liveCreaseRegionPosX; // live Crease Region PosX
145 int32_t liveCreaseRegionPosY; // live Crease Region PosY
146 uint32_t liveCreaseRegionPosWidth; // live Crease Region PosWidth
147 uint32_t liveCreaseRegionPosHeight; // live Crease Region PosHeight
148 if (isVertical) {
149 TLOGI(WmsLogTag::DMS, "the current FoldCreaseRect is vertical");
150 liveCreaseRegionPosX = foldRect[0];
151 liveCreaseRegionPosY = foldRect[1];
152 liveCreaseRegionPosWidth = static_cast<uint32_t>(foldRect[2]);
153 liveCreaseRegionPosHeight = static_cast<uint32_t>(foldRect[3]);
154 } else {
155 TLOGI(WmsLogTag::DMS, "the current FoldCreaseRect is horizontal");
156 liveCreaseRegionPosX = foldRect[1];
157 liveCreaseRegionPosY = foldRect[0];
158 liveCreaseRegionPosWidth = static_cast<uint32_t>(foldRect[3]);
159 liveCreaseRegionPosHeight = static_cast<uint32_t>(foldRect[2]);
160 }
161 foldCreaseRect = {
162 {
163 liveCreaseRegionPosX, liveCreaseRegionPosY,
164 liveCreaseRegionPosWidth, liveCreaseRegionPosHeight
165 }
166 };
167 return;
168 }
169
GetStatusGlobalFullFoldCreaseRegion(bool isVertical) const170 FoldCreaseRegion SecondaryDisplayFoldPolicy::GetStatusGlobalFullFoldCreaseRegion(bool isVertical) const
171 {
172 std::vector<int32_t> foldRect = FoldScreenStateInternel::StringFoldRectSplitToInt(g_FoldScreenRect,
173 FOLD_CREASE_DELIMITER);
174 if (foldRect.size() != FOLD_CREASE_RECT_SIZE) {
175 TLOGE(WmsLogTag::DMS, "foldRect is invalid");
176 return FoldCreaseRegion(0, {});
177 }
178
179 ScreenId screenIdFull = 0;
180 std::vector<DMRect> foldCreaseRect;
181 GetStatusGlobalFullFoldCreaseRect(isVertical, foldRect, foldCreaseRect);
182 return FoldCreaseRegion(screenIdFull, foldCreaseRect);
183 }
184
GetStatusGlobalFullFoldCreaseRect(bool isVertical,const std::vector<int32_t> & foldRect,std::vector<DMRect> & foldCreaseRect) const185 void SecondaryDisplayFoldPolicy::GetStatusGlobalFullFoldCreaseRect(bool isVertical,
186 const std::vector<int32_t>& foldRect, std::vector<DMRect>& foldCreaseRect) const
187 {
188 int32_t liveCreaseRegionABPosX; // live Crease Region ABPosX
189 int32_t liveCreaseRegionABPosY; // live Crease Region ABPosY
190 uint32_t liveCreaseRegionABPosWidth; // live Crease Region ABPosWidth
191 uint32_t liveCreaseRegionABPosHeight; // live Crease Region ABPosHeight
192 int32_t liveCreaseRegionBCPosX; // live Crease Region BCPosX
193 int32_t liveCreaseRegionBCPosY; // live Crease Region BCPosY
194 uint32_t liveCreaseRegionBCPosWidth; // live Crease Region BCPosWidth
195 uint32_t liveCreaseRegionBCPosHeight; // live Crease Region BCPosHeight
196 if (isVertical) {
197 TLOGI(WmsLogTag::DMS, "the current FoldCreaseRect is vertical");
198 liveCreaseRegionABPosX = foldRect[0];
199 liveCreaseRegionABPosY = foldRect[1];
200 liveCreaseRegionABPosWidth = static_cast<uint32_t>(foldRect[2]);
201 liveCreaseRegionABPosHeight = static_cast<uint32_t>(foldRect[3]);
202 liveCreaseRegionBCPosX = foldRect[4];
203 liveCreaseRegionBCPosY = foldRect[5];
204 liveCreaseRegionBCPosWidth = static_cast<uint32_t>(foldRect[6]);
205 liveCreaseRegionBCPosHeight = static_cast<uint32_t>(foldRect[7]);
206 } else {
207 TLOGI(WmsLogTag::DMS, "the current FoldCreaseRect is horizontal");
208 liveCreaseRegionABPosX = foldRect[1];
209 liveCreaseRegionABPosY = foldRect[0];
210 liveCreaseRegionABPosWidth = static_cast<uint32_t>(foldRect[3]);
211 liveCreaseRegionABPosHeight = static_cast<uint32_t>(foldRect[2]);
212 liveCreaseRegionBCPosX = foldRect[5];
213 liveCreaseRegionBCPosY = foldRect[4];
214 liveCreaseRegionBCPosWidth = static_cast<uint32_t>(foldRect[7]);
215 liveCreaseRegionBCPosHeight = static_cast<uint32_t>(foldRect[6]);
216 }
217 foldCreaseRect = {
218 {
219 liveCreaseRegionABPosX, liveCreaseRegionABPosY,
220 static_cast<uint32_t>(liveCreaseRegionABPosWidth), static_cast<uint32_t>(liveCreaseRegionABPosHeight)
221 },
222 {
223 liveCreaseRegionBCPosX, liveCreaseRegionBCPosY,
224 static_cast<uint32_t>(liveCreaseRegionBCPosWidth), static_cast<uint32_t>(liveCreaseRegionBCPosHeight)
225 }
226 };
227 return;
228 }
229
ChangeScreenDisplayMode(FoldDisplayMode displayMode,DisplayModeChangeReason reason)230 void SecondaryDisplayFoldPolicy::ChangeScreenDisplayMode(FoldDisplayMode displayMode, DisplayModeChangeReason reason)
231 {
232 SetLastCacheDisplayMode(displayMode);
233 if (GetModeChangeRunningStatus()) {
234 TLOGW(WmsLogTag::DMS, "last process not complete, skip mode: %{public}d", displayMode);
235 return;
236 }
237 sptr<ScreenSession> screenSession = ScreenSessionManager::GetInstance().GetScreenSession(SCREEN_ID_FULL);
238 if (screenSession == nullptr) {
239 TLOGE(WmsLogTag::DMS, "default screenSession is null");
240 return;
241 }
242 {
243 std::lock_guard<std::recursive_mutex> lock_mode(displayModeMutex_);
244 lastDisplayMode_ = displayMode;
245 }
246 if (displayMode == FoldDisplayMode::UNKNOWN) {
247 TLOGW(WmsLogTag::DMS, "displayMode is unknown");
248 } else {
249 ChangeSuperScreenDisplayMode(screenSession, displayMode);
250 }
251 ReportFoldDisplayModeChange(displayMode);
252 {
253 std::lock_guard<std::recursive_mutex> lock_mode(displayModeMutex_);
254 currentDisplayMode_ = displayMode;
255 }
256 if (displayMode == FoldDisplayMode::GLOBAL_FULL) {
257 TLOGW(WmsLogTag::DMS, "Set device status to STATUS_GLOBAL_FULL");
258 SetDeviceStatus(static_cast<uint32_t>(DMDeviceStatus::STATUS_GLOBAL_FULL));
259 system::SetParameter("persist.dms.device.status",
260 std::to_string(static_cast<uint32_t>(DMDeviceStatus::STATUS_GLOBAL_FULL)));
261 } else {
262 TLOGW(WmsLogTag::DMS, "Set device status to UNKNOWN");
263 SetDeviceStatus(static_cast<uint32_t>(DMDeviceStatus::UNKNOWN));
264 system::SetParameter("persist.dms.device.status",
265 std::to_string(static_cast<uint32_t>(DMDeviceStatus::UNKNOWN)));
266 }
267 ScreenSessionManager::GetInstance().NotifyDisplayModeChanged(displayMode);
268 }
269
SendSensorResult(FoldStatus foldStatus)270 void SecondaryDisplayFoldPolicy::SendSensorResult(FoldStatus foldStatus)
271 {
272 TLOGW(WmsLogTag::DMS, "FoldStatus: %{public}d", foldStatus);
273 FoldDisplayMode displayMode = GetModeMatchStatus();
274 ChangeScreenDisplayMode(displayMode);
275 }
276
CloseCoordinationScreen()277 void SecondaryDisplayFoldPolicy::CloseCoordinationScreen()
278 {
279 std::lock_guard<std::mutex> lock(coordinationMutex_);
280 if (!ScreenSessionManager::GetInstance().GetCoordinationFlag()) {
281 TLOGW(WmsLogTag::DMS, "CloseCoordinationScreen skipped, current coordination flag is false");
282 return;
283 }
284 TLOGI(WmsLogTag::DMS, "Close Coordination Screen current mode=%{public}d", currentDisplayMode_);
285
286 AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, REMOVE_DISPLAY_NODE);
287
288 ScreenSessionManager::GetInstance().OnScreenChange(SCREEN_ID_MAIN, ScreenEvent::DISCONNECTED);
289 ScreenSessionManager::GetInstance().SetCoordinationFlag(false);
290 }
291
ChangeScreenDisplayModeToCoordination()292 void SecondaryDisplayFoldPolicy::ChangeScreenDisplayModeToCoordination()
293 {
294 std::lock_guard<std::mutex> lock(coordinationMutex_);
295 if (ScreenSessionManager::GetInstance().GetCoordinationFlag()) {
296 TLOGW(WmsLogTag::DMS, "change displaymode to coordination skipped, current coordination flag is true");
297 return;
298 }
299 TLOGI(WmsLogTag::DMS, "change displaymode to coordination current mode=%{public}d", currentDisplayMode_);
300
301 ScreenSessionManager::GetInstance().SetCoordinationFlag(true);
302 ScreenSessionManager::GetInstance().OnScreenChange(SCREEN_ID_MAIN, ScreenEvent::CONNECTED);
303
304 // set position_Z for dual displayNode
305 UpdatePositionZForDualDisplayNode();
306 AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, ADD_DISPLAY_NODE);
307 }
308
AddOrRemoveDisplayNodeToTree(ScreenId screenId,int32_t command)309 void SecondaryDisplayFoldPolicy::AddOrRemoveDisplayNodeToTree(ScreenId screenId, int32_t command)
310 {
311 TLOGI(WmsLogTag::DMS, "AddOrRemoveDisplayNodeToTree, screenId: %{public}" PRIu64 ", command: %{public}d",
312 screenId, command);
313 sptr<ScreenSession> screenSession = ScreenSessionManager::GetInstance().GetScreenSession(screenId);
314 if (screenSession == nullptr) {
315 TLOGE(WmsLogTag::DMS, "AddOrRemoveDisplayNodeToTree, screenSession is null");
316 return;
317 }
318 std::shared_ptr<RSDisplayNode> displayNode = screenSession->GetDisplayNode();
319 if (displayNode == nullptr) {
320 TLOGE(WmsLogTag::DMS, "AddOrRemoveDisplayNodeToTree, displayNode is null");
321 return;
322 }
323
324 if (command == ADD_DISPLAY_NODE) {
325 UpdateDisplayNodeBasedOnScreenId(screenId, displayNode);
326 displayNode->AddDisplayNodeToTree();
327 } else if (command == REMOVE_DISPLAY_NODE) {
328 displayNode->RemoveDisplayNodeFromTree();
329 }
330 displayNode = nullptr;
331 TLOGI(WmsLogTag::DMS, "add or remove displayNode");
332 RSTransactionAdapter::FlushImplicitTransaction(screenSession->GetRSUIContext());
333 }
334
UpdateDisplayNodeBasedOnScreenId(ScreenId screenId,std::shared_ptr<RSDisplayNode> displayNode)335 void SecondaryDisplayFoldPolicy::UpdateDisplayNodeBasedOnScreenId(ScreenId screenId,
336 std::shared_ptr<RSDisplayNode> displayNode)
337 {
338 if (screenId != SCREEN_ID_MAIN) {
339 return;
340 }
341 TLOGW(WmsLogTag::DMS, "UpdateDisplayNodeBasedOnScreenId: %{public}" PRIu64, screenId);
342 displayNode->SetScreenId(SCREEN_ID_FULL);
343 displayNode->SetRotation(MAIN_DISPLAY_ROTATION_DEGREE);
344 displayNode->SetTranslate({ROTATION_TRANSLATE_X, ROTATION_TRANSLATE_Y});
345 displayNode->SetFrame(0, 0, screenParams_[MAIN_STATUS_WIDTH], screenParams_[SCREEN_HEIGHT]);
346 displayNode->SetBounds(0, 0, screenParams_[MAIN_STATUS_WIDTH], screenParams_[SCREEN_HEIGHT]);
347 }
348
InitPositionZInfos()349 void SecondaryDisplayFoldPolicy::InitPositionZInfos()
350 {
351 if (!dualDisplayNodePositionZ_.empty()) {
352 return;
353 }
354 dualDisplayNodePositionZ_.insert(std::make_pair(SCREEN_ID_FULL, FULL_NODE_POSITION_Z));
355 dualDisplayNodePositionZ_.insert(std::make_pair(SCREEN_ID_MAIN, MAIN_NODE_POSITION_Z));
356 }
357
UpdatePositionZForDualDisplayNode()358 void SecondaryDisplayFoldPolicy::UpdatePositionZForDualDisplayNode()
359 {
360 InitPositionZInfos();
361 for (const auto& pair : dualDisplayNodePositionZ_) {
362 int screenId = pair.first;
363 float positionZ = pair.second;
364 sptr<ScreenSession> screenSession = ScreenSessionManager::GetInstance().GetScreenSession(screenId);
365 if (screenSession == nullptr) {
366 TLOGE(WmsLogTag::DMS, "AddOrRemoveDisplayNodeToTree, screenSession is null");
367 continue;
368 }
369 std::shared_ptr<RSDisplayNode> displayNode = screenSession->GetDisplayNode();
370 if (displayNode == nullptr) {
371 TLOGE(WmsLogTag::DMS, "AddOrRemoveDisplayNodeToTree, displayNode is null");
372 continue;
373 }
374 displayNode->SetPositionZ(positionZ);
375 RSTransactionAdapter::FlushImplicitTransaction(screenSession->GetRSUIContext());
376 }
377 }
378
ExitCoordination()379 void SecondaryDisplayFoldPolicy::ExitCoordination()
380 {
381 std::lock_guard<std::mutex> lock(coordinationMutex_);
382 if (!ScreenSessionManager::GetInstance().GetCoordinationFlag()) {
383 TLOGW(WmsLogTag::DMS, "ExitCoordination skipped, current coordination flag is false");
384 return;
385 }
386 ScreenSessionManager::GetInstance().SetKeyguardDrawnDoneFlag(false);
387 AddOrRemoveDisplayNodeToTree(SCREEN_ID_MAIN, REMOVE_DISPLAY_NODE);
388 ScreenSessionManager::GetInstance().OnScreenChange(SCREEN_ID_MAIN, ScreenEvent::DISCONNECTED);
389 ScreenSessionManager::GetInstance().SetCoordinationFlag(false);
390 #ifdef TP_FEATURE_ENABLE
391 TLOGI(WmsLogTag::DMS, "ExitCoordination SetTpFeatureConfig to full");
392 RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE, STATUS_FULL, TpFeatureConfigType::AFT_TP_FEATURE);
393 #endif
394 FoldDisplayMode displayMode = GetModeMatchStatus();
395 currentDisplayMode_ = displayMode;
396 lastDisplayMode_ = displayMode;
397 TLOGI(WmsLogTag::DMS, "Exit coordination, current display mode:%{public}d", displayMode);
398 ScreenSessionManager::GetInstance().NotifyDisplayModeChanged(displayMode);
399 }
400
SetOnBootAnimation(bool onBootAnimation)401 void SecondaryDisplayFoldPolicy::SetOnBootAnimation(bool onBootAnimation)
402 {
403 TLOGW(WmsLogTag::DMS, "onBootAnimation: %{public}d", onBootAnimation);
404 onBootAnimation_ = onBootAnimation;
405 if (!onBootAnimation_) {
406 TLOGW(WmsLogTag::DMS, "when boot animation finished, change display mode");
407 isChangeScreenWhenBootCompleted = true;
408 RecoverWhenBootAnimationExit();
409 }
410 }
411
RecoverWhenBootAnimationExit()412 void SecondaryDisplayFoldPolicy::RecoverWhenBootAnimationExit()
413 {
414 TLOGW(WmsLogTag::DMS, "CurrentScreen(%{public}" PRIu64 ")", screenId_);
415 FoldDisplayMode displayMode = GetModeMatchStatus();
416 ChangeScreenDisplayMode(displayMode);
417 }
418
GetModeMatchStatus()419 FoldDisplayMode SecondaryDisplayFoldPolicy::GetModeMatchStatus()
420 {
421 FoldDisplayMode displayMode = FoldDisplayMode::MAIN;
422 switch (currentFoldStatus_) {
423 case FoldStatus::EXPAND: {
424 displayMode = FoldDisplayMode::FULL;
425 break;
426 }
427 case FoldStatus::FOLDED: {
428 displayMode = FoldDisplayMode::MAIN;
429 break;
430 }
431 case FoldStatus::HALF_FOLD: {
432 displayMode = FoldDisplayMode::FULL;
433 break;
434 }
435 case FoldStatus::FOLD_STATE_EXPAND_WITH_SECOND_EXPAND: {
436 displayMode = FoldDisplayMode::GLOBAL_FULL;
437 break;
438 }
439 case FoldStatus::FOLD_STATE_EXPAND_WITH_SECOND_HALF_FOLDED: {
440 displayMode = FoldDisplayMode::GLOBAL_FULL;
441 break;
442 }
443 case FoldStatus::FOLD_STATE_FOLDED_WITH_SECOND_EXPAND: {
444 displayMode = FoldDisplayMode::MAIN;
445 break;
446 }
447 case FoldStatus::FOLD_STATE_FOLDED_WITH_SECOND_HALF_FOLDED: {
448 displayMode = FoldDisplayMode::MAIN;
449 break;
450 }
451 case FoldStatus::FOLD_STATE_HALF_FOLDED_WITH_SECOND_EXPAND: {
452 displayMode = FoldDisplayMode::GLOBAL_FULL;
453 break;
454 }
455 case FoldStatus::FOLD_STATE_HALF_FOLDED_WITH_SECOND_HALF_FOLDED: {
456 displayMode = FoldDisplayMode::GLOBAL_FULL;
457 break;
458 }
459 default: {
460 TLOGW(WmsLogTag::DMS, "FoldStatus is invalid");
461 }
462 }
463 TLOGW(WmsLogTag::DMS, "displayMode: %{public}d", displayMode);
464 return displayMode;
465 }
466
ChangeSuperScreenDisplayMode(sptr<ScreenSession> screenSession,FoldDisplayMode displayMode)467 void SecondaryDisplayFoldPolicy::ChangeSuperScreenDisplayMode(sptr<ScreenSession> screenSession,
468 FoldDisplayMode displayMode)
469 {
470 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:ChangeScreenDisplayMode(displayMode = %" PRIu64")", displayMode);
471 {
472 std::lock_guard<std::recursive_mutex> lock_mode(displayModeMutex_);
473 if (currentDisplayMode_ == displayMode && !isChangeScreenWhenBootCompleted) {
474 TLOGW(WmsLogTag::DMS, "already in displayMode %{public}d", displayMode);
475 return;
476 }
477 if (isChangeScreenWhenBootCompleted) {
478 isChangeScreenWhenBootCompleted = false;
479 }
480 }
481 SetSecondaryDisplayModeChangeStatus(true);
482 SendPropertyChangeResult(screenSession, SCREEN_ID_FULL, ScreenPropertyChangeReason::FOLD_SCREEN_EXPAND,
483 displayMode);
484 if (currentDisplayMode_ != displayMode) {
485 if ((currentDisplayMode_ == FoldDisplayMode::GLOBAL_FULL && displayMode == FoldDisplayMode::FULL) ||
486 (currentDisplayMode_ == FoldDisplayMode::FULL && displayMode == FoldDisplayMode::MAIN) ||
487 (currentDisplayMode_ == FoldDisplayMode::GLOBAL_FULL && displayMode == FoldDisplayMode::MAIN)) {
488 return;
489 }
490 }
491 auto taskScreenOnFullOn = [=] {
492 screenId_ = SCREEN_ID_FULL;
493 PowerMgr::PowerMgrClient::GetInstance().WakeupDeviceAsync();
494 SetdisplayModeChangeStatus(false);
495 };
496 screenPowerTaskScheduler_->PostAsyncTask(taskScreenOnFullOn, "screenOnFullOnTask");
497 }
498
SendPropertyChangeResult(sptr<ScreenSession> screenSession,ScreenId screenId,ScreenPropertyChangeReason reason,FoldDisplayMode displayMode)499 void SecondaryDisplayFoldPolicy::SendPropertyChangeResult(sptr<ScreenSession> screenSession, ScreenId screenId,
500 ScreenPropertyChangeReason reason, FoldDisplayMode displayMode)
501 {
502 std::lock_guard<std::recursive_mutex> lock_info(displayInfoMutex_);
503 screenProperty_ = ScreenSessionManager::GetInstance().GetPhyScreenProperty(screenId);
504 switch (displayMode) {
505 case FoldDisplayMode::FULL: {
506 if (currentDisplayMode_ == FoldDisplayMode::COORDINATION) {
507 CloseCoordinationScreen();
508 }
509 SetStatusFullActiveRectAndTpFeature(screenSession, screenProperty_);
510 break;
511 }
512 case FoldDisplayMode::MAIN: {
513 if (currentDisplayMode_ == FoldDisplayMode::COORDINATION) {
514 CloseCoordinationScreen();
515 }
516 reason = ScreenPropertyChangeReason::FOLD_SCREEN_FOLDING;
517 SetStatusMainActiveRectAndTpFeature(screenSession, screenProperty_);
518 break;
519 }
520 case FoldDisplayMode::GLOBAL_FULL: {
521 if (currentDisplayMode_ == FoldDisplayMode::COORDINATION) {
522 CloseCoordinationScreen();
523 }
524 SetStatusGlobalFullActiveRectAndTpFeature(screenSession, screenProperty_);
525 break;
526 }
527 case FoldDisplayMode::COORDINATION: {
528 if (currentDisplayMode_ == FoldDisplayMode::FULL) {
529 ChangeScreenDisplayModeToCoordination();
530 SetStatusConditionalActiveRectAndTpFeature(screenProperty_);
531 }
532 break;
533 }
534 default: {
535 TLOGW(WmsLogTag::DMS, "unKnown displayMode");
536 break;
537 }
538 }
539
540 screenSession->UpdatePropertyByFoldControl(screenProperty_, displayMode);
541 auto oldScreenProperty = screenSession->GetScreenProperty();
542 if (displayMode == FoldDisplayMode::MAIN) {
543 screenSession->SetRotationAndScreenRotationOnly(Rotation::ROTATION_0);
544 }
545 screenSession->PropertyChange(oldScreenProperty, reason);
546 TLOGI(WmsLogTag::DMS, "screenBounds : width_= %{public}f, height_= %{public}f",
547 screenSession->GetScreenProperty().GetBounds().rect_.width_,
548 screenSession->GetScreenProperty().GetBounds().rect_.height_);
549 }
550
SetStatusFullActiveRectAndTpFeature(const sptr<ScreenSession> & screenSession,ScreenProperty & screenProperty)551 void SecondaryDisplayFoldPolicy::SetStatusFullActiveRectAndTpFeature(const sptr<ScreenSession>& screenSession,
552 ScreenProperty &screenProperty)
553 {
554 if (screenParams_.size() < FULL_STATUS_OFFSET_X + 1) {
555 return;
556 }
557 auto fullStatusScreenBounds = RRect({0, screenParams_[FULL_STATUS_OFFSET_X],
558 screenParams_[FULL_STATUS_WIDTH], screenParams_[SCREEN_HEIGHT]}, 0.0f, 0.0f);
559 screenProperty.SetBounds(fullStatusScreenBounds);
560 screenSession->SetScreenAreaOffsetY(screenParams_[FULL_STATUS_OFFSET_X]);
561 screenSession->SetScreenAreaHeight(screenParams_[FULL_STATUS_WIDTH]);
562 OHOS::Rect rectCur{
563 .x = 0,
564 .y = screenParams_[FULL_STATUS_OFFSET_X],
565 .w = screenParams_[SCREEN_HEIGHT],
566 .h = screenParams_[FULL_STATUS_WIDTH],
567 };
568 if (!onBootAnimation_) {
569 RSInterfaces::GetInstance().NotifyScreenSwitched();
570 auto response = RSInterfaces::GetInstance().SetScreenActiveRect(0, rectCur);
571 TLOGI(WmsLogTag::DMS, "rs response is %{public}ld", static_cast<long>(response));
572 }
573 #ifdef TP_FEATURE_ENABLE
574 RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE, STATUS_FULL, TpFeatureConfigType::AFT_TP_FEATURE);
575 #endif
576 SetSecondaryDisplayModeChangeStatus(false);
577 }
578
SetStatusMainActiveRectAndTpFeature(const sptr<ScreenSession> & screenSession,ScreenProperty & screenProperty)579 void SecondaryDisplayFoldPolicy::SetStatusMainActiveRectAndTpFeature(const sptr<ScreenSession>& screenSession,
580 ScreenProperty &screenProperty)
581 {
582 if (screenParams_.size() < SCREEN_HEIGHT + 1) {
583 return;
584 }
585 auto mianStatusScreenBounds =
586 RRect({0, 0, screenParams_[MAIN_STATUS_WIDTH], screenParams_[SCREEN_HEIGHT]}, 0.0f, 0.0f);
587 screenProperty.SetBounds(mianStatusScreenBounds);
588 screenSession->SetScreenAreaOffsetY(0);
589 screenSession->SetScreenAreaHeight(screenParams_[MAIN_STATUS_WIDTH]);
590 OHOS::Rect rectCur{
591 .x = 0,
592 .y = 0,
593 .w = screenParams_[SCREEN_HEIGHT],
594 .h = screenParams_[MAIN_STATUS_WIDTH],
595 };
596 if (!onBootAnimation_) {
597 RSInterfaces::GetInstance().NotifyScreenSwitched();
598 auto response = RSInterfaces::GetInstance().SetScreenActiveRect(0, rectCur);
599 TLOGI(WmsLogTag::DMS, "rs response is %{public}ld", static_cast<long>(response));
600 }
601 #ifdef TP_FEATURE_ENABLE
602 RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE, STATUS_MAIN, TpFeatureConfigType::AFT_TP_FEATURE);
603 #endif
604 SetSecondaryDisplayModeChangeStatus(false);
605 }
606
SetStatusGlobalFullActiveRectAndTpFeature(const sptr<ScreenSession> & screenSession,ScreenProperty & screenProperty)607 void SecondaryDisplayFoldPolicy::SetStatusGlobalFullActiveRectAndTpFeature(const sptr<ScreenSession>& screenSession,
608 ScreenProperty &screenProperty)
609 {
610 if (screenParams_.size() < SCREEN_HEIGHT + 1) {
611 return;
612 }
613 auto globalFullStatusScreenBounds =
614 RRect({0, 0, screenParams_[GLOBAL_FULL_STATUS_WIDTH], screenParams_[SCREEN_HEIGHT]}, 0.0f, 0.0f);
615 screenProperty.SetBounds(globalFullStatusScreenBounds);
616 screenSession->SetScreenAreaOffsetY(0);
617 screenSession->SetScreenAreaHeight(screenParams_[GLOBAL_FULL_STATUS_WIDTH]);
618 OHOS::Rect rectCur{
619 .x = 0,
620 .y = 0,
621 .w = screenParams_[SCREEN_HEIGHT],
622 .h = screenParams_[GLOBAL_FULL_STATUS_WIDTH],
623 };
624 if (!onBootAnimation_) {
625 RSInterfaces::GetInstance().NotifyScreenSwitched();
626 auto response = RSInterfaces::GetInstance().SetScreenActiveRect(0, rectCur);
627 TLOGI(WmsLogTag::DMS, "rs response is %{public}ld", static_cast<long>(response));
628 }
629 #ifdef TP_FEATURE_ENABLE
630 RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE, STATUS_GLOBAL_FULL, TpFeatureConfigType::AFT_TP_FEATURE);
631 #endif
632 SetSecondaryDisplayModeChangeStatus(false);
633 }
634
SetStatusConditionalActiveRectAndTpFeature(ScreenProperty & screenProperty)635 void SecondaryDisplayFoldPolicy::SetStatusConditionalActiveRectAndTpFeature(ScreenProperty &screenProperty)
636 {
637 auto globalFullStatusScreenBounds = RRect({0, screenParams_[FULL_STATUS_OFFSET_X],
638 screenParams_[FULL_STATUS_WIDTH], screenParams_[SCREEN_HEIGHT]}, 0.0f, 0.0f);
639 screenProperty.SetBounds(globalFullStatusScreenBounds);
640 screenProperty.SetScreenAreaOffsetY(screenParams_[FULL_STATUS_OFFSET_X]);
641 screenProperty.SetScreenAreaHeight(screenParams_[FULL_STATUS_WIDTH]);
642 OHOS::Rect rectCur {
643 .x = 0,
644 .y = 0,
645 .w = screenParams_[SCREEN_HEIGHT],
646 .h = screenParams_[GLOBAL_FULL_STATUS_WIDTH],
647 };
648 if (!onBootAnimation_) {
649 RSInterfaces::GetInstance().NotifyScreenSwitched();
650 auto response = RSInterfaces::GetInstance().SetScreenActiveRect(0, rectCur);
651 TLOGI(WmsLogTag::DMS, "rs response is %{public}d", static_cast<uint32_t>(response));
652 }
653 #ifdef TP_FEATURE_ENABLE
654 RSInterfaces::GetInstance().SetTpFeatureConfig(TP_TYPE, STATUS_FULL, TpFeatureConfigType::AFT_TP_FEATURE);
655 #endif
656 SetSecondaryDisplayModeChangeStatus(false);
657 }
658
ReportFoldDisplayModeChange(FoldDisplayMode displayMode)659 void SecondaryDisplayFoldPolicy::ReportFoldDisplayModeChange(FoldDisplayMode displayMode)
660 {
661 int32_t mode = static_cast<int32_t>(displayMode);
662 TLOGW(WmsLogTag::DMS, "displayMode: %{public}d", mode);
663 int32_t ret = HiSysEventWrite(
664 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
665 "DISPLAY_MODE",
666 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
667 "FOLD_DISPLAY_MODE", mode);
668 if (ret != 0) {
669 TLOGE(WmsLogTag::DMS, "write HiSysEvent error, ret: %{public}d", ret);
670 }
671 }
672
GetCurrentFoldCreaseRegion()673 sptr<FoldCreaseRegion> SecondaryDisplayFoldPolicy::GetCurrentFoldCreaseRegion()
674 {
675 return currentFoldCreaseRegion_;
676 }
677
GetLiveCreaseRegion()678 FoldCreaseRegion SecondaryDisplayFoldPolicy::GetLiveCreaseRegion()
679 {
680 TLOGI(WmsLogTag::DMS, "enter");
681 std::lock_guard<std::mutex> lock_mode(liveCreaseRegionMutex_);
682 FoldDisplayMode displayMode = GetScreenDisplayMode();
683 if (displayMode == FoldDisplayMode::UNKNOWN || displayMode == FoldDisplayMode::MAIN) {
684 return FoldCreaseRegion(0, {});
685 }
686 sptr<ScreenSession> screenSession = ScreenSessionManager::GetInstance().GetScreenSession(SCREEN_ID_FULL);
687 if (screenSession == nullptr) {
688 TLOGE(WmsLogTag::DMS, "default screenSession is null");
689 return FoldCreaseRegion(0, {});
690 }
691 DisplayOrientation displayOrientation = screenSession->GetScreenProperty().GetDisplayOrientation();
692 if (displayMode == FoldDisplayMode::FULL || displayMode == FoldDisplayMode::COORDINATION) {
693 switch (displayOrientation) {
694 case DisplayOrientation::PORTRAIT:
695 case DisplayOrientation::PORTRAIT_INVERTED: {
696 liveCreaseRegion_ = GetStatusFullFoldCreaseRegion(true);
697 break;
698 }
699 case DisplayOrientation::LANDSCAPE:
700 case DisplayOrientation::LANDSCAPE_INVERTED: {
701 liveCreaseRegion_ = GetStatusFullFoldCreaseRegion(false);
702 break;
703 }
704 default: {
705 TLOGE(WmsLogTag::DMS, "displayOrientation is invalid");
706 }
707 }
708 }
709 if (displayMode == FoldDisplayMode::GLOBAL_FULL) {
710 switch (displayOrientation) {
711 case DisplayOrientation::PORTRAIT:
712 case DisplayOrientation::PORTRAIT_INVERTED: {
713 liveCreaseRegion_ = GetStatusGlobalFullFoldCreaseRegion(false);
714 break;
715 }
716 case DisplayOrientation::LANDSCAPE:
717 case DisplayOrientation::LANDSCAPE_INVERTED: {
718 liveCreaseRegion_ = GetStatusGlobalFullFoldCreaseRegion(true);
719 break;
720 }
721 default: {
722 TLOGE(WmsLogTag::DMS, "displayOrientation is invalid");
723 }
724 }
725 }
726 return liveCreaseRegion_;
727 }
728
InitScreenParams()729 void SecondaryDisplayFoldPolicy::InitScreenParams()
730 {
731 std::vector<DisplayPhysicalResolution> resolutions = ScreenSceneConfig::GetAllDisplayPhysicalConfig();
732 for (auto &resolution : resolutions) {
733 if (FoldDisplayMode::MAIN == resolution.foldDisplayMode_) {
734 screenParams_.push_back(resolution.physicalWidth_);
735 } else if (FoldDisplayMode::FULL == resolution.foldDisplayMode_) {
736 screenParams_.push_back(resolution.physicalWidth_);
737 } else if (FoldDisplayMode::GLOBAL_FULL == resolution.foldDisplayMode_) {
738 screenParams_.push_back(resolution.physicalWidth_);
739 screenParams_.push_back(resolution.physicalHeight_);
740 } else {
741 TLOGW(WmsLogTag::DMS, "unKnown displayMode");
742 }
743 }
744 screenParams_.push_back(screenParams_[GLOBAL_FULL_STATUS_WIDTH] - screenParams_[FULL_STATUS_WIDTH]);
745 TLOGI(WmsLogTag::DMS,
746 "PhysicalResolution : mainStatusWidth_= %{public}d, fullStatusWidth_= %{public}d, gloablFullStatusWidth_="
747 "%{public}d, screenHeight_= %{public}d, fullStatusOffsetX_= %{public}d",
748 screenParams_[MAIN_STATUS_WIDTH], screenParams_[FULL_STATUS_WIDTH],
749 screenParams_[GLOBAL_FULL_STATUS_WIDTH], screenParams_[SCREEN_HEIGHT],
750 screenParams_[FULL_STATUS_OFFSET_X]);
751 }
752
GetScreenParams()753 std::vector<uint32_t> SecondaryDisplayFoldPolicy::GetScreenParams()
754 {
755 return screenParams_;
756 }
757
SetSecondaryDisplayModeChangeStatus(bool status)758 void SecondaryDisplayFoldPolicy::SetSecondaryDisplayModeChangeStatus(bool status)
759 {
760 if (status) {
761 secondaryPengdingTask_ = SECONDARY_FOLD_TO_EXPAND_TASK_NUM;
762 startTimePoint_ = std::chrono::steady_clock::now();
763 displayModeChangeRunning_ = status;
764 } else {
765 secondaryPengdingTask_ --;
766 if (secondaryPengdingTask_ > 0) {
767 return;
768 }
769 displayModeChangeRunning_ = false;
770 endTimePoint_ = std::chrono::steady_clock::now();
771 if (lastCachedisplayMode_.load() != GetScreenDisplayMode()) {
772 ScreenSessionManager::GetInstance().TriggerDisplayModeUpdate(lastCachedisplayMode_.load());
773 }
774 }
775 }
776
777 } // namespace OHOS::Rosen
778