• 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 #include <parameters.h>
17 #include <hisysevent.h>
18 
19 #include "fold_screen_controller/fold_screen_policy.h"
20 #include "fold_screen_controller/sensor_fold_state_manager/single_display_sensor_pocket_fold_state_manager.h"
21 #include "fold_screen_controller/sensor_fold_state_manager/sensor_fold_state_manager.h"
22 #include "session/screen/include/screen_session.h"
23 #include "screen_scene_config.h"
24 
25 #include "window_manager_hilog.h"
26 #include "app_mgr_client.h"
27 #include "screen_session_manager/include/screen_rotation_property.h"
28 #include "screen_session_manager.h"
29 #include "sensor_agent.h"
30 #include "sensor_agent_type.h"
31 
32 #ifdef POWER_MANAGER_ENABLE
33 #include <power_mgr_client.h>
34 #endif
35 
36 namespace OHOS::Rosen {
37 using OHOS::AppExecFwk::AppStateData;
38 using OHOS::AppExecFwk::ApplicationState;
39 namespace {
40 const std::string CAMERA_NAME = "camera";
41 constexpr float ANGLE_MIN_VAL = 0.0F;
42 constexpr float ALTA_HALF_FOLDED_MAX_THRESHOLD = 140.0F;
43 constexpr float CLOSE_ALTA_HALF_FOLDED_MIN_THRESHOLD = 70.0F;
44 constexpr float OPEN_ALTA_HALF_FOLDED_MIN_THRESHOLD = 25.0F;
45 constexpr float ALTA_HALF_FOLDED_BUFFER = 10.0F;
46 constexpr float LARGER_BOUNDARY_FOR_ALTA_THRESHOLD = 90.0F;
47 constexpr int32_t LARGER_BOUNDARY_FLAG = 1;
48 constexpr int32_t SMALLER_BOUNDARY_FLAG = 0;
49 constexpr int32_t HALL_THRESHOLD = 1;
50 constexpr int32_t HALL_FOLDED_THRESHOLD = 0;
51 constexpr float TENT_MODE_EXIT_MIN_THRESHOLD = 5.0F;
52 constexpr float TENT_MODE_EXIT_MAX_THRESHOLD = 175.0F;
53 constexpr int32_t TENT_MODE_OFF = 0;
54 constexpr int32_t TENT_MODE_ON = 1;
55 constexpr int32_t TENT_MODE_HOVER_ON = 2;
56 } // namespace
57 
SingleDisplaySensorPocketFoldStateManager()58 SingleDisplaySensorPocketFoldStateManager::SingleDisplaySensorPocketFoldStateManager()
59 {
60     auto stringListConfig = ScreenSceneConfig::GetStringListConfig();
61     if (stringListConfig.count("hallSwitchApp") != 0) {
62         hallSwitchPackageNameList_ = stringListConfig["hallSwitchApp"];
63     }
64 }
~SingleDisplaySensorPocketFoldStateManager()65 SingleDisplaySensorPocketFoldStateManager::~SingleDisplaySensorPocketFoldStateManager() {}
66 
HandleAngleChange(float angle,int hall,sptr<FoldScreenPolicy> foldScreenPolicy)67 void SingleDisplaySensorPocketFoldStateManager::HandleAngleChange(float angle, int hall,
68     sptr<FoldScreenPolicy> foldScreenPolicy)
69 {
70     currentAngle = angle;
71     if (IsTentMode()) {
72         return TentModeHandleSensorChange(angle, hall, foldScreenPolicy);
73     }
74     FoldStatus nextState = GetNextFoldState(angle, hall);
75     HandleSensorChange(nextState, angle, foldScreenPolicy);
76 }
77 
HandleHallChange(float angle,int hall,sptr<FoldScreenPolicy> foldScreenPolicy)78 void SingleDisplaySensorPocketFoldStateManager::HandleHallChange(float angle, int hall,
79     sptr<FoldScreenPolicy> foldScreenPolicy)
80 {
81     currentHall = hall;
82     if (IsTentMode()) {
83         return TentModeHandleSensorChange(angle, hall, foldScreenPolicy);
84     }
85     FoldStatus nextState = GetNextFoldState(angle, hall);
86     HandleSensorChange(nextState, angle, foldScreenPolicy);
87 }
88 
UpdateSwitchScreenBoundaryForLargeFoldDevice(float angle,int hall)89 void SingleDisplaySensorPocketFoldStateManager::UpdateSwitchScreenBoundaryForLargeFoldDevice(float angle, int hall)
90 {
91     if (hall == HALL_FOLDED_THRESHOLD) {
92         allowUserSensorForLargeFoldDevice = SMALLER_BOUNDARY_FLAG;
93     } else if (angle >= LARGER_BOUNDARY_FOR_ALTA_THRESHOLD) {
94         allowUserSensorForLargeFoldDevice = LARGER_BOUNDARY_FLAG;
95     }
96 }
97 
GetNextFoldState(float angle,int hall)98 FoldStatus SingleDisplaySensorPocketFoldStateManager::GetNextFoldState(float angle, int hall)
99 {
100     UpdateSwitchScreenBoundaryForLargeFoldDevice(angle, hall);
101     FoldStatus currentState = GetCurrentState();
102     if (std::isless(angle, ANGLE_MIN_VAL)) {
103         return currentState;
104     }
105     FoldStatus state;
106 
107     if (allowUserSensorForLargeFoldDevice == SMALLER_BOUNDARY_FLAG) {
108         if (std::islessequal(angle, OPEN_ALTA_HALF_FOLDED_MIN_THRESHOLD) && hall == HALL_FOLDED_THRESHOLD) {
109             state = FoldStatus::FOLDED;
110         } else if (std::isgreaterequal(angle, OPEN_ALTA_HALF_FOLDED_MIN_THRESHOLD + ALTA_HALF_FOLDED_BUFFER) &&
111             hall == HALL_FOLDED_THRESHOLD) {
112             state = FoldStatus::HALF_FOLD;
113         } else if (std::islessequal(angle, ALTA_HALF_FOLDED_MAX_THRESHOLD - ALTA_HALF_FOLDED_BUFFER) &&
114             hall == HALL_THRESHOLD) {
115             state = FoldStatus::HALF_FOLD;
116         } else if (std::isgreaterequal(angle, ALTA_HALF_FOLDED_MAX_THRESHOLD)) {
117             state = FoldStatus::EXPAND;
118         } else {
119             state = currentState;
120             if (state == FoldStatus::UNKNOWN) {
121                 state = FoldStatus::HALF_FOLD;
122             }
123         }
124         return state;
125     }
126 
127     if (hall == HALL_THRESHOLD && angle == OPEN_ALTA_HALF_FOLDED_MIN_THRESHOLD) {
128         state = currentState;
129     } else if (std::islessequal(angle, CLOSE_ALTA_HALF_FOLDED_MIN_THRESHOLD)) {
130         state = FoldStatus::FOLDED;
131     } else if (std::islessequal(angle, ALTA_HALF_FOLDED_MAX_THRESHOLD - ALTA_HALF_FOLDED_BUFFER) &&
132         std::isgreater(angle, CLOSE_ALTA_HALF_FOLDED_MIN_THRESHOLD + ALTA_HALF_FOLDED_BUFFER)) {
133         state = FoldStatus::HALF_FOLD;
134     } else if (std::isgreaterequal(angle, ALTA_HALF_FOLDED_MAX_THRESHOLD)) {
135         state = FoldStatus::EXPAND;
136     } else {
137         state = currentState;
138         if (state == FoldStatus::UNKNOWN) {
139             state = FoldStatus::HALF_FOLD;
140         }
141     }
142     return state;
143 }
144 
RegisterApplicationStateObserver()145 void SingleDisplaySensorPocketFoldStateManager::RegisterApplicationStateObserver()
146 {
147     applicationStateObserver_ = new (std::nothrow) ApplicationStatePocketObserver();
148     auto appMgrClient_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
149     if (applicationStateObserver_ == nullptr) {
150         TLOGI(WmsLogTag::DMS, "applicationStateObserver_ is nullptr.");
151         return;
152     }
153     if (appMgrClient_ == nullptr) {
154         TLOGE(WmsLogTag::DMS, "appMgrClient_ is nullptr.");
155     } else {
156         auto flag = static_cast<int32_t>(
157             appMgrClient_->RegisterApplicationStateObserver(applicationStateObserver_, hallSwitchPackageNameList_));
158         if (flag != ERR_OK) {
159             TLOGE(WmsLogTag::DMS, "Register app debug listener failed.");
160         } else {
161             TLOGI(WmsLogTag::DMS, "Register app debug listener success.");
162         }
163     }
164 }
165 
HandleTentChange(int tentType,sptr<FoldScreenPolicy> foldScreenPolicy,int32_t hall)166 void SingleDisplaySensorPocketFoldStateManager::HandleTentChange(int tentType,
167     sptr<FoldScreenPolicy> foldScreenPolicy, int32_t hall)
168 {
169     if (tentType == tentModeType_) {
170         TLOGI(WmsLogTag::DMS, "Repeat reporting tent mode:%{public}d, no processing", tentModeType_);
171         return;
172     }
173 
174     SetTentMode(tentType);
175     if (foldScreenPolicy == nullptr) {
176         TLOGE(WmsLogTag::DMS, "foldScreenPolicy is nullptr");
177         return;
178     }
179     if (tentType != TENT_MODE_OFF) {
180         ReportTentStatusChange(ReportTentModeStatus::NORMAL_ENTER_TENT_MODE);
181         HandleSensorChange(FoldStatus::FOLDED, currentAngle, foldScreenPolicy);
182         foldScreenPolicy->ChangeOnTentMode(FoldStatus::FOLDED);
183         if (tentType == TENT_MODE_ON) {
184             SetDeviceStatusAndParam(static_cast<uint32_t>(DMDeviceStatus::STATUS_TENT));
185             ScreenRotationProperty::HandleHoverStatusEventInput(DeviceHoverStatus::TENT_STATUS);
186         } else if (tentType == TENT_MODE_HOVER_ON) {
187             SetDeviceStatusAndParam(static_cast<uint32_t>(DMDeviceStatus::STATUS_TENT_HOVER));
188             ScreenRotationProperty::HandleHoverStatusEventInput(DeviceHoverStatus::TENT_STATUS_HOVER);
189         }
190     } else {
191         if (hall == HALL_FOLDED_THRESHOLD) {
192             currentAngle = ANGLE_MIN_VAL;
193         }
194         FoldStatus nextState = FoldStatus::UNKNOWN;
195         if (hall == -1) {
196             nextState = GetNextFoldState(currentAngle, currentHall);
197         } else {
198             nextState = GetNextFoldState(currentAngle, hall);
199         }
200         if (nextState == FoldStatus::FOLDED) {
201             SetDeviceStatusAndParam(static_cast<uint32_t>(DMDeviceStatus::STATUS_FOLDED));
202         } else {
203             SetDeviceStatusAndParam(static_cast<uint32_t>(DMDeviceStatus::UNKNOWN));
204         }
205         HandleSensorChange(nextState, currentAngle, foldScreenPolicy);
206         ReportTentStatusChange(ReportTentModeStatus::NORMAL_EXIT_TENT_MODE);
207         foldScreenPolicy->ChangeOffTentMode();
208         ScreenRotationProperty::HandleHoverStatusEventInput(DeviceHoverStatus::TENT_STATUS_CANCEL);
209     }
210 }
211 
TriggerTentExit(float angle,int hall)212 bool SingleDisplaySensorPocketFoldStateManager::TriggerTentExit(float angle, int hall)
213 {
214     if (hall == HALL_FOLDED_THRESHOLD) {
215         ReportTentStatusChange(ReportTentModeStatus::ABNORMAL_EXIT_TENT_MODE_DUE_TO_HALL);
216         TLOGI(WmsLogTag::DMS, "Exit tent mode due to hall sensor report folded");
217         return true;
218     }
219 
220     if (std::isless(angle, TENT_MODE_EXIT_MIN_THRESHOLD) || std::isgreater(angle, TENT_MODE_EXIT_MAX_THRESHOLD)) {
221         ReportTentStatusChange(ReportTentModeStatus::ABNORMAL_EXIT_TENT_MODE_DUE_TO_ANGLE);
222         TLOGI(WmsLogTag::DMS, "Exit tent mode due to angle sensor report angle:%{public}f", angle);
223         return true;
224     }
225 
226     return false;
227 }
228 
TentModeHandleSensorChange(float angle,int hall,sptr<FoldScreenPolicy> foldScreenPolicy)229 void SingleDisplaySensorPocketFoldStateManager::TentModeHandleSensorChange(float angle, int hall,
230     sptr<FoldScreenPolicy> foldScreenPolicy)
231 {
232     if (TriggerTentExit(angle, hall)) {
233         FoldStatus nextState = GetNextFoldState(angle, hall);
234         HandleSensorChange(nextState, angle, foldScreenPolicy);
235         TLOGI(WmsLogTag::DMS, "exit tent mode. angle: %{public}f, hall: %{public}d", angle, hall);
236         SetTentMode(TENT_MODE_OFF);
237         if (nextState == FoldStatus::FOLDED) {
238             SetDeviceStatusAndParam(static_cast<uint32_t>(DMDeviceStatus::STATUS_FOLDED));
239         } else {
240             SetDeviceStatusAndParam(static_cast<uint32_t>(DMDeviceStatus::UNKNOWN));
241         }
242         ScreenRotationProperty::HandleHoverStatusEventInput(DeviceHoverStatus::TENT_STATUS_CANCEL);
243     }
244 }
245 
ReportTentStatusChange(ReportTentModeStatus tentStatus)246 void SingleDisplaySensorPocketFoldStateManager::ReportTentStatusChange(ReportTentModeStatus tentStatus)
247 {
248     int32_t status = static_cast<int32_t>(tentStatus);
249     TLOGI(WmsLogTag::DMS, "report tentStatus: %{public}d", status);
250     int32_t ret = HiSysEventWrite(
251         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
252         "FOLD_TENT_MODE",
253         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
254         "FOLD_TENT_STATUS", status);
255     if (ret != 0) {
256         TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d", ret);
257     }
258 }
259 
ApplicationStatePocketObserver()260 ApplicationStatePocketObserver::ApplicationStatePocketObserver() {}
261 
RegisterCameraForegroundChanged(std::function<void ()> callback)262 void ApplicationStatePocketObserver::RegisterCameraForegroundChanged(std::function<void()> callback)
263 {
264     onCameraForegroundChanged_ = callback;
265 }
266 
OnForegroundApplicationChanged(const AppStateData & appStateData)267 void ApplicationStatePocketObserver::OnForegroundApplicationChanged(const AppStateData &appStateData)
268 {
269     if (appStateData.state == static_cast<int32_t>(ApplicationState::APP_STATE_FOREGROUND)) {
270         if (appStateData.bundleName.find(CAMERA_NAME) != std::string::npos) {
271             isCameraForeground_ = true;
272         }
273         foregroundBundleName_ = appStateData.bundleName;
274     }
275     if (appStateData.state == static_cast<int32_t>(ApplicationState::APP_STATE_BACKGROUND)) {
276         if (appStateData.bundleName.find(CAMERA_NAME) != std::string::npos) {
277             isCameraForeground_ = false;
278         }
279         if (foregroundBundleName_.compare(appStateData.bundleName) == 0) {
280             foregroundBundleName_ = "" ;
281         }
282     }
283     if (appStateData.bundleName.find(CAMERA_NAME) != std::string::npos) {
284         if (onCameraForegroundChanged_ == nullptr) {
285             TLOGE(WmsLogTag::DMS, "onCameraForegroundChanged_ not register");
286             return;
287         }
288     }
289 }
290 
IsCameraForeground()291 bool ApplicationStatePocketObserver::IsCameraForeground()
292 {
293     return isCameraForeground_;
294 }
295 
GetForegroundApp()296 std::string ApplicationStatePocketObserver::GetForegroundApp()
297 {
298     return foregroundBundleName_;
299 }
300 
SetDeviceStatusAndParam(uint32_t deviceStatus)301 void SingleDisplaySensorPocketFoldStateManager::SetDeviceStatusAndParam(uint32_t deviceStatus)
302 {
303     TLOGI(WmsLogTag::DMS, "Set device status to: %{public}u", deviceStatus);
304     SetDeviceStatus(deviceStatus);
305     system::SetParameter("persist.dms.device.status", std::to_string(deviceStatus));
306 }
307 } // namespace OHOS::Rosen