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