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 } // namespace
60
DualDisplaySensorFoldStateManager()61 DualDisplaySensorFoldStateManager::DualDisplaySensorFoldStateManager()
62 {
63 auto stringListConfig = ScreenSceneConfig::GetStringListConfig();
64 if (stringListConfig.count("hallSwitchApp") != 0) {
65 hallSwitchPackageNameList_ = stringListConfig["hallSwitchApp"];
66 }
67 }
68
~DualDisplaySensorFoldStateManager()69 DualDisplaySensorFoldStateManager::~DualDisplaySensorFoldStateManager() {}
70
HandleAngleChange(float angle,int hall,sptr<FoldScreenPolicy> foldScreenPolicy)71 void DualDisplaySensorFoldStateManager::HandleAngleChange(float angle, int hall,
72 sptr<FoldScreenPolicy> foldScreenPolicy)
73 {
74 if (std::islessequal(angle, INWARD_FOLDED_THRESHOLD + ANGLE_BUFFER) && hall == HALL_THRESHOLD) {
75 return;
76 }
77 if (std::isless(angle, ANGLE_MIN_VAL + ANGLE_BUFFER)) {
78 return;
79 }
80 if (hall == HALL_FOLDED_THRESHOLD) {
81 angle = ANGLE_MIN_VAL;
82 }
83 FoldStatus nextState = GetNextFoldState(angle, hall);
84 HandleSensorChange(nextState, angle, foldScreenPolicy);
85 }
86
HandleHallChange(float angle,int hall,sptr<FoldScreenPolicy> foldScreenPolicy)87 void DualDisplaySensorFoldStateManager::HandleHallChange(float angle, int hall,
88 sptr<FoldScreenPolicy> foldScreenPolicy)
89 {
90 if (applicationStateObserver_ != nullptr && hall == HALL_THRESHOLD
91 && PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
92 if (std::count(hallSwitchPackageNameList_.begin(), hallSwitchPackageNameList_.end(),
93 applicationStateObserver_->GetForegroundApp())) {
94 isHallSwitchApp_ = false;
95 return;
96 }
97 }
98 if (hall == HALL_THRESHOLD) {
99 angle = INWARD_HALF_FOLDED_MIN_THRESHOLD + 1.0f;
100 }
101 FoldStatus nextState = GetNextFoldState(angle, hall);
102 HandleSensorChange(nextState, angle, foldScreenPolicy);
103 }
104
GetNextFoldState(float angle,int hall)105 FoldStatus DualDisplaySensorFoldStateManager::GetNextFoldState(float angle, int hall)
106 {
107 FoldStatus state = GetCurrentState();
108 // EXPAND
109 if (std::isgreaterequal(angle, INWARD_EXPAND_THRESHOLD + ANGLE_BUFFER)) {
110 isHallSwitchApp_ = true;
111 return FoldStatus::EXPAND;
112 }
113 // FOLDED
114 if (std::islessequal(angle, INWARD_FOLDED_LOWER_THRESHOLD + ANGLE_BUFFER)) {
115 isHallSwitchApp_ = true;
116 return FoldStatus::FOLDED;
117 }
118 // HALF_FOLD
119 if (isHallSwitchApp_) {
120 ProcessHalfFoldState(state, angle, INWARD_FOLDED_UPPER_THRESHOLD, INWARD_HALF_FOLDED_MAX_THRESHOLD);
121 } else {
122 ProcessHalfFoldState(state, angle, INWARD_HALF_FOLDED_MIN_THRESHOLD, INWARD_HALF_FOLDED_MAX_THRESHOLD);
123 isHallSwitchApp_ = true;
124 }
125 return state;
126 }
ProcessHalfFoldState(FoldStatus & state,float angle,float halfFoldMinThreshold,float halfFoldMaxThreshold)127 void DualDisplaySensorFoldStateManager::ProcessHalfFoldState(FoldStatus& state, float angle,
128 float halfFoldMinThreshold, float halfFoldMaxThreshold)
129 {
130 if (std::isgreaterequal(angle, halfFoldMinThreshold + ANGLE_BUFFER)
131 && std::islessequal(angle, halfFoldMaxThreshold + ANGLE_BUFFER)) {
132 state = FoldStatus::HALF_FOLD;
133 }
134 }
135
RegisterApplicationStateObserver()136 void DualDisplaySensorFoldStateManager::RegisterApplicationStateObserver()
137 {
138 applicationStateObserver_ = new (std::nothrow) ApplicationStateObserver();
139 if (applicationStateObserver_ == nullptr) {
140 WLOGFE("applicationStateObserver_ is nullptr.");
141 return;
142 }
143 auto appMgrClient_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
144 if (appMgrClient_ == nullptr) {
145 WLOGFE("appMgrClient_ is nullptr.");
146 return;
147 }
148 int32_t flag =
149 appMgrClient_->RegisterApplicationStateObserver(applicationStateObserver_, hallSwitchPackageNameList_);
150 if (flag != ERR_OK) {
151 WLOGFE("Register app state listener failed, flag = %{public}d", flag);
152 } else {
153 WLOGFI("Register app state listener success.");
154 }
155 }
156
ApplicationStateObserver()157 ApplicationStateObserver::ApplicationStateObserver() {}
158
OnForegroundApplicationChanged(const AppStateData & appStateData)159 void ApplicationStateObserver::OnForegroundApplicationChanged(const AppStateData &appStateData)
160 {
161 if (appStateData.state == static_cast<int32_t>(ApplicationState::APP_STATE_FOREGROUND)) {
162 foregroundBundleName_ = appStateData.bundleName;
163 WLOGFI("APP_STATE_FOREGROUND, packageName= %{public}s", foregroundBundleName_.c_str());
164 }
165 if (appStateData.state == static_cast<int32_t>(ApplicationState::APP_STATE_BACKGROUND)
166 && foregroundBundleName_.compare(appStateData.bundleName) == 0) {
167 foregroundBundleName_ = "" ;
168 }
169 }
170
GetForegroundApp()171 std::string ApplicationStateObserver::GetForegroundApp()
172 {
173 return foregroundBundleName_;
174 }
175 } // namespace OHOS::Rosen