• 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 "fold_screen_controller/sensor_fold_state_manager/dual_display_sensor_fold_state_manager.h"
17 #include <iservice_registry.h>
18 #include <parameters.h>
19 #include <refbase.h>
20 #include <map>
21 #include <string>
22 #include <utility>
23 #include <vector>
24 
25 #include "app_mgr_client.h"
26 #include "app_service_manager.h"
27 #include "app_mgr_constants.h"
28 #include "app_mgr_interface.h"
29 
30 #include "fold_screen_controller/sensor_fold_state_manager/sensor_fold_state_manager.h"
31 #include "session/screen/include/screen_session.h"
32 #include "screen_scene_config.h"
33 #include "iremote_object.h"
34 #include "window_manager_hilog.h"
35 
36 #ifdef POWER_MANAGER_ENABLE
37 #include <power_mgr_client.h>
38 #endif
39 
40 namespace OHOS::Rosen {
41 using OHOS::AppExecFwk::AppStateData;
42 using OHOS::AppExecFwk::ApplicationState;
43 namespace {
44 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "DualDisplaySensorFoldStateManager"};
45 const float INWARD_FOLDED_THRESHOLD = static_cast<float>(system::GetIntParameter<int32_t>
46     ("const.fold.folded_threshold", 85));
47 const float INWARD_EXPAND_THRESHOLD = static_cast<float>(system::GetIntParameter<int32_t>
48     ("const.fold.expand_threshold", 145));
49 const float INWARD_HALF_FOLDED_MAX_THRESHOLD = static_cast<float>(system::GetIntParameter<int32_t>
50     ("const.half_folded_max_threshold", 135));
51 const float INWARD_HALF_FOLDED_MIN_THRESHOLD = static_cast<float>(system::GetIntParameter<int32_t>
52     ("const.fold.half_folded_min_threshold", 85));
53 constexpr int32_t HALL_THRESHOLD = 1;
54 constexpr int32_t HALL_FOLDED_THRESHOLD = 0;
55 constexpr float ANGLE_MIN_VAL = 0.0F;
56 constexpr float INWARD_FOLDED_LOWER_THRESHOLD = 10.0F;
57 constexpr float INWARD_FOLDED_UPPER_THRESHOLD = 20.0F;
58 constexpr float ANGLE_BUFFER = 0.001F;
59 constexpr float HALL_ZERO_INVALID_POSTURE = 170.0F;
60 } // namespace
61 
DualDisplaySensorFoldStateManager()62 DualDisplaySensorFoldStateManager::DualDisplaySensorFoldStateManager()
63 {
64     auto stringListConfig = ScreenSceneConfig::GetStringListConfig();
65     if (stringListConfig.count("hallSwitchApp") != 0) {
66         hallSwitchPackageNameList_ = stringListConfig["hallSwitchApp"];
67     }
68 }
69 
~DualDisplaySensorFoldStateManager()70 DualDisplaySensorFoldStateManager::~DualDisplaySensorFoldStateManager() {}
71 
HandleAngleChange(float angle,int hall,sptr<FoldScreenPolicy> foldScreenPolicy)72 void DualDisplaySensorFoldStateManager::HandleAngleChange(float angle, int hall,
73     sptr<FoldScreenPolicy> foldScreenPolicy)
74 {
75     if (std::islessequal(angle, INWARD_FOLDED_THRESHOLD + ANGLE_BUFFER) && hall == HALL_THRESHOLD) {
76         return;
77     }
78     if (std::isgreaterequal(angle, HALL_ZERO_INVALID_POSTURE + ANGLE_BUFFER) && hall == HALL_FOLDED_THRESHOLD) {
79         return;
80     }
81     if (std::isless(angle, ANGLE_MIN_VAL + ANGLE_BUFFER)) {
82         return;
83     }
84     if (hall == HALL_FOLDED_THRESHOLD) {
85         angle = ANGLE_MIN_VAL;
86     }
87     FoldStatus nextState = GetNextFoldState(angle, hall);
88     if (nextState != GetCurrentState()) {
89         TLOGI(WmsLogTag::DMS, "angle: %{public}f, hall: %{public}d.", angle, hall);
90     }
91     HandleSensorChange(nextState, angle, foldScreenPolicy);
92 }
93 
HandleHallChange(float angle,int hall,sptr<FoldScreenPolicy> foldScreenPolicy)94 void DualDisplaySensorFoldStateManager::HandleHallChange(float angle, int hall,
95     sptr<FoldScreenPolicy> foldScreenPolicy)
96 {
97     if (applicationStateObserver_ != nullptr && hall == HALL_THRESHOLD
98         && PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
99         if (std::count(hallSwitchPackageNameList_.begin(), hallSwitchPackageNameList_.end(),
100             applicationStateObserver_->GetForegroundApp())) {
101             isHallSwitchApp_ = false;
102             return;
103         }
104     }
105     if (hall == HALL_THRESHOLD) {
106         angle = INWARD_HALF_FOLDED_MIN_THRESHOLD + 1.0f;
107     }
108     FoldStatus nextState = GetNextFoldState(angle, hall);
109     if (nextState != GetCurrentState()) {
110         TLOGI(WmsLogTag::DMS, "angle: %{public}f, hall: %{public}d.", angle, hall);
111     }
112     HandleSensorChange(nextState, angle, foldScreenPolicy);
113 }
114 
GetNextFoldState(float angle,int hall)115 FoldStatus DualDisplaySensorFoldStateManager::GetNextFoldState(float angle, int hall)
116 {
117     FoldStatus state = GetCurrentState();
118     // EXPAND
119     if (std::isgreaterequal(angle, INWARD_EXPAND_THRESHOLD + ANGLE_BUFFER)) {
120         isHallSwitchApp_ = true;
121         return FoldStatus::EXPAND;
122     }
123     // FOLDED
124     if (std::islessequal(angle, INWARD_FOLDED_LOWER_THRESHOLD + ANGLE_BUFFER)) {
125         isHallSwitchApp_ = true;
126         return FoldStatus::FOLDED;
127     }
128     // HALF_FOLD
129     if (isHallSwitchApp_) {
130         ProcessHalfFoldState(state, angle, INWARD_FOLDED_UPPER_THRESHOLD, INWARD_HALF_FOLDED_MAX_THRESHOLD);
131     } else {
132         ProcessHalfFoldState(state, angle, INWARD_HALF_FOLDED_MIN_THRESHOLD, INWARD_HALF_FOLDED_MAX_THRESHOLD);
133         isHallSwitchApp_ = true;
134     }
135     return state;
136 }
ProcessHalfFoldState(FoldStatus & state,float angle,float halfFoldMinThreshold,float halfFoldMaxThreshold)137 void DualDisplaySensorFoldStateManager::ProcessHalfFoldState(FoldStatus& state, float angle,
138     float halfFoldMinThreshold, float halfFoldMaxThreshold)
139 {
140     if (std::isgreaterequal(angle, halfFoldMinThreshold + ANGLE_BUFFER)
141         && std::islessequal(angle, halfFoldMaxThreshold + ANGLE_BUFFER)) {
142         state = FoldStatus::HALF_FOLD;
143     }
144 }
145 
RegisterApplicationStateObserver()146 void DualDisplaySensorFoldStateManager::RegisterApplicationStateObserver()
147 {
148     applicationStateObserver_ = new (std::nothrow) ApplicationStateObserver();
149     if (applicationStateObserver_ == nullptr) {
150         WLOGFE("applicationStateObserver_ is nullptr.");
151         return;
152     }
153     auto appMgrClient_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
154     if (appMgrClient_ == nullptr) {
155         WLOGFE("appMgrClient_ is nullptr.");
156         return;
157     }
158     int32_t flag =
159         appMgrClient_->RegisterApplicationStateObserver(applicationStateObserver_, hallSwitchPackageNameList_);
160     if (flag != ERR_OK) {
161         WLOGFE("Register app state listener failed, flag = %{public}d", flag);
162     } else {
163         WLOGFI("Register app state listener success.");
164     }
165 }
166 
ApplicationStateObserver()167 ApplicationStateObserver::ApplicationStateObserver() {}
168 
OnForegroundApplicationChanged(const AppStateData & appStateData)169 void ApplicationStateObserver::OnForegroundApplicationChanged(const AppStateData &appStateData)
170 {
171     if (appStateData.state == static_cast<int32_t>(ApplicationState::APP_STATE_FOREGROUND)) {
172         foregroundBundleName_ = appStateData.bundleName;
173         WLOGFI("APP_STATE_FOREGROUND, packageName= %{public}s", foregroundBundleName_.c_str());
174     }
175     if (appStateData.state == static_cast<int32_t>(ApplicationState::APP_STATE_BACKGROUND)
176         && foregroundBundleName_.compare(appStateData.bundleName) == 0) {
177         foregroundBundleName_ = "" ;
178     }
179 }
180 
GetForegroundApp()181 std::string ApplicationStateObserver::GetForegroundApp()
182 {
183     return foregroundBundleName_;
184 }
185 } // namespace OHOS::Rosen