• 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 #ifdef SENSOR_ENABLE
17 #include <cmath>
18 #include <hisysevent.h>
19 #include <parameters.h>
20 
21 #include "fold_screen_controller/secondary_fold_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 
30 namespace OHOS {
31 namespace Rosen {
32 namespace {
33 constexpr float ANGLE_MIN_VAL = 0.0F;
34 constexpr float ANGLE_MAX_VAL = 180.0F;
35 constexpr int32_t SENSOR_SUCCESS = 0;
36 constexpr int32_t POSTURE_INTERVAL = 100000000;
37 constexpr uint16_t SENSOR_EVENT_FIRST_DATA = 0;
38 constexpr uint16_t HALL_B_C_COLUMN_ORDER = 1;
39 constexpr uint16_t HALL_A_B_COLUMN_ORDER = 4;
40 constexpr float ACCURACY_ERROR_FOR_ALTA = 0.0001F;
41 constexpr float MINI_NOTIFY_FOLD_ANGLE = 0.5F;
42 std::vector<float> oldFoldAngle = {0.0F, 0.0F};
43 constexpr size_t SECONDARY_POSTURE_SIZE = 3;
44 constexpr size_t SECONDARY_HALL_SIZE = 2;
45 constexpr uint16_t FIRST_DATA = 0;
46 constexpr uint16_t SECOND_DATA = 1;
47 constexpr uint16_t THIRD_DATA = 2;
48 const int32_t MAIN_STATUS_WIDTH = 0;
49 const int32_t FULL_STATUS_WIDTH = 1;
50 const int32_t GLOBAL_FULL_STATUS_WIDTH = 2;
51 const int32_t SCREEN_HEIGHT = 3;
52 const int32_t FULL_STATUS_OFFSET_X = 4;
53 const int32_t PARAMS_VECTOR_SIZE = 5;
54 } // namespace
55 WM_IMPLEMENT_SINGLE_INSTANCE(SecondaryFoldSensorManager);
56 
SecondarySensorPostureDataCallback(SensorEvent * event)57 static void SecondarySensorPostureDataCallback(SensorEvent *event)
58 {
59     SecondaryFoldSensorManager::GetInstance().HandlePostureData(event);
60 }
61 
SecondarySensorHallDataCallbackExt(SensorEvent * event)62 static void SecondarySensorHallDataCallbackExt(SensorEvent *event)
63 {
64     SecondaryFoldSensorManager::GetInstance().HandleHallDataExt(event);
65 }
66 
SetFoldScreenPolicy(sptr<FoldScreenPolicy> foldScreenPolicy)67 void SecondaryFoldSensorManager::SetFoldScreenPolicy(sptr<FoldScreenPolicy> foldScreenPolicy)
68 {
69     foldScreenPolicy_ = foldScreenPolicy;
70 }
71 
SetSensorFoldStateManager(sptr<SensorFoldStateManager> sensorFoldStateManager)72 void SecondaryFoldSensorManager::SetSensorFoldStateManager(sptr<SensorFoldStateManager> sensorFoldStateManager)
73 {
74     sensorFoldStateManager_ = sensorFoldStateManager;
75 }
76 
RegisterPostureCallback()77 void SecondaryFoldSensorManager::RegisterPostureCallback()
78 {
79     postureUser.callback = SecondarySensorPostureDataCallback;
80     int32_t subscribeRet = SubscribeSensor(SENSOR_TYPE_ID_POSTURE, &postureUser);
81     int32_t setBatchRet = SetBatch(SENSOR_TYPE_ID_POSTURE, &postureUser, POSTURE_INTERVAL, POSTURE_INTERVAL);
82     int32_t activateRet = ActivateSensor(SENSOR_TYPE_ID_POSTURE, &postureUser);
83     TLOGI(WmsLogTag::DMS,
84         "subscribeRet: %{public}d, setBatchRet: %{public}d, activateRet: %{public}d",
85         subscribeRet, setBatchRet, activateRet);
86     if (subscribeRet != SENSOR_SUCCESS || setBatchRet != SENSOR_SUCCESS || activateRet != SENSOR_SUCCESS) {
87         TLOGE(WmsLogTag::DMS, "failed.");
88     } else {
89         registerPosture_ = true;
90         TLOGI(WmsLogTag::DMS, "success.");
91     }
92 }
93 
UnRegisterPostureCallback()94 void SecondaryFoldSensorManager::UnRegisterPostureCallback()
95 {
96     int32_t deactivateRet = DeactivateSensor(SENSOR_TYPE_ID_POSTURE, &postureUser);
97     int32_t unsubscribeRet = UnsubscribeSensor(SENSOR_TYPE_ID_POSTURE, &postureUser);
98     TLOGI(WmsLogTag::DMS, "deactivateRet: %{public}d, unsubscribeRet: %{public}d",
99         deactivateRet, unsubscribeRet);
100     if (deactivateRet == SENSOR_SUCCESS && unsubscribeRet == SENSOR_SUCCESS) {
101         registerPosture_ = false;
102         TLOGI(WmsLogTag::DMS, "success.");
103     }
104 }
105 
RegisterHallCallback()106 void SecondaryFoldSensorManager::RegisterHallCallback()
107 {
108     hallUser.callback = SecondarySensorHallDataCallbackExt;
109     int32_t subscribeRet = SubscribeSensor(SENSOR_TYPE_ID_HALL_EXT, &hallUser);
110     TLOGI(WmsLogTag::DMS, "subscribeRet: %{public}d", subscribeRet);
111     int32_t setBatchRet = SetBatch(SENSOR_TYPE_ID_HALL_EXT, &hallUser, POSTURE_INTERVAL, POSTURE_INTERVAL);
112     TLOGI(WmsLogTag::DMS, "setBatchRet: %{public}d", setBatchRet);
113     int32_t activateRet = ActivateSensor(SENSOR_TYPE_ID_HALL_EXT, &hallUser);
114     TLOGI(WmsLogTag::DMS, "activateRet: %{public}d", activateRet);
115     if (subscribeRet != SENSOR_SUCCESS || setBatchRet != SENSOR_SUCCESS || activateRet != SENSOR_SUCCESS) {
116         TLOGE(WmsLogTag::DMS, "failed.");
117     } else {
118         TLOGI(WmsLogTag::DMS, "success.");
119     }
120 }
121 
UnRegisterHallCallback()122 void SecondaryFoldSensorManager::UnRegisterHallCallback()
123 {
124     int32_t deactivateRet = DeactivateSensor(SENSOR_TYPE_ID_HALL_EXT, &hallUser);
125     int32_t unsubscribeRet = UnsubscribeSensor(SENSOR_TYPE_ID_HALL_EXT, &hallUser);
126     if (deactivateRet == SENSOR_SUCCESS && unsubscribeRet == SENSOR_SUCCESS) {
127         TLOGW(WmsLogTag::DMS, "success.");
128     }
129 }
130 
HandlePostureData(const SensorEvent * const event)131 void SecondaryFoldSensorManager::HandlePostureData(const SensorEvent * const event)
132 {
133     float postureBc = 0.0F;
134     float postureAb = 0.0F;
135     float postureAbAnti = 0.0F;
136     if (!GetPostureInner(event, postureBc, postureAb, postureAbAnti)) {
137         return;
138     }
139     globalAngle_[FIRST_DATA] = postureBc;
140     globalAngle_[SECOND_DATA] = postureAb;
141     globalAngle_[THIRD_DATA] = postureAbAnti;
142     if (IsDataBeyondBoundary()) {
143         return;
144     }
145     TLOGD(WmsLogTag::DMS, "%{public}s, %{public}s",
146         FoldScreenStateInternel::TransVec2Str(globalAngle_, "angle").c_str(),
147         FoldScreenStateInternel::TransVec2Str(globalHall_, "hall").c_str());
148     if (sensorFoldStateManager_ == nullptr) {
149         return;
150     }
151     sensorFoldStateManager_->HandleAngleOrHallChange(globalAngle_, globalHall_, foldScreenPolicy_);
152     NotifyFoldAngleChanged(globalAngle_);
153 }
154 
NotifyFoldAngleChanged(const std::vector<float> & angles)155 void SecondaryFoldSensorManager::NotifyFoldAngleChanged(const std::vector<float> &angles)
156 {
157     if (angles.size() < SECONDARY_HALL_SIZE) {
158         return;
159     }
160     bool bcFlag = fabs(angles[0] - oldFoldAngle[0]) < MINI_NOTIFY_FOLD_ANGLE;
161     bool abFlag = fabs(angles[1] - oldFoldAngle[1]) < MINI_NOTIFY_FOLD_ANGLE;
162     if (bcFlag && abFlag) {
163         return;
164     }
165     oldFoldAngle[0] = angles[0];
166     oldFoldAngle[1] = angles[1];
167     std::vector<float> notifyAngles = {angles[0], angles[1]};
168     ScreenSessionManager::GetInstance().NotifyFoldAngleChanged(notifyAngles);
169 }
170 
HandleHallDataExt(const SensorEvent * const event)171 void SecondaryFoldSensorManager::HandleHallDataExt(const SensorEvent * const event)
172 {
173     uint16_t hallBc = 0;
174     uint16_t hallAb = 0;
175     if (!GetHallInner(event, hallBc, hallAb)) {
176         return;
177     }
178     globalHall_[FIRST_DATA] = hallBc;
179     globalHall_[SECOND_DATA] = hallAb;
180     if (IsDataBeyondBoundary()) {
181         return;
182     }
183     TLOGI(WmsLogTag::DMS, "%{public}s, %{public}s",
184         FoldScreenStateInternel::TransVec2Str(globalAngle_, "angle").c_str(),
185         FoldScreenStateInternel::TransVec2Str(globalHall_, "hall").c_str());
186     if (!registerPosture_) {
187         globalAngle_[FIRST_DATA] = ANGLE_MIN_VAL;
188         globalAngle_[SECOND_DATA] = ANGLE_MIN_VAL;
189         globalAngle_[THIRD_DATA] = ANGLE_MIN_VAL;
190     }
191     if (sensorFoldStateManager_ == nullptr) {
192         return;
193     }
194     sensorFoldStateManager_->HandleAngleOrHallChange(globalAngle_, globalHall_, foldScreenPolicy_);
195     return;
196 }
197 
IsDataBeyondBoundary()198 bool SecondaryFoldSensorManager::IsDataBeyondBoundary()
199 {
200     if (globalAngle_.size() < SECONDARY_POSTURE_SIZE || globalHall_.size() < SECONDARY_HALL_SIZE) {
201         TLOGE(WmsLogTag::DMS, "oversize, global angles: %{public}zu, halls size: %{public}zu.",
202             globalAngle_.size(), globalHall_.size());
203         return true;
204     }
205     for (size_t i = 0; i < SECONDARY_POSTURE_SIZE - 1; i++) {
206         float angle = globalAngle_[i];
207         if (std::isless(angle, ANGLE_MIN_VAL) ||
208             std::isgreater(angle, ANGLE_MAX_VAL + ACCURACY_ERROR_FOR_ALTA)) {
209             TLOGE(WmsLogTag::DMS, "i = %{public}zu, angle = %{public}f", i, angle);
210             return true;
211         }
212     }
213     for (size_t i = 0; i < SECONDARY_HALL_SIZE; i++) {
214         uint16_t hall = globalHall_[i];
215         if (hall != 0 && hall != 1) {
216             TLOGE(WmsLogTag::DMS, "i = %{public}zu, hall = %{public}u", i, hall);
217             return true;
218         }
219     }
220     return false;
221 }
222 
GetPostureInner(const SensorEvent * const event,float & valueBc,float & valueAb,float & valueAbAnti)223 bool SecondaryFoldSensorManager::GetPostureInner(const SensorEvent * const event, float &valueBc, float &valueAb,
224     float &valueAbAnti)
225 {
226     if (event == nullptr) {
227         TLOGW(WmsLogTag::DMS, "SensorEvent is nullptr.");
228         return false;
229     }
230     if (event[SENSOR_EVENT_FIRST_DATA].data == nullptr) {
231         TLOGW(WmsLogTag::DMS, "SensorEvent[0].data is nullptr.");
232         return false;
233     }
234     if (event[SENSOR_EVENT_FIRST_DATA].dataLen < sizeof(FoldScreenSensorManager::PostureDataSecondary)) {
235         TLOGW(WmsLogTag::DMS, "SensorEvent dataLen less than posture data size.");
236         return false;
237     }
238     FoldScreenSensorManager::PostureDataSecondary *postureData =
239         reinterpret_cast<FoldScreenSensorManager::PostureDataSecondary *>(event[SENSOR_EVENT_FIRST_DATA].data);
240     valueBc = (*postureData).postureBc;
241     valueAb = (*postureData).postureAb;
242     valueAbAnti = (*postureData).postureAbAnti;
243     TLOGD(WmsLogTag::DMS, "postureBc: %{public}f, postureAb: %{public}f, postureAbAnti: %{public}f.",
244         valueBc, valueAb, valueAbAnti);
245     return true;
246 }
247 
GetHallInner(const SensorEvent * const event,uint16_t & valueBc,uint16_t & valueAb)248 bool SecondaryFoldSensorManager::GetHallInner(const SensorEvent * const event, uint16_t &valueBc, uint16_t &valueAb)
249 {
250     if (event == nullptr) {
251         TLOGW(WmsLogTag::DMS, "SensorEvent is nullptr.");
252         return false;
253     }
254     if (event[SENSOR_EVENT_FIRST_DATA].data == nullptr) {
255         TLOGW(WmsLogTag::DMS, "SensorEvent[0].data is nullptr.");
256         return false;
257     }
258     if (event[SENSOR_EVENT_FIRST_DATA].dataLen < sizeof(FoldScreenSensorManager::ExtHallData)) {
259         TLOGW(WmsLogTag::DMS, "SensorEvent dataLen less than hall data size.");
260         return false;
261     }
262     FoldScreenSensorManager::ExtHallData *extHallData =
263         reinterpret_cast<FoldScreenSensorManager::ExtHallData *>(event[SENSOR_EVENT_FIRST_DATA].data);
264     uint16_t flag = static_cast<uint16_t>((*extHallData).flag);
265     if (!(flag & (1 << HALL_B_C_COLUMN_ORDER)) || !(flag & (1 << HALL_A_B_COLUMN_ORDER))) {
266         TLOGW(WmsLogTag::DMS, "not support Extend Hall.");
267         return false;
268     }
269     valueBc = static_cast<uint16_t>((*extHallData).hall); // axis of bc screen. 0: hall closed, 1: hall expaned
270     valueAb = static_cast<uint16_t>((*extHallData).hallAb);
271     TLOGI(WmsLogTag::DMS, "hallBc: %{public}u, hallAb: %{public}u.", valueBc, valueAb);
272     return true;
273 }
274 
PowerKeySetScreenActiveRect()275 void SecondaryFoldSensorManager::PowerKeySetScreenActiveRect()
276 {
277     if (foldScreenPolicy_->GetScreenParams().size() != PARAMS_VECTOR_SIZE) {
278         return;
279     }
280     uint32_t x = 0;
281     uint32_t y = 0;
282     uint32_t width = foldScreenPolicy_->GetScreenParams()[SCREEN_HEIGHT];
283     uint32_t height = 0;
284     if (foldScreenPolicy_->currentDisplayMode_ == FoldDisplayMode::FULL) {
285         y = foldScreenPolicy_->GetScreenParams()[FULL_STATUS_OFFSET_X];
286         height = foldScreenPolicy_->GetScreenParams()[FULL_STATUS_WIDTH];
287     } else if (foldScreenPolicy_->currentDisplayMode_ == FoldDisplayMode::MAIN) {
288         height = foldScreenPolicy_->GetScreenParams()[MAIN_STATUS_WIDTH];
289     } else if (foldScreenPolicy_->currentDisplayMode_ == FoldDisplayMode::GLOBAL_FULL) {
290         height = foldScreenPolicy_->GetScreenParams()[GLOBAL_FULL_STATUS_WIDTH];
291     } else {
292         TLOGW(WmsLogTag::DMS, "displayMode[%{public}u] unknown.", foldScreenPolicy_->currentDisplayMode_);
293         return;
294     }
295     OHOS::Rect rectCur {
296         .x = x,
297         .y = y,
298         .w = width,
299         .h = height,
300     };
301     RSInterfaces::GetInstance().SetScreenActiveRect(0, rectCur);
302     isPowerRectExe_ = true;
303 }
304 
IsPostureUserCallbackInvalid() const305 bool SecondaryFoldSensorManager::IsPostureUserCallbackInvalid() const
306 {
307     return postureUser.callback == nullptr;
308 }
309 
IsHallUserCallbackInvalid() const310 bool SecondaryFoldSensorManager::IsHallUserCallbackInvalid() const
311 {
312     return hallUser.callback == nullptr;
313 }
314 
GetGlobalAngle() const315 std::vector<float> SecondaryFoldSensorManager::GetGlobalAngle() const
316 {
317     return globalAngle_;
318 }
319 
GetGlobalHall() const320 std::vector<uint16_t> SecondaryFoldSensorManager::GetGlobalHall() const
321 {
322     return globalHall_;
323 }
324 } // Rosen
325 } // OHOS
326 #endif