• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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