• 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 
16 #include "fold_screen_controller/sensor_fold_state_manager/secondary_display_sensor_fold_state_manager.h"
17 #include <parameters.h>
18 
19 #include <hisysevent.h>
20 #include "screen_session_manager.h"
21 #include "fold_screen_controller/fold_screen_policy.h"
22 #include "fold_screen_controller/sensor_fold_state_manager/sensor_fold_state_manager.h"
23 #include "session/screen/include/screen_session.h"
24 #include "fold_screen_state_internel.h"
25 
26 #include "window_manager_hilog.h"
27 
28 #ifdef POWER_MANAGER_ENABLE
29 #include <power_mgr_client.h>
30 #endif
31 
32 namespace OHOS::Rosen {
33 namespace {
34 constexpr uint8_t HALLS_AXIS_SIZE = 2;
35 constexpr uint8_t ANGLES_AXIS_SIZE = 3;
36 constexpr float ANGLE_MIN_VAL = 0.0F;
37 constexpr float GRL_HALF_FOLDED_MAX_THRESHOLD = 140.0F;
38 constexpr float CLOSE_GRL_HALF_FOLDED_MIN_THRESHOLD = 70.0F;
39 constexpr float OPEN_GRL_HALF_FOLDED_MIN_THRESHOLD = 45.0F;
40 constexpr float GRL_HALF_FOLDED_BUFFER = 10.0F;
41 constexpr float LARGER_BOUNDARY_FOR_GRL_THRESHOLD = 90.0F;
42 constexpr int32_t LARGER_BOUNDARY_FLAG = 1;
43 constexpr int32_t SMALLER_BOUNDARY_FLAG = 0;
44 constexpr int32_t HALL_THRESHOLD = 1;
45 constexpr int32_t HALL_FOLDED_THRESHOLD = 0;
46 constexpr int32_t HALF_FOLD_VALUE = 3;
47 constexpr int32_t REFLEXION_VALUE = 2;
48 } // namespace
49 
SecondaryDisplaySensorFoldStateManager()50 SecondaryDisplaySensorFoldStateManager::SecondaryDisplaySensorFoldStateManager() {}
~SecondaryDisplaySensorFoldStateManager()51 SecondaryDisplaySensorFoldStateManager::~SecondaryDisplaySensorFoldStateManager() {}
52 
HandleAngleOrHallChange(const std::vector<float> & angles,const std::vector<uint16_t> & halls,sptr<FoldScreenPolicy> foldScreenPolicy)53 void SecondaryDisplaySensorFoldStateManager::HandleAngleOrHallChange(const std::vector<float> &angles,
54     const std::vector<uint16_t> &halls, sptr<FoldScreenPolicy> foldScreenPolicy)
55 {
56     FoldStatus nextState = GetNextFoldState(angles, halls);
57     HandleSensorChange(nextState, angles, foldScreenPolicy);
58     if (angles.size() != ANGLES_AXIS_SIZE) {
59         TLOGE(WmsLogTag::DMS, "angles size is not right, angles size %{public}zu", angles.size());
60         return;
61     }
62     bool isSecondaryReflexion = static_cast<bool>(angles[REFLEXION_VALUE]);
63     if (isSecondaryReflexion) {
64         TLOGW(WmsLogTag::DMS, "Secondary is reflexion");
65         isHasReflexioned = true;
66         ReportSecondaryReflexion(static_cast<int32_t>(nextState), static_cast<int32_t>(nextState),
67             isSecondaryReflexion);
68         SendReflexionResult(isSecondaryReflexion);
69     }
70     if (isHasReflexioned && !isSecondaryReflexion) {
71         TLOGW(WmsLogTag::DMS, "Secondary recover from reflexion");
72         isHasReflexioned = false;
73         SendReflexionResult(isSecondaryReflexion);
74     }
75 }
76 
GetNextFoldState(const std::vector<float> & angles,const std::vector<uint16_t> & halls)77 FoldStatus SecondaryDisplaySensorFoldStateManager::GetNextFoldState(const std::vector<float> &angles,
78     const std::vector<uint16_t> &halls)
79 {
80     TLOGD(WmsLogTag::DMS, "%{public}s, %{public}s",
81         FoldScreenStateInternel::TransVec2Str(angles, "angle").c_str(),
82         FoldScreenStateInternel::TransVec2Str(halls, "hall").c_str());
83 
84     FoldStatus state = FoldStatus::UNKNOWN;
85     bool isPowerOn = PowerMgr::PowerMgrClient::GetInstance().IsScreenOn();
86     if (angles.size() != ANGLES_AXIS_SIZE || halls.size() != HALLS_AXIS_SIZE) {
87         TLOGE(WmsLogTag::DMS, "angles or halls size is not right, angles size %{public}zu, halls size %{public}zu",
88             angles.size(), halls.size());
89         return state;
90     }
91     if (!isPowerOn) {
92         state = GetFoldStateUnpower(halls);
93         return state;
94     }
95     float angleAB = angles[1];
96     uint16_t hallAB = halls[1];
97     float angleBC = angles[0];
98     uint16_t hallBC = halls[0];
99 
100     FoldStatus nextStateSecondary = UpdateSwitchScreenBoundaryForLargeFoldDeviceAB(angleAB,
101         hallAB, mNextStateAB);
102     mNextStateAB = nextStateSecondary;
103 
104     FoldStatus nextStatePrimary = UpdateSwitchScreenBoundaryForLargeFoldDeviceBC(angleBC,
105         hallBC, mNextStateBC);
106     mNextStateBC = nextStatePrimary;
107 
108     state = GetGlobalFoldState(nextStatePrimary, nextStateSecondary);
109     return state;
110 }
111 
UpdateSwitchScreenBoundaryForLargeFoldDeviceAB(float angle,uint16_t hall,FoldStatus state)112 FoldStatus SecondaryDisplaySensorFoldStateManager::UpdateSwitchScreenBoundaryForLargeFoldDeviceAB(float angle,
113     uint16_t hall, FoldStatus state)
114 {
115     if (hall == HALL_FOLDED_THRESHOLD) {
116         allowUserSensorForLargeFoldDeviceAB = SMALLER_BOUNDARY_FLAG;
117     } else if (angle >= LARGER_BOUNDARY_FOR_GRL_THRESHOLD) {
118         allowUserSensorForLargeFoldDeviceAB = LARGER_BOUNDARY_FLAG;
119     }
120     return GetNextFoldStateHalf(angle, hall, state, allowUserSensorForLargeFoldDeviceAB);
121 }
122 
UpdateSwitchScreenBoundaryForLargeFoldDeviceBC(float angle,uint16_t hall,FoldStatus state)123 FoldStatus SecondaryDisplaySensorFoldStateManager::UpdateSwitchScreenBoundaryForLargeFoldDeviceBC(float angle,
124     uint16_t hall, FoldStatus state)
125 {
126     if (hall == HALL_FOLDED_THRESHOLD) {
127         allowUserSensorForLargeFoldDeviceBC = SMALLER_BOUNDARY_FLAG;
128     } else if (angle >= LARGER_BOUNDARY_FOR_GRL_THRESHOLD) {
129         allowUserSensorForLargeFoldDeviceBC = LARGER_BOUNDARY_FLAG;
130     }
131     return GetNextFoldStateHalf(angle, hall, state, allowUserSensorForLargeFoldDeviceBC);
132 }
133 
GetNextFoldStateHalf(float angle,uint16_t hall,FoldStatus CurrentState,int32_t allowUserSensorForLargeFoldDevice)134 FoldStatus SecondaryDisplaySensorFoldStateManager::GetNextFoldStateHalf(float angle,
135     uint16_t hall, FoldStatus CurrentState, int32_t allowUserSensorForLargeFoldDevice)
136 {
137     if (std::isless(angle, ANGLE_MIN_VAL)) {
138         return CurrentState;
139     }
140     FoldStatus state = FoldStatus::UNKNOWN;
141 
142     if (allowUserSensorForLargeFoldDevice == SMALLER_BOUNDARY_FLAG) {
143         if (std::islessequal(angle, OPEN_GRL_HALF_FOLDED_MIN_THRESHOLD)) {
144             state = FoldStatus::FOLDED;
145         } else if (std::isgreaterequal(angle, OPEN_GRL_HALF_FOLDED_MIN_THRESHOLD + GRL_HALF_FOLDED_BUFFER) &&
146             hall == HALL_FOLDED_THRESHOLD) {
147             state = FoldStatus::HALF_FOLD;
148         } else if (std::islessequal(angle, GRL_HALF_FOLDED_MAX_THRESHOLD - GRL_HALF_FOLDED_BUFFER) &&
149             hall == HALL_THRESHOLD) {
150             state = FoldStatus::HALF_FOLD;
151         } else if (std::isgreaterequal(angle, GRL_HALF_FOLDED_MAX_THRESHOLD)) {
152             state = FoldStatus::EXPAND;
153         } else {
154             state = CurrentState;
155             if (state == FoldStatus::UNKNOWN) {
156                 state = FoldStatus::HALF_FOLD;
157             }
158         }
159         return state;
160     }
161 
162     if (hall == HALL_THRESHOLD && angle == OPEN_GRL_HALF_FOLDED_MIN_THRESHOLD) {
163         state = CurrentState;
164     } else if (std::islessequal(angle, CLOSE_GRL_HALF_FOLDED_MIN_THRESHOLD)) {
165         state = FoldStatus::FOLDED;
166     } else if (std::islessequal(angle, GRL_HALF_FOLDED_MAX_THRESHOLD - GRL_HALF_FOLDED_BUFFER) &&
167         std::isgreater(angle, CLOSE_GRL_HALF_FOLDED_MIN_THRESHOLD + GRL_HALF_FOLDED_BUFFER)) {
168         state = FoldStatus::HALF_FOLD;
169     } else if (std::isgreaterequal(angle, GRL_HALF_FOLDED_MAX_THRESHOLD)) {
170         state = FoldStatus::EXPAND;
171     } else {
172         state = CurrentState;
173         if (state == FoldStatus::UNKNOWN) {
174             state = FoldStatus::HALF_FOLD;
175         }
176     }
177     return state;
178 }
179 
GetGlobalFoldState(FoldStatus mPrimaryFoldState,FoldStatus mSecondaryFoldState)180 FoldStatus SecondaryDisplaySensorFoldStateManager::GetGlobalFoldState(FoldStatus mPrimaryFoldState,
181     FoldStatus mSecondaryFoldState)
182 {
183     FoldStatus defaultState = FoldStatus::FOLDED;
184     if (mSecondaryFoldState == FoldStatus::UNKNOWN || mSecondaryFoldState == defaultState) {
185         return mPrimaryFoldState;
186     }
187     int32_t mPrimaryFoldStatus = static_cast<int32_t>(mPrimaryFoldState);
188     int32_t mSecondaryFoldStatus = static_cast<int32_t>(mSecondaryFoldState);
189     if (mSecondaryFoldStatus == HALF_FOLD_VALUE) {
190         mSecondaryFoldStatus --;
191     }
192     int32_t globalFoldStatus = mPrimaryFoldStatus + mSecondaryFoldStatus * 10;
193     FoldStatus globalFoldState = static_cast<FoldStatus>(globalFoldStatus);
194     return globalFoldState;
195 }
196 
GetFoldStateUnpower(const std::vector<uint16_t> & halls)197 FoldStatus SecondaryDisplaySensorFoldStateManager::GetFoldStateUnpower(const std::vector<uint16_t> &halls)
198 {
199     TLOGW(WmsLogTag::DMS, "The screen is not currently lit");
200     FoldStatus state = FoldStatus::UNKNOWN;
201     int hall1 = halls[0];
202     int hall2 = halls[1];
203     if (hall2 == HALL_THRESHOLD && hall1 == HALL_THRESHOLD) {
204         state = FoldStatus::FOLD_STATE_EXPAND_WITH_SECOND_EXPAND;
205     } else if (hall2 == HALL_FOLDED_THRESHOLD && hall1 == HALL_THRESHOLD) {
206         state = FoldStatus::EXPAND;
207     } else if (hall2 == HALL_FOLDED_THRESHOLD && hall1 == HALL_FOLDED_THRESHOLD) {
208         state = FoldStatus::FOLDED;
209     } else if (hall2 == HALL_THRESHOLD && hall1 == HALL_FOLDED_THRESHOLD) {
210         state = FoldStatus::FOLD_STATE_FOLDED_WITH_SECOND_EXPAND;
211     }
212     return state;
213 }
214 
ReportSecondaryReflexion(int32_t currentStatus,int32_t nextStatus,bool isSecondaryReflexion)215 void SecondaryDisplaySensorFoldStateManager::ReportSecondaryReflexion(int32_t currentStatus, int32_t nextStatus,
216     bool isSecondaryReflexion)
217 {
218     TLOGW(WmsLogTag::DMS, "ReportSecondaryReflexion currentStatus: %{public}d, isSecondaryReflexion: %{public}d",
219         currentStatus, isSecondaryReflexion);
220     int32_t ret = HiSysEventWrite(
221         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
222         "NOTIFY_FOLD_STATE_CHANGE",
223         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
224         "CURRENT_FOLD_STATUS", currentStatus,
225         "NEXT_FOLD_STATUS", nextStatus,
226         "SENSOR_POSTURE", isSecondaryReflexion);
227     if (ret != 0) {
228         TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d", ret);
229     }
230 }
231 
SendReflexionResult(bool isSecondaryReflexion)232 void SecondaryDisplaySensorFoldStateManager::SendReflexionResult(bool isSecondaryReflexion)
233 {
234     auto screenSession = ScreenSessionManager::GetInstance().GetDefaultScreenSession();
235     if (screenSession == nullptr) {
236         TLOGE(WmsLogTag::DMS, "screen session is null!");
237         return;
238     }
239     ScreenId screenId = screenSession->GetScreenId();
240     ScreenSessionManager::GetInstance().OnSecondaryReflexionChange(screenId, isSecondaryReflexion);
241 }
242 } // namespace OHOS::Rosen