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 = 100000000;
47 constexpr uint16_t SENSOR_EVENT_FIRST_DATA = 0;
48 constexpr float ACCURACY_ERROR_FOR_ALTA = 0.0001F;
49 static const float INWARD_HALF_FOLDED_MIN_THRESHOLD = static_cast<float>(system::GetIntParameter<int32_t>
50 ("const.fold.half_folded_min_threshold", 85));
51 static const 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 TLOGE(WmsLogTag::DMS, "RegisterPostureCallback failed.");
83 } else {
84 registerPosture_ = true;
85 TLOGI(WmsLogTag::DMS, "FoldScreenSensorManager.RegisterPostureCallback success.");
86 }
87 }
88
UnRegisterPostureCallback()89 void FoldScreenSensorManager::UnRegisterPostureCallback()
90 {
91 int32_t deactivateRet = DeactivateSensor(SENSOR_TYPE_ID_POSTURE, &postureUser);
92 int32_t unsubscribeRet = UnsubscribeSensor(SENSOR_TYPE_ID_POSTURE, &postureUser);
93 TLOGI(WmsLogTag::DMS, "UnRegisterPostureCallback, deactivateRet: %{public}d, unsubscribeRet: %{public}d",
94 deactivateRet, unsubscribeRet);
95 if (deactivateRet == SENSOR_SUCCESS && unsubscribeRet == SENSOR_SUCCESS) {
96 registerPosture_ = false;
97 TLOGI(WmsLogTag::DMS, "FoldScreenSensorManager.UnRegisterPostureCallback success.");
98 }
99 }
100
RegisterHallCallback()101 void FoldScreenSensorManager::RegisterHallCallback()
102 {
103 hallUser.callback = SensorHallDataCallback;
104 int32_t subscribeRet = SubscribeSensor(SENSOR_TYPE_ID_HALL_EXT, &hallUser);
105 TLOGI(WmsLogTag::DMS, "RegisterHallCallback, subscribeRet: %{public}d", subscribeRet);
106 int32_t setBatchRet = SetBatch(SENSOR_TYPE_ID_HALL_EXT, &hallUser, POSTURE_INTERVAL, POSTURE_INTERVAL);
107 TLOGI(WmsLogTag::DMS, "RegisterHallCallback, setBatchRet: %{public}d", setBatchRet);
108 int32_t activateRet = ActivateSensor(SENSOR_TYPE_ID_HALL_EXT, &hallUser);
109 TLOGI(WmsLogTag::DMS, "RegisterHallCallback, activateRet: %{public}d", activateRet);
110 if (subscribeRet != SENSOR_SUCCESS || setBatchRet != SENSOR_SUCCESS || activateRet != SENSOR_SUCCESS) {
111 TLOGE(WmsLogTag::DMS, "RegisterHallCallback failed.");
112 }
113 }
114
UnRegisterHallCallback()115 void FoldScreenSensorManager::UnRegisterHallCallback()
116 {
117 int32_t deactivateRet1 = DeactivateSensor(SENSOR_TYPE_ID_HALL_EXT, &hallUser);
118 int32_t unsubscribeRet1 = UnsubscribeSensor(SENSOR_TYPE_ID_HALL_EXT, &hallUser);
119 if (deactivateRet1 == SENSOR_SUCCESS && unsubscribeRet1 == SENSOR_SUCCESS) {
120 TLOGI(WmsLogTag::DMS, "FoldScreenSensorManager.UnRegisterHallCallback success.");
121 }
122 }
123
HandlePostureData(const SensorEvent * const event)124 void FoldScreenSensorManager::HandlePostureData(const SensorEvent * const event)
125 {
126 if (event == nullptr) {
127 TLOGI(WmsLogTag::DMS, "SensorEvent is nullptr.");
128 return;
129 }
130 if (event[SENSOR_EVENT_FIRST_DATA].data == nullptr) {
131 TLOGI(WmsLogTag::DMS, "SensorEvent[0].data is nullptr.");
132 return;
133 }
134 if (event[SENSOR_EVENT_FIRST_DATA].dataLen < sizeof(PostureData)) {
135 TLOGI(WmsLogTag::DMS, "SensorEvent dataLen less than posture data size.");
136 return;
137 }
138 PostureData *postureData = reinterpret_cast<PostureData *>(event[SENSOR_EVENT_FIRST_DATA].data);
139 globalAngle = (*postureData).angle;
140 if (globalHall == USHRT_MAX || std::isless(globalAngle, ANGLE_MIN_VAL) ||
141 std::isgreater(globalAngle, ANGLE_MAX_VAL + ACCURACY_ERROR_FOR_ALTA)) {
142 TLOGE(WmsLogTag::DMS, "Invalid value, hall value is: %{public}u, angle value is: %{public}f.",
143 globalHall, globalAngle);
144 return;
145 }
146 TLOGD(WmsLogTag::DMS, "angle value in PostureData is: %{public}f.", globalAngle);
147 sensorFoldStateManager_->HandleAngleChange(globalAngle, globalHall, foldScreenPolicy_);
148 notifyFoldAngleChanged(globalAngle);
149 }
150
notifyFoldAngleChanged(float foldAngle)151 void FoldScreenSensorManager::notifyFoldAngleChanged(float foldAngle)
152 {
153 if (fabs(foldAngle - oldFoldAngle) < MINI_NOTIFY_FOLD_ANGLE) {
154 return;
155 }
156 oldFoldAngle = foldAngle;
157 std::vector<float> foldAngles;
158 foldAngles.push_back(foldAngle);
159 ScreenSessionManager::GetInstance().NotifyFoldAngleChanged(foldAngles);
160 }
161
HandleHallData(const SensorEvent * const event)162 void FoldScreenSensorManager::HandleHallData(const SensorEvent * const event)
163 {
164 if (event == nullptr) {
165 TLOGI(WmsLogTag::DMS, "SensorEvent is nullptr.");
166 return;
167 }
168 if (event[SENSOR_EVENT_FIRST_DATA].data == nullptr) {
169 TLOGI(WmsLogTag::DMS, "SensorEvent[0].data is nullptr.");
170 return;
171 }
172 if (event[SENSOR_EVENT_FIRST_DATA].dataLen < sizeof(ExtHallData)) {
173 TLOGI(WmsLogTag::DMS, "SensorEvent dataLen less than hall data size.");
174 return;
175 }
176 ExtHallData *extHallData = reinterpret_cast<ExtHallData *>(event[SENSOR_EVENT_FIRST_DATA].data);
177 uint16_t flag = (uint16_t)(*extHallData).flag;
178 if (!(flag & (1 << 1))) {
179 TLOGI(WmsLogTag::DMS, "NOT Support Extend Hall.");
180 return;
181 }
182 if (globalHall == (uint16_t)(*extHallData).hall) {
183 TLOGI(WmsLogTag::DMS, "Hall don't change, hall = %{public}u", globalHall);
184 return;
185 }
186 globalHall = (uint16_t)(*extHallData).hall;
187 if (globalHall == USHRT_MAX || std::isless(globalAngle, ANGLE_MIN_VAL) ||
188 std::isgreater(globalAngle, ANGLE_MAX_VAL + ACCURACY_ERROR_FOR_ALTA)) {
189 TLOGE(WmsLogTag::DMS, "Invalid value, hall value is: %{public}u, angle value is: %{public}f.",
190 globalHall, globalAngle);
191 return;
192 }
193 TLOGI(WmsLogTag::DMS, "hall value is: %{public}u, angle value is: %{public}f", globalHall, globalAngle);
194 if (!registerPosture_) {
195 globalAngle = ANGLE_MIN_VAL;
196 }
197 sensorFoldStateManager_->HandleHallChange(globalAngle, globalHall, foldScreenPolicy_);
198 }
199
RegisterApplicationStateObserver()200 void FoldScreenSensorManager::RegisterApplicationStateObserver()
201 {
202 sensorFoldStateManager_->RegisterApplicationStateObserver();
203 }
204
TriggerDisplaySwitch()205 void FoldScreenSensorManager::TriggerDisplaySwitch()
206 {
207 TLOGI(WmsLogTag::DMS, "TriggerDisplaySwitch hall value is: %{public}u, angle value is: %{public}f",
208 globalHall, globalAngle);
209 if (!registerPosture_) {
210 globalAngle = ANGLE_MIN_VAL;
211 } else {
212 if (FoldScreenStateInternel::IsDualDisplayFoldDevice()) {
213 globalAngle = INWARD_HALF_FOLDED_MIN_THRESHOLD;
214 } else if (FoldScreenStateInternel::IsSingleDisplayFoldDevice()) {
215 globalAngle = LARGE_FOLD_HALF_FOLDED_MIN_THRESHOLD;
216 }
217 }
218 sensorFoldStateManager_->HandleAngleChange(globalAngle, globalHall, foldScreenPolicy_);
219 }
220 } // Rosen
221 } // OHOS
222 #endif