• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifdef SENSOR_ENABLE
17 #include <cmath>
18 #include <hisysevent.h>
19 #include <parameters.h>
20 
21 #include "fold_screen_controller/fold_screen_sensor_manager.h"
22 #include "fold_screen_state_internel.h"
23 #include "window_manager_hilog.h"
24 #include "screen_session_manager.h"
25 
26 #ifdef POWER_MANAGER_ENABLE
27 #include <power_mgr_client.h>
28 #endif
29 
SensorPostureDataCallback(SensorEvent * event)30 static void SensorPostureDataCallback(SensorEvent *event)
31 {
32     OHOS::Rosen::FoldScreenSensorManager::GetInstance().HandlePostureData(event);
33 }
34 
SensorHallDataCallback(SensorEvent * event)35 static void SensorHallDataCallback(SensorEvent *event)
36 {
37     OHOS::Rosen::FoldScreenSensorManager::GetInstance().HandleHallData(event);
38 }
39 
40 namespace OHOS {
41 namespace Rosen {
42 namespace {
43 constexpr float ANGLE_MIN_VAL = 0.0F;
44 constexpr float ANGLE_MAX_VAL = 180.0F;
45 constexpr int32_t SENSOR_SUCCESS = 0;
46 constexpr int32_t POSTURE_INTERVAL = 10000000;
47 constexpr uint16_t SENSOR_EVENT_FIRST_DATA = 0;
48 constexpr float ACCURACY_ERROR_FOR_ALTA = 0.0001F;
49 static float INWARD_HALF_FOLDED_MIN_THRESHOLD = static_cast<float>(system::GetIntParameter<int32_t>
50     ("const.fold.half_folded_min_threshold", 85));
51 static float LARGE_FOLD_HALF_FOLDED_MIN_THRESHOLD = static_cast<float>(system::GetIntParameter<int32_t>
52     ("const.large_fold.half_folded_min_threshold", 25));
53 constexpr float MINI_NOTIFY_FOLD_ANGLE = 0.5F;
54 float oldFoldAngle = 0.0F;
55 } // namespace
56 WM_IMPLEMENT_SINGLE_INSTANCE(FoldScreenSensorManager);
57 
FoldScreenSensorManager()58 FoldScreenSensorManager::FoldScreenSensorManager()
59 {
60 }
61 
SetFoldScreenPolicy(sptr<FoldScreenPolicy> foldScreenPolicy)62 void FoldScreenSensorManager::SetFoldScreenPolicy(sptr<FoldScreenPolicy> foldScreenPolicy)
63 {
64     foldScreenPolicy_ = foldScreenPolicy;
65 }
66 
SetSensorFoldStateManager(sptr<SensorFoldStateManager> sensorFoldStateManager)67 void FoldScreenSensorManager::SetSensorFoldStateManager(sptr<SensorFoldStateManager> sensorFoldStateManager)
68 {
69     sensorFoldStateManager_ = sensorFoldStateManager;
70 }
71 
RegisterPostureCallback()72 void FoldScreenSensorManager::RegisterPostureCallback()
73 {
74     postureUser.callback = SensorPostureDataCallback;
75     int32_t subscribeRet = SubscribeSensor(SENSOR_TYPE_ID_POSTURE, &postureUser);
76     int32_t setBatchRet = SetBatch(SENSOR_TYPE_ID_POSTURE, &postureUser, POSTURE_INTERVAL, POSTURE_INTERVAL);
77     int32_t activateRet = ActivateSensor(SENSOR_TYPE_ID_POSTURE, &postureUser);
78     TLOGI(WmsLogTag::DMS,
79         "RegisterPostureCallback, subscribeRet: %{public}d, setBatchRet: %{public}d, activateRet: %{public}d",
80         subscribeRet, setBatchRet, activateRet);
81     if (subscribeRet != SENSOR_SUCCESS || setBatchRet != SENSOR_SUCCESS || activateRet != SENSOR_SUCCESS) {
82         registerPosture_ = false;
83         TLOGE(WmsLogTag::DMS, "RegisterPostureCallback failed.");
84     } else {
85         registerPosture_ = true;
86         TLOGI(WmsLogTag::DMS, "RegisterPostureCallback success.");
87     }
88 }
89 
UnRegisterPostureCallback()90 void FoldScreenSensorManager::UnRegisterPostureCallback()
91 {
92     int32_t deactivateRet = DeactivateSensor(SENSOR_TYPE_ID_POSTURE, &postureUser);
93     int32_t unsubscribeRet = UnsubscribeSensor(SENSOR_TYPE_ID_POSTURE, &postureUser);
94     TLOGI(WmsLogTag::DMS, "UnRegisterPostureCallback, deactivateRet: %{public}d, unsubscribeRet: %{public}d",
95         deactivateRet, unsubscribeRet);
96     if (deactivateRet == SENSOR_SUCCESS && unsubscribeRet == SENSOR_SUCCESS) {
97         registerPosture_ = false;
98         TLOGI(WmsLogTag::DMS, "UnRegisterPostureCallback success.");
99     }
100 }
101 
RegisterHallCallback()102 void FoldScreenSensorManager::RegisterHallCallback()
103 {
104     hallUser.callback = SensorHallDataCallback;
105     int32_t subscribeRet = SubscribeSensor(SENSOR_TYPE_ID_HALL_EXT, &hallUser);
106     TLOGI(WmsLogTag::DMS, "RegisterHallCallback, subscribeRet: %{public}d", subscribeRet);
107     int32_t setBatchRet = SetBatch(SENSOR_TYPE_ID_HALL_EXT, &hallUser, POSTURE_INTERVAL, POSTURE_INTERVAL);
108     TLOGI(WmsLogTag::DMS, "RegisterHallCallback, setBatchRet: %{public}d", setBatchRet);
109     int32_t activateRet = ActivateSensor(SENSOR_TYPE_ID_HALL_EXT, &hallUser);
110     TLOGI(WmsLogTag::DMS, "RegisterHallCallback, activateRet: %{public}d", activateRet);
111     if (subscribeRet != SENSOR_SUCCESS || setBatchRet != SENSOR_SUCCESS || activateRet != SENSOR_SUCCESS) {
112         registerHall_ = false;
113         TLOGE(WmsLogTag::DMS, "RegisterHallCallback failed.");
114     } else {
115         registerHall_ = true;
116         TLOGI(WmsLogTag::DMS, "RegisterHallCallback success.");
117     }
118 }
119 
UnRegisterHallCallback()120 void FoldScreenSensorManager::UnRegisterHallCallback()
121 {
122     int32_t deactivateRet1 = DeactivateSensor(SENSOR_TYPE_ID_HALL_EXT, &hallUser);
123     int32_t unsubscribeRet1 = UnsubscribeSensor(SENSOR_TYPE_ID_HALL_EXT, &hallUser);
124     if (deactivateRet1 == SENSOR_SUCCESS && unsubscribeRet1 == SENSOR_SUCCESS) {
125         TLOGI(WmsLogTag::DMS, "UnRegisterHallCallback success.");
126         registerHall_ = false;
127     }
128 }
129 
HandlePostureData(const SensorEvent * const event)130 void FoldScreenSensorManager::HandlePostureData(const SensorEvent * const event)
131 {
132     if (event == nullptr) {
133         TLOGI(WmsLogTag::DMS, "SensorEvent is nullptr.");
134         return;
135     }
136     if (event[SENSOR_EVENT_FIRST_DATA].data == nullptr) {
137         TLOGI(WmsLogTag::DMS, "SensorEvent[0].data is nullptr.");
138         return;
139     }
140     if (event[SENSOR_EVENT_FIRST_DATA].dataLen < sizeof(PostureData)) {
141         TLOGI(WmsLogTag::DMS, "SensorEvent dataLen less than posture data size.");
142         return;
143     }
144     PostureData *postureData = reinterpret_cast<PostureData *>(event[SENSOR_EVENT_FIRST_DATA].data);
145     globalAngle = (*postureData).angle;
146     if (globalHall == USHRT_MAX || std::isless(globalAngle, ANGLE_MIN_VAL) ||
147         std::isgreater(globalAngle, ANGLE_MAX_VAL + ACCURACY_ERROR_FOR_ALTA)) {
148         TLOGE(WmsLogTag::DMS, "Invalid value, hall value is: %{public}u, angle value is: %{public}f.",
149             globalHall, globalAngle);
150         return;
151     }
152     TLOGD(WmsLogTag::DMS, "angle value in PostureData is: %{public}f.", globalAngle);
153     sensorFoldStateManager_->HandleAngleChange(globalAngle, globalHall, foldScreenPolicy_);
154     NotifyFoldAngleChanged(globalAngle);
155 }
156 
NotifyFoldAngleChanged(float foldAngle)157 void FoldScreenSensorManager::NotifyFoldAngleChanged(float foldAngle)
158 {
159     if (fabs(foldAngle - oldFoldAngle) < MINI_NOTIFY_FOLD_ANGLE) {
160         return;
161     }
162     oldFoldAngle = foldAngle;
163     std::vector<float> foldAngles;
164     foldAngles.push_back(foldAngle);
165     ScreenSessionManager::GetInstance().NotifyFoldAngleChanged(foldAngles);
166 }
167 
HandleHallData(const SensorEvent * const event)168 void FoldScreenSensorManager::HandleHallData(const SensorEvent * const event)
169 {
170     if (event == nullptr) {
171         TLOGI(WmsLogTag::DMS, "SensorEvent is nullptr.");
172         return;
173     }
174     if (event[SENSOR_EVENT_FIRST_DATA].data == nullptr) {
175         TLOGI(WmsLogTag::DMS, "SensorEvent[0].data is nullptr.");
176         return;
177     }
178     if (event[SENSOR_EVENT_FIRST_DATA].dataLen < sizeof(ExtHallData)) {
179         TLOGI(WmsLogTag::DMS, "SensorEvent dataLen less than hall data size.");
180         return;
181     }
182     ExtHallData *extHallData = reinterpret_cast<ExtHallData *>(event[SENSOR_EVENT_FIRST_DATA].data);
183     uint16_t flag = static_cast<uint16_t>((*extHallData).flag);
184     if (!(flag & (1 << 1))) {
185         TLOGI(WmsLogTag::DMS, "NOT Support Extend Hall.");
186         return;
187     }
188     if (globalHall == static_cast<uint16_t>((*extHallData).hall)) {
189         TLOGI(WmsLogTag::DMS, "Hall don't change, hall = %{public}u", globalHall);
190         return;
191     }
192     globalHall = static_cast<uint16_t>((*extHallData).hall);
193     if (globalHall == USHRT_MAX || std::isless(globalAngle, ANGLE_MIN_VAL) ||
194         std::isgreater(globalAngle, ANGLE_MAX_VAL + ACCURACY_ERROR_FOR_ALTA)) {
195         TLOGE(WmsLogTag::DMS, "Invalid value, hall value is: %{public}u, angle value is: %{public}f.",
196             globalHall, globalAngle);
197         return;
198     }
199     TLOGI(WmsLogTag::DMS, "hall value is: %{public}u, angle value is: %{public}f", globalHall, globalAngle);
200     if (!registerPosture_) {
201         globalAngle = ANGLE_MIN_VAL;
202     }
203     sensorFoldStateManager_->HandleHallChange(globalAngle, globalHall, foldScreenPolicy_);
204 }
205 
RegisterApplicationStateObserver()206 void FoldScreenSensorManager::RegisterApplicationStateObserver()
207 {
208     sensorFoldStateManager_->RegisterApplicationStateObserver();
209 }
210 
TriggerDisplaySwitch()211 void FoldScreenSensorManager::TriggerDisplaySwitch()
212 {
213     TLOGI(WmsLogTag::DMS, "TriggerDisplaySwitch hall value is: %{public}u, angle value is: %{public}f",
214         globalHall, globalAngle);
215     if (!registerPosture_) {
216         globalAngle = ANGLE_MIN_VAL;
217     } else {
218         if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
219             globalAngle = INWARD_HALF_FOLDED_MIN_THRESHOLD;
220         } else if (FoldScreenStateInternel::IsSingleDisplayFoldDevice()) {
221             globalAngle = LARGE_FOLD_HALF_FOLDED_MIN_THRESHOLD;
222         }
223     }
224     sensorFoldStateManager_->HandleAngleChange(globalAngle, globalHall, foldScreenPolicy_);
225 }
226 
GetSensorRegisterStatus()227 bool FoldScreenSensorManager::GetSensorRegisterStatus()
228 {
229     return registerHall_ || registerPosture_;
230 }
231 
GetGlobalAngle() const232 float FoldScreenSensorManager::GetGlobalAngle() const
233 {
234     return globalAngle;
235 }
236 
SetGlobalAngle(float angle)237 void FoldScreenSensorManager::SetGlobalAngle(float angle)
238 {
239     if (std::isless(angle, ANGLE_MIN_VAL) ||
240         std::isgreater(angle, ANGLE_MAX_VAL + ACCURACY_ERROR_FOR_ALTA)) {
241         TLOGI(WmsLogTag::DMS, "Invalid angle: %{public}f", angle);
242         return;
243     }
244     globalAngle = angle;
245 }
246 
GetGlobalHall() const247 uint16_t FoldScreenSensorManager::GetGlobalHall() const
248 {
249     return globalHall;
250 }
251 
SetGlobalHall(uint16_t hall)252 void FoldScreenSensorManager::SetGlobalHall(uint16_t hall)
253 {
254     if (hall == USHRT_MAX) {
255         TLOGI(WmsLogTag::DMS, "Invalid hall: %{public}u", hall);
256         return;
257     }
258     globalHall = hall;
259 }
260 } // Rosen
261 } // OHOS
262 #endif