1 /*
2 * Copyright (C) 2022 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 "accessibility_display_manager.h"
17 #include "accessible_ability_manager_service.h"
18 #include "hilog_wrapper.h"
19 #include "utils.h"
20
21 namespace OHOS {
22 namespace Accessibility {
23 namespace {
24 constexpr int32_t DEFAULT_DPI = 540;
25 constexpr int32_t DEFAULT_WIDTH = 1260;
26 constexpr int32_t DEFAULT_HEIGHT = 2720;
27
28 static const std::map<std::pair<Rosen::DisplayOrientation, Rosen::DisplayOrientation>, RotationType> rotationMap = {
29 {{Rosen::DisplayOrientation::PORTRAIT, Rosen::DisplayOrientation::LANDSCAPE},
30 RotationType::RIGHT_ROTATE},
31 {{Rosen::DisplayOrientation::PORTRAIT, Rosen::DisplayOrientation::LANDSCAPE_INVERTED},
32 RotationType::LEFT_ROTATE},
33 {{Rosen::DisplayOrientation::PORTRAIT, Rosen::DisplayOrientation::PORTRAIT_INVERTED},
34 RotationType::FLIP_VERTICAL},
35
36 {{Rosen::DisplayOrientation::LANDSCAPE, Rosen::DisplayOrientation::PORTRAIT},
37 RotationType::LEFT_ROTATE},
38 {{Rosen::DisplayOrientation::LANDSCAPE, Rosen::DisplayOrientation::PORTRAIT_INVERTED},
39 RotationType::RIGHT_ROTATE},
40 {{Rosen::DisplayOrientation::LANDSCAPE, Rosen::DisplayOrientation::LANDSCAPE_INVERTED},
41 RotationType::FLIP_VERTICAL},
42
43 {{Rosen::DisplayOrientation::PORTRAIT_INVERTED, Rosen::DisplayOrientation::LANDSCAPE},
44 RotationType::LEFT_ROTATE},
45 {{Rosen::DisplayOrientation::PORTRAIT_INVERTED, Rosen::DisplayOrientation::PORTRAIT},
46 RotationType::FLIP_VERTICAL},
47 {{Rosen::DisplayOrientation::PORTRAIT_INVERTED, Rosen::DisplayOrientation::LANDSCAPE_INVERTED},
48 RotationType::RIGHT_ROTATE},
49
50 {{Rosen::DisplayOrientation::LANDSCAPE_INVERTED, Rosen::DisplayOrientation::PORTRAIT},
51 RotationType::RIGHT_ROTATE},
52 {{Rosen::DisplayOrientation::LANDSCAPE_INVERTED, Rosen::DisplayOrientation::LANDSCAPE},
53 RotationType::FLIP_VERTICAL},
54 {{Rosen::DisplayOrientation::LANDSCAPE_INVERTED, Rosen::DisplayOrientation::PORTRAIT_INVERTED},
55 RotationType::LEFT_ROTATE}
56 };
57 }
58
AccessibilityDisplayManager()59 AccessibilityDisplayManager::AccessibilityDisplayManager()
60 {
61 }
62
~AccessibilityDisplayManager()63 AccessibilityDisplayManager::~AccessibilityDisplayManager()
64 {
65 UnregisterDisplayListener();
66 }
67
GetDisplay(uint64_t id)68 const sptr<Rosen::Display> AccessibilityDisplayManager::GetDisplay(uint64_t id)
69 {
70 HILOG_DEBUG();
71 return Rosen::DisplayManager::GetInstance().GetDisplayById(id);
72 }
73
GetDisplays()74 std::vector<sptr<Rosen::Display>> AccessibilityDisplayManager::GetDisplays()
75 {
76 HILOG_DEBUG();
77 return Rosen::DisplayManager::GetInstance().GetAllDisplays();
78 }
79
GetDefaultDisplay()80 const sptr<Rosen::Display> AccessibilityDisplayManager::GetDefaultDisplay()
81 {
82 HILOG_DEBUG();
83 return Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
84 }
85
GetDefaultDisplayId()86 uint64_t AccessibilityDisplayManager::GetDefaultDisplayId()
87 {
88 HILOG_DEBUG();
89 return Rosen::DisplayManager::GetInstance().GetDefaultDisplayId();
90 }
91
GetWidth()92 int32_t AccessibilityDisplayManager::GetWidth()
93 {
94 HILOG_DEBUG();
95 sptr<Rosen::Display> displaySync = GetDefaultDisplaySync();
96 if (displaySync == nullptr) {
97 HILOG_ERROR("default displaySync is null");
98 return DEFAULT_WIDTH;
99 }
100
101 return displaySync->GetWidth();
102 }
103
GetHeight()104 int32_t AccessibilityDisplayManager::GetHeight()
105 {
106 HILOG_DEBUG();
107 sptr<Rosen::Display> displaySync = GetDefaultDisplaySync();
108 if (displaySync == nullptr) {
109 HILOG_ERROR("default displaySync is null");
110 return DEFAULT_HEIGHT;
111 }
112
113 return displaySync->GetHeight();
114 }
115
GetOrientation()116 OHOS::Rosen::DisplayOrientation AccessibilityDisplayManager::GetOrientation()
117 {
118 HILOG_DEBUG();
119 sptr<Rosen::Display> displaySync = GetDefaultDisplaySync();
120 if (displaySync == nullptr) {
121 HILOG_ERROR("default displaySync is null");
122 return OHOS::Rosen::DisplayOrientation::PORTRAIT;
123 }
124
125 auto displayInfo = displaySync->GetDisplayInfo();
126 if (displayInfo == nullptr) {
127 HILOG_ERROR("default displayInfo is null");
128 return OHOS::Rosen::DisplayOrientation::PORTRAIT;
129 }
130
131 return displayInfo->GetDisplayOrientation();
132 }
133
GetDefaultDisplaySync()134 sptr<Rosen::Display> AccessibilityDisplayManager::GetDefaultDisplaySync()
135 {
136 HILOG_DEBUG();
137 return Rosen::DisplayManager::GetInstance().GetDefaultDisplaySync();
138 }
139
GetDefaultDisplayDpi()140 int32_t AccessibilityDisplayManager::GetDefaultDisplayDpi()
141 {
142 HILOG_DEBUG();
143 if (GetDefaultDisplay() == nullptr) {
144 HILOG_ERROR("default display is null");
145 return DEFAULT_DPI;
146 }
147
148 return GetDefaultDisplay()->GetDpi();
149 }
150
IsFoldable()151 bool AccessibilityDisplayManager::IsFoldable()
152 {
153 HILOG_DEBUG();
154 return Rosen::DisplayManager::GetInstance().IsFoldable();
155 }
156
GetFoldDisplayMode()157 Rosen::FoldDisplayMode AccessibilityDisplayManager::GetFoldDisplayMode()
158 {
159 HILOG_DEBUG();
160 return Rosen::DisplayManager::GetInstance().GetFoldDisplayMode();
161 }
162
GetFoldStatus()163 Rosen::FoldStatus AccessibilityDisplayManager::GetFoldStatus()
164 {
165 HILOG_DEBUG();
166 return Rosen::DisplayManager::GetInstance().GetFoldStatus();
167 }
168
SetDisplayScale(const uint64_t screenId,float scaleX,float scaleY,float pivotX,float pivotY)169 void AccessibilityDisplayManager::SetDisplayScale(const uint64_t screenId,
170 float scaleX, float scaleY, float pivotX, float pivotY)
171 {
172 HILOG_DEBUG("scaleX = %{public}f, scaleY = %{public}f, pivotX = %{public}f, pivotY = %{public}f",
173 scaleX, scaleY, pivotX, pivotY);
174 Rosen::DisplayManager::GetInstance().SetDisplayScale(screenId, scaleX,
175 scaleY, pivotX, pivotY);
176 }
177
RegisterDisplayListener(const std::shared_ptr<MagnificationManager> & manager)178 void AccessibilityDisplayManager::RegisterDisplayListener(
179 const std::shared_ptr<MagnificationManager> &manager)
180 {
181 HILOG_DEBUG();
182 if (listener_) {
183 HILOG_DEBUG("Display listener is already registed!");
184 return;
185 }
186 listener_ = new(std::nothrow) DisplayListener(manager);
187 if (!listener_) {
188 HILOG_ERROR("Create display listener fail!");
189 return;
190 }
191 Rosen::DisplayManager::GetInstance().RegisterDisplayListener(listener_);
192 }
193
UnregisterDisplayListener()194 void AccessibilityDisplayManager::UnregisterDisplayListener()
195 {
196 HILOG_DEBUG();
197 if (listener_) {
198 Rosen::DisplayManager::GetInstance().UnregisterDisplayListener(listener_);
199 listener_ = nullptr;
200 }
201 }
202
GetRotationType(Rosen::DisplayOrientation prev,Rosen::DisplayOrientation curr)203 RotationType AccessibilityDisplayManager::GetRotationType(Rosen::DisplayOrientation prev,
204 Rosen::DisplayOrientation curr)
205 {
206 auto key = std::make_pair(prev, curr);
207 auto it = rotationMap.find(key);
208 if (it != rotationMap.end()) {
209 return it->second;
210 }
211 return RotationType::UNKNOWN;
212 }
213
OnChange(Rosen::DisplayId dId)214 void AccessibilityDisplayManager::DisplayListener::OnChange(Rosen::DisplayId dId)
215 {
216 HILOG_DEBUG();
217 if (manager_ == nullptr) {
218 manager_ = Singleton<AccessibleAbilityManagerService>::GetInstance().GetMagnificationMgr();
219 }
220 if (manager_ == nullptr) {
221 HILOG_ERROR("manager_ is nullptr.");
222 return;
223 }
224
225 #ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
226 AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
227 OHOS::Rosen::DisplayOrientation currentOrientation = displayMgr.GetOrientation();
228 OHOS::Rosen::FoldDisplayMode currentMode = displayMgr.GetFoldDisplayMode();
229 if (orientation_ == currentOrientation && displayMode_ == currentMode) {
230 return;
231 }
232 HILOG_INFO("need fresh.");
233 if (Utils::IsWideFold()) {
234 OnChangeForWideFold(currentOrientation, currentMode);
235 return;
236 }
237
238 if (Utils::IsBigFold()) {
239 OnChangeForBigFold(currentOrientation, currentMode);
240 return;
241 }
242 OnChangeDefault(currentOrientation);
243 #else
244 HILOG_INFO("not support");
245 #endif
246 }
247
OnChangeForWideFold(OHOS::Rosen::DisplayOrientation currentOrientation,OHOS::Rosen::FoldDisplayMode currentMode)248 void AccessibilityDisplayManager::DisplayListener::OnChangeForWideFold(
249 OHOS::Rosen::DisplayOrientation currentOrientation,
250 OHOS::Rosen::FoldDisplayMode currentMode)
251 {
252 HILOG_DEBUG("currentOrientation = %{public}d, currentMode = %{public}d",
253 currentOrientation, currentMode);
254 auto interceptor = AccessibilityInputInterceptor::GetInstance();
255 if (interceptor == nullptr) {
256 HILOG_ERROR("interceptor is null");
257 return;
258 }
259 if (currentMode == Rosen::FoldDisplayMode::MAIN) {
260 HILOG_INFO("FoldDisplayMode MAIN");
261 interceptor->ShieldZoomGesture(true);
262 displayMode_ = currentMode;
263 return;
264 }
265 if (currentMode == Rosen::FoldDisplayMode::FULL) {
266 HILOG_INFO("FoldDisplayMode FULL");
267 interceptor->ShieldZoomGesture(false);
268 displayMode_ = currentMode;
269 if (orientation_ != currentOrientation) {
270 HILOG_INFO("need refresh orientation.");
271 RotationType type = Singleton<AccessibilityDisplayManager>::GetInstance().GetRotationType(
272 orientation_, currentOrientation);
273 if (manager_ != nullptr) {
274 manager_->RefreshWindowParam(type);
275 }
276 orientation_ = currentOrientation;
277 }
278 }
279 }
280
OnChangeForBigFold(OHOS::Rosen::DisplayOrientation currentOrientation,OHOS::Rosen::FoldDisplayMode currentMode)281 void AccessibilityDisplayManager::DisplayListener::OnChangeForBigFold(
282 OHOS::Rosen::DisplayOrientation currentOrientation,
283 OHOS::Rosen::FoldDisplayMode currentMode)
284 {
285 HILOG_DEBUG("currentOrientation = %{public}d, currentMode = %{public}d",
286 currentOrientation, currentMode);
287 if (displayMode_ != currentMode) {
288 HILOG_INFO("need refresh");
289 if (manager_ != nullptr) {
290 manager_->RefreshWindowParam(RotationType::NO_CHANGE);
291 }
292 displayMode_ = currentMode;
293 }
294
295 if (orientation_ != currentOrientation) {
296 HILOG_INFO("need refresh orientation.");
297 RotationType type = Singleton<AccessibilityDisplayManager>::GetInstance().GetRotationType(
298 orientation_, currentOrientation);
299 if (manager_ != nullptr) {
300 manager_->RefreshWindowParam(type);
301 }
302 orientation_ = currentOrientation;
303 }
304 }
305
OnChangeDefault(OHOS::Rosen::DisplayOrientation currentOrientation)306 void AccessibilityDisplayManager::DisplayListener::OnChangeDefault(
307 OHOS::Rosen::DisplayOrientation currentOrientation)
308 {
309 HILOG_DEBUG("currentOrientation = %{public}d", currentOrientation);
310 if (orientation_ != currentOrientation) {
311 HILOG_INFO("need refresh orientation.");
312 RotationType type = Singleton<AccessibilityDisplayManager>::GetInstance().GetRotationType(
313 orientation_, currentOrientation);
314 if (manager_ != nullptr) {
315 manager_->RefreshWindowParam(type);
316 }
317 orientation_ = currentOrientation;
318 }
319 }
320 } // namespace Accessibility
321 } // namespace OHOS