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