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