1e0dac50fSopenharmony_ci/*
2e0dac50fSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License.
5e0dac50fSopenharmony_ci * You may obtain a copy of the License at
6e0dac50fSopenharmony_ci *
7e0dac50fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e0dac50fSopenharmony_ci *
9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and
13e0dac50fSopenharmony_ci * limitations under the License.
14e0dac50fSopenharmony_ci */
15e0dac50fSopenharmony_ci
16e0dac50fSopenharmony_ci#include "screen_rotation_controller.h"
17e0dac50fSopenharmony_ci
18e0dac50fSopenharmony_ci#include <chrono>
19e0dac50fSopenharmony_ci#include <securec.h>
20e0dac50fSopenharmony_ci
21e0dac50fSopenharmony_ci#include "display_manager_service_inner.h"
22e0dac50fSopenharmony_ci
23e0dac50fSopenharmony_cinamespace OHOS {
24e0dac50fSopenharmony_cinamespace Rosen {
25e0dac50fSopenharmony_cinamespace {
26e0dac50fSopenharmony_ciconstexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "ScreenRotationController"};
27e0dac50fSopenharmony_ci}
28e0dac50fSopenharmony_ci
29e0dac50fSopenharmony_ciDisplayId ScreenRotationController::defaultDisplayId_ = 0;
30e0dac50fSopenharmony_ciRotation ScreenRotationController::currentDisplayRotation_;
31e0dac50fSopenharmony_cibool ScreenRotationController::isScreenRotationLocked_ = true;
32e0dac50fSopenharmony_ciuint32_t ScreenRotationController::defaultDeviceRotationOffset_ = 0;
33e0dac50fSopenharmony_ciOrientation ScreenRotationController::lastOrientationType_ = Orientation::UNSPECIFIED;
34e0dac50fSopenharmony_ciRotation ScreenRotationController::lastSensorDecidedRotation_;
35e0dac50fSopenharmony_ciRotation ScreenRotationController::rotationLockedRotation_;
36e0dac50fSopenharmony_ciuint32_t ScreenRotationController::defaultDeviceRotation_ = 0;
37e0dac50fSopenharmony_cistd::map<SensorRotation, DeviceRotation> ScreenRotationController::sensorToDeviceRotationMap_;
38e0dac50fSopenharmony_cistd::map<DeviceRotation, Rotation> ScreenRotationController::deviceToDisplayRotationMap_;
39e0dac50fSopenharmony_cistd::map<Rotation, DisplayOrientation> ScreenRotationController::displayToDisplayOrientationMap_;
40e0dac50fSopenharmony_ciDeviceRotation ScreenRotationController::lastSensorRotationConverted_ = DeviceRotation::INVALID;
41e0dac50fSopenharmony_ci
42e0dac50fSopenharmony_civoid ScreenRotationController::Init()
43e0dac50fSopenharmony_ci{
44e0dac50fSopenharmony_ci    ProcessRotationMapping();
45e0dac50fSopenharmony_ci    currentDisplayRotation_ = GetCurrentDisplayRotation();
46e0dac50fSopenharmony_ci    defaultDisplayId_ = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId();
47e0dac50fSopenharmony_ci    if (defaultDisplayId_  == DISPLAY_ID_INVALID) {
48e0dac50fSopenharmony_ci        WLOGFE("defaultDisplayId_ is invalid");
49e0dac50fSopenharmony_ci    }
50e0dac50fSopenharmony_ci    lastSensorDecidedRotation_ = currentDisplayRotation_;
51e0dac50fSopenharmony_ci    rotationLockedRotation_ = currentDisplayRotation_;
52e0dac50fSopenharmony_ci}
53e0dac50fSopenharmony_ci
54e0dac50fSopenharmony_cibool ScreenRotationController::IsScreenRotationLocked()
55e0dac50fSopenharmony_ci{
56e0dac50fSopenharmony_ci    return isScreenRotationLocked_;
57e0dac50fSopenharmony_ci}
58e0dac50fSopenharmony_ci
59e0dac50fSopenharmony_ciDMError ScreenRotationController::SetScreenRotationLocked(bool isLocked)
60e0dac50fSopenharmony_ci{
61e0dac50fSopenharmony_ci    isScreenRotationLocked_ = isLocked;
62e0dac50fSopenharmony_ci    if (isLocked) {
63e0dac50fSopenharmony_ci        rotationLockedRotation_ = GetCurrentDisplayRotation();
64e0dac50fSopenharmony_ci        return DMError::DM_OK;
65e0dac50fSopenharmony_ci    }
66e0dac50fSopenharmony_ci    if (GetCurrentDisplayRotation() == ConvertDeviceToDisplayRotation(lastSensorRotationConverted_)) {
67e0dac50fSopenharmony_ci        return DMError::DM_OK;
68e0dac50fSopenharmony_ci    }
69e0dac50fSopenharmony_ci    Orientation currentOrientation = GetPreferredOrientation();
70e0dac50fSopenharmony_ci    if (IsSensorRelatedOrientation(currentOrientation)) {
71e0dac50fSopenharmony_ci        ProcessSwitchToSensorRelatedOrientation(currentOrientation, lastSensorRotationConverted_);
72e0dac50fSopenharmony_ci    }
73e0dac50fSopenharmony_ci    return DMError::DM_OK;
74e0dac50fSopenharmony_ci}
75e0dac50fSopenharmony_ci
76e0dac50fSopenharmony_civoid ScreenRotationController::SetDefaultDeviceRotationOffset(uint32_t defaultDeviceRotationOffset)
77e0dac50fSopenharmony_ci{
78e0dac50fSopenharmony_ci    // Available options for defaultDeviceRotationOffset: {0, 90, 180, 270}
79e0dac50fSopenharmony_ci    if (defaultDeviceRotationOffset < 0 || defaultDeviceRotationOffset > 270 || defaultDeviceRotationOffset % 90 != 0) {
80e0dac50fSopenharmony_ci        return;
81e0dac50fSopenharmony_ci    }
82e0dac50fSopenharmony_ci    defaultDeviceRotationOffset_ = defaultDeviceRotationOffset;
83e0dac50fSopenharmony_ci}
84e0dac50fSopenharmony_ci
85e0dac50fSopenharmony_civoid ScreenRotationController::HandleSensorEventInput(DeviceRotation deviceRotation)
86e0dac50fSopenharmony_ci{
87e0dac50fSopenharmony_ci    if (deviceRotation == DeviceRotation::INVALID) {
88e0dac50fSopenharmony_ci        WLOGFW("deviceRotation is invalid, return.");
89e0dac50fSopenharmony_ci        return;
90e0dac50fSopenharmony_ci    }
91e0dac50fSopenharmony_ci    Orientation orientation = GetPreferredOrientation();
92e0dac50fSopenharmony_ci    currentDisplayRotation_ = GetCurrentDisplayRotation();
93e0dac50fSopenharmony_ci    lastSensorRotationConverted_ = deviceRotation;
94e0dac50fSopenharmony_ci    if (!IsSensorRelatedOrientation(orientation)) {
95e0dac50fSopenharmony_ci        WLOGFD("If the current preferred orientation is locked or sensor-independent, return.");
96e0dac50fSopenharmony_ci        return;
97e0dac50fSopenharmony_ci    }
98e0dac50fSopenharmony_ci
99e0dac50fSopenharmony_ci    if (currentDisplayRotation_ == ConvertDeviceToDisplayRotation(deviceRotation)) {
100e0dac50fSopenharmony_ci        WLOGFD("If the current display rotation is same to sensor rotation, return.");
101e0dac50fSopenharmony_ci        return;
102e0dac50fSopenharmony_ci    }
103e0dac50fSopenharmony_ci    Rotation targetDisplayRotation = CalcTargetDisplayRotation(orientation, deviceRotation);
104e0dac50fSopenharmony_ci    SetScreenRotation(targetDisplayRotation);
105e0dac50fSopenharmony_ci}
106e0dac50fSopenharmony_ci
107e0dac50fSopenharmony_ciRotation ScreenRotationController::GetCurrentDisplayRotation()
108e0dac50fSopenharmony_ci{
109e0dac50fSopenharmony_ci    sptr<DisplayInfo> defaultDisplayInfo = DisplayManagerServiceInner::GetInstance().GetDefaultDisplay();
110e0dac50fSopenharmony_ci    if (defaultDisplayInfo == nullptr) {
111e0dac50fSopenharmony_ci        WLOGFE("Cannot get default display info");
112e0dac50fSopenharmony_ci        return defaultDeviceRotation_ == 0 ? ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_PORTRAIT) :
113e0dac50fSopenharmony_ci            ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_LANDSCAPE);
114e0dac50fSopenharmony_ci    }
115e0dac50fSopenharmony_ci    return defaultDisplayInfo->GetRotation();
116e0dac50fSopenharmony_ci}
117e0dac50fSopenharmony_ci
118e0dac50fSopenharmony_ciOrientation ScreenRotationController::GetPreferredOrientation()
119e0dac50fSopenharmony_ci{
120e0dac50fSopenharmony_ci    sptr<ScreenInfo> screenInfo = DisplayManagerServiceInner::GetInstance().GetScreenInfoByDisplayId(defaultDisplayId_);
121e0dac50fSopenharmony_ci    if (screenInfo == nullptr) {
122e0dac50fSopenharmony_ci        WLOGFE("Cannot get default screen info");
123e0dac50fSopenharmony_ci        return Orientation::UNSPECIFIED;
124e0dac50fSopenharmony_ci    }
125e0dac50fSopenharmony_ci    return screenInfo->GetOrientation();
126e0dac50fSopenharmony_ci}
127e0dac50fSopenharmony_ci
128e0dac50fSopenharmony_ciRotation ScreenRotationController::CalcTargetDisplayRotation(
129e0dac50fSopenharmony_ci    Orientation requestedOrientation, DeviceRotation sensorRotationConverted)
130e0dac50fSopenharmony_ci{
131e0dac50fSopenharmony_ci    switch (requestedOrientation) {
132e0dac50fSopenharmony_ci        case Orientation::SENSOR: {
133e0dac50fSopenharmony_ci            lastSensorDecidedRotation_ = ConvertDeviceToDisplayRotation(sensorRotationConverted);
134e0dac50fSopenharmony_ci            return lastSensorDecidedRotation_;
135e0dac50fSopenharmony_ci        }
136e0dac50fSopenharmony_ci        case Orientation::SENSOR_VERTICAL: {
137e0dac50fSopenharmony_ci            return ProcessAutoRotationPortraitOrientation(sensorRotationConverted);
138e0dac50fSopenharmony_ci        }
139e0dac50fSopenharmony_ci        case Orientation::SENSOR_HORIZONTAL: {
140e0dac50fSopenharmony_ci            return ProcessAutoRotationLandscapeOrientation(sensorRotationConverted);
141e0dac50fSopenharmony_ci        }
142e0dac50fSopenharmony_ci        case Orientation::AUTO_ROTATION_RESTRICTED: {
143e0dac50fSopenharmony_ci            if (isScreenRotationLocked_) {
144e0dac50fSopenharmony_ci                return currentDisplayRotation_;
145e0dac50fSopenharmony_ci            }
146e0dac50fSopenharmony_ci            lastSensorDecidedRotation_ = ConvertDeviceToDisplayRotation(sensorRotationConverted);
147e0dac50fSopenharmony_ci            return lastSensorDecidedRotation_;
148e0dac50fSopenharmony_ci        }
149e0dac50fSopenharmony_ci        case Orientation::AUTO_ROTATION_PORTRAIT_RESTRICTED: {
150e0dac50fSopenharmony_ci            if (isScreenRotationLocked_) {
151e0dac50fSopenharmony_ci                return currentDisplayRotation_;
152e0dac50fSopenharmony_ci            }
153e0dac50fSopenharmony_ci            return ProcessAutoRotationPortraitOrientation(sensorRotationConverted);
154e0dac50fSopenharmony_ci        }
155e0dac50fSopenharmony_ci        case Orientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED: {
156e0dac50fSopenharmony_ci            if (isScreenRotationLocked_) {
157e0dac50fSopenharmony_ci                return currentDisplayRotation_;
158e0dac50fSopenharmony_ci            }
159e0dac50fSopenharmony_ci            return ProcessAutoRotationLandscapeOrientation(sensorRotationConverted);
160e0dac50fSopenharmony_ci        }
161e0dac50fSopenharmony_ci        default: {
162e0dac50fSopenharmony_ci            return currentDisplayRotation_;
163e0dac50fSopenharmony_ci        }
164e0dac50fSopenharmony_ci    }
165e0dac50fSopenharmony_ci}
166e0dac50fSopenharmony_ci
167e0dac50fSopenharmony_ciRotation ScreenRotationController::ProcessAutoRotationPortraitOrientation(DeviceRotation sensorRotationConverted)
168e0dac50fSopenharmony_ci{
169e0dac50fSopenharmony_ci    if (IsDeviceRotationHorizontal(sensorRotationConverted)) {
170e0dac50fSopenharmony_ci        return currentDisplayRotation_;
171e0dac50fSopenharmony_ci    }
172e0dac50fSopenharmony_ci    lastSensorDecidedRotation_ = ConvertDeviceToDisplayRotation(sensorRotationConverted);
173e0dac50fSopenharmony_ci    return lastSensorDecidedRotation_;
174e0dac50fSopenharmony_ci}
175e0dac50fSopenharmony_ci
176e0dac50fSopenharmony_ciRotation ScreenRotationController::ProcessAutoRotationLandscapeOrientation(DeviceRotation sensorRotationConverted)
177e0dac50fSopenharmony_ci{
178e0dac50fSopenharmony_ci    if (IsDeviceRotationVertical(sensorRotationConverted)) {
179e0dac50fSopenharmony_ci        return currentDisplayRotation_;
180e0dac50fSopenharmony_ci    }
181e0dac50fSopenharmony_ci    lastSensorDecidedRotation_ = ConvertDeviceToDisplayRotation(sensorRotationConverted);
182e0dac50fSopenharmony_ci    return lastSensorDecidedRotation_;
183e0dac50fSopenharmony_ci}
184e0dac50fSopenharmony_ci
185e0dac50fSopenharmony_civoid ScreenRotationController::SetScreenRotation(Rotation targetRotation, bool withAnimation)
186e0dac50fSopenharmony_ci{
187e0dac50fSopenharmony_ci    if (targetRotation == GetCurrentDisplayRotation()) {
188e0dac50fSopenharmony_ci        return;
189e0dac50fSopenharmony_ci    }
190e0dac50fSopenharmony_ci    DisplayManagerServiceInner::GetInstance().GetDefaultDisplay()->SetRotation(targetRotation);
191e0dac50fSopenharmony_ci    DisplayManagerServiceInner::GetInstance().SetRotationFromWindow(defaultDisplayId_, targetRotation, withAnimation);
192e0dac50fSopenharmony_ci    WLOGFI("dms: Set screen rotation: %{public}u withAnimation: %{public}u", targetRotation, withAnimation);
193e0dac50fSopenharmony_ci}
194e0dac50fSopenharmony_ci
195e0dac50fSopenharmony_ciDeviceRotation ScreenRotationController::CalcDeviceRotation(SensorRotation sensorRotation)
196e0dac50fSopenharmony_ci{
197e0dac50fSopenharmony_ci    if (sensorRotation == SensorRotation::INVALID) {
198e0dac50fSopenharmony_ci        return DeviceRotation::INVALID;
199e0dac50fSopenharmony_ci    }
200e0dac50fSopenharmony_ci    // offset(in degree) divided by 90 to get rotation bias
201e0dac50fSopenharmony_ci    int32_t bias = static_cast<int32_t>(defaultDeviceRotationOffset_ / 90);
202e0dac50fSopenharmony_ci    int32_t deviceRotationValue = static_cast<int32_t>(sensorRotation) - bias;
203e0dac50fSopenharmony_ci    while (deviceRotationValue < 0) {
204e0dac50fSopenharmony_ci        // +4 is used to normalize the values into the range 0~3, corresponding to the four rotations.
205e0dac50fSopenharmony_ci        deviceRotationValue += 4;
206e0dac50fSopenharmony_ci    }
207e0dac50fSopenharmony_ci    if (defaultDeviceRotation_ == 1) {
208e0dac50fSopenharmony_ci        deviceRotationValue += static_cast<int32_t>(defaultDeviceRotation_);
209e0dac50fSopenharmony_ci        // %2 to determine whether the rotation is horizontal or vertical.
210e0dac50fSopenharmony_ci        if (deviceRotationValue % 2 == 0) {
211e0dac50fSopenharmony_ci            // if device's default rotation is landscape, use -2 to swap 0 and 90, 180 and 270.
212e0dac50fSopenharmony_ci            deviceRotationValue -= 2;
213e0dac50fSopenharmony_ci        }
214e0dac50fSopenharmony_ci    }
215e0dac50fSopenharmony_ci    return static_cast<DeviceRotation>(deviceRotationValue);
216e0dac50fSopenharmony_ci}
217e0dac50fSopenharmony_ci
218e0dac50fSopenharmony_cibool ScreenRotationController::IsSensorRelatedOrientation(Orientation orientation)
219e0dac50fSopenharmony_ci{
220e0dac50fSopenharmony_ci    if ((orientation >= Orientation::UNSPECIFIED && orientation <= Orientation::REVERSE_HORIZONTAL) ||
221e0dac50fSopenharmony_ci        orientation == Orientation::LOCKED) {
222e0dac50fSopenharmony_ci        return false;
223e0dac50fSopenharmony_ci    }
224e0dac50fSopenharmony_ci    return true;
225e0dac50fSopenharmony_ci}
226e0dac50fSopenharmony_ci
227e0dac50fSopenharmony_civoid ScreenRotationController::ProcessSwitchToSensorRelatedOrientation(
228e0dac50fSopenharmony_ci    Orientation orientation, DeviceRotation sensorRotationConverted)
229e0dac50fSopenharmony_ci{
230e0dac50fSopenharmony_ci    lastOrientationType_ = orientation;
231e0dac50fSopenharmony_ci    switch (orientation) {
232e0dac50fSopenharmony_ci        case Orientation::AUTO_ROTATION_RESTRICTED: {
233e0dac50fSopenharmony_ci            if (isScreenRotationLocked_) {
234e0dac50fSopenharmony_ci                SetScreenRotation(rotationLockedRotation_);
235e0dac50fSopenharmony_ci                return;
236e0dac50fSopenharmony_ci            }
237e0dac50fSopenharmony_ci            [[fallthrough]];
238e0dac50fSopenharmony_ci        }
239e0dac50fSopenharmony_ci        case Orientation::SENSOR: {
240e0dac50fSopenharmony_ci            ProcessSwitchToAutoRotation(sensorRotationConverted);
241e0dac50fSopenharmony_ci            return;
242e0dac50fSopenharmony_ci        }
243e0dac50fSopenharmony_ci        case Orientation::AUTO_ROTATION_PORTRAIT_RESTRICTED: {
244e0dac50fSopenharmony_ci            if (isScreenRotationLocked_) {
245e0dac50fSopenharmony_ci                ProcessSwitchToAutoRotationPortraitRestricted();
246e0dac50fSopenharmony_ci                return;
247e0dac50fSopenharmony_ci            }
248e0dac50fSopenharmony_ci            [[fallthrough]];
249e0dac50fSopenharmony_ci        }
250e0dac50fSopenharmony_ci        case Orientation::SENSOR_VERTICAL: {
251e0dac50fSopenharmony_ci            ProcessSwitchToAutoRotationPortrait(sensorRotationConverted);
252e0dac50fSopenharmony_ci            return;
253e0dac50fSopenharmony_ci        }
254e0dac50fSopenharmony_ci        case Orientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED: {
255e0dac50fSopenharmony_ci            if (isScreenRotationLocked_) {
256e0dac50fSopenharmony_ci                ProcessSwitchToAutoRotationLandscapeRestricted();
257e0dac50fSopenharmony_ci                return;
258e0dac50fSopenharmony_ci            }
259e0dac50fSopenharmony_ci            [[fallthrough]];
260e0dac50fSopenharmony_ci        }
261e0dac50fSopenharmony_ci        case Orientation::SENSOR_HORIZONTAL: {
262e0dac50fSopenharmony_ci            ProcessSwitchToAutoRotationLandscape(sensorRotationConverted);
263e0dac50fSopenharmony_ci            return;
264e0dac50fSopenharmony_ci        }
265e0dac50fSopenharmony_ci        default: {
266e0dac50fSopenharmony_ci            return;
267e0dac50fSopenharmony_ci        }
268e0dac50fSopenharmony_ci    }
269e0dac50fSopenharmony_ci}
270e0dac50fSopenharmony_ci
271e0dac50fSopenharmony_civoid ScreenRotationController::ProcessSwitchToAutoRotation(DeviceRotation rotation)
272e0dac50fSopenharmony_ci{
273e0dac50fSopenharmony_ci    if (rotation != DeviceRotation::INVALID) {
274e0dac50fSopenharmony_ci        SetScreenRotation(ConvertDeviceToDisplayRotation(rotation));
275e0dac50fSopenharmony_ci    }
276e0dac50fSopenharmony_ci}
277e0dac50fSopenharmony_ci
278e0dac50fSopenharmony_civoid ScreenRotationController::ProcessSwitchToAutoRotationPortrait(DeviceRotation rotation)
279e0dac50fSopenharmony_ci{
280e0dac50fSopenharmony_ci    if (IsDeviceRotationVertical(rotation)) {
281e0dac50fSopenharmony_ci        SetScreenRotation(ConvertDeviceToDisplayRotation(rotation));
282e0dac50fSopenharmony_ci        return;
283e0dac50fSopenharmony_ci    }
284e0dac50fSopenharmony_ci    SetScreenRotation(ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_PORTRAIT));
285e0dac50fSopenharmony_ci}
286e0dac50fSopenharmony_ci
287e0dac50fSopenharmony_civoid ScreenRotationController::ProcessSwitchToAutoRotationLandscape(DeviceRotation rotation)
288e0dac50fSopenharmony_ci{
289e0dac50fSopenharmony_ci    if (IsDeviceRotationHorizontal(rotation)) {
290e0dac50fSopenharmony_ci        SetScreenRotation(ConvertDeviceToDisplayRotation(rotation));
291e0dac50fSopenharmony_ci        return;
292e0dac50fSopenharmony_ci    }
293e0dac50fSopenharmony_ci    SetScreenRotation(ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_LANDSCAPE));
294e0dac50fSopenharmony_ci}
295e0dac50fSopenharmony_ci
296e0dac50fSopenharmony_civoid ScreenRotationController::ProcessSwitchToAutoRotationPortraitRestricted()
297e0dac50fSopenharmony_ci{
298e0dac50fSopenharmony_ci    if (IsCurrentDisplayVertical()) {
299e0dac50fSopenharmony_ci        return;
300e0dac50fSopenharmony_ci    }
301e0dac50fSopenharmony_ci    if (IsDisplayRotationVertical(rotationLockedRotation_)) {
302e0dac50fSopenharmony_ci        SetScreenRotation(rotationLockedRotation_);
303e0dac50fSopenharmony_ci        return;
304e0dac50fSopenharmony_ci    }
305e0dac50fSopenharmony_ci    SetScreenRotation(ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_PORTRAIT));
306e0dac50fSopenharmony_ci}
307e0dac50fSopenharmony_ci
308e0dac50fSopenharmony_civoid ScreenRotationController::ProcessSwitchToAutoRotationLandscapeRestricted()
309e0dac50fSopenharmony_ci{
310e0dac50fSopenharmony_ci    if (IsCurrentDisplayHorizontal()) {
311e0dac50fSopenharmony_ci        return;
312e0dac50fSopenharmony_ci    }
313e0dac50fSopenharmony_ci    if (IsDisplayRotationHorizontal(rotationLockedRotation_)) {
314e0dac50fSopenharmony_ci        SetScreenRotation(rotationLockedRotation_);
315e0dac50fSopenharmony_ci        return;
316e0dac50fSopenharmony_ci    }
317e0dac50fSopenharmony_ci    SetScreenRotation(ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_LANDSCAPE));
318e0dac50fSopenharmony_ci}
319e0dac50fSopenharmony_ci
320e0dac50fSopenharmony_ciDeviceRotation ScreenRotationController::ConvertSensorToDeviceRotation(SensorRotation sensorRotation)
321e0dac50fSopenharmony_ci{
322e0dac50fSopenharmony_ci    if (sensorToDeviceRotationMap_.empty()) {
323e0dac50fSopenharmony_ci        ProcessRotationMapping();
324e0dac50fSopenharmony_ci    }
325e0dac50fSopenharmony_ci    return sensorToDeviceRotationMap_.at(sensorRotation);
326e0dac50fSopenharmony_ci}
327e0dac50fSopenharmony_ci
328e0dac50fSopenharmony_ciDisplayOrientation ScreenRotationController::ConvertRotationToDisplayOrientation(Rotation rotation)
329e0dac50fSopenharmony_ci{
330e0dac50fSopenharmony_ci    if (displayToDisplayOrientationMap_.empty()) {
331e0dac50fSopenharmony_ci        ProcessRotationMapping();
332e0dac50fSopenharmony_ci    }
333e0dac50fSopenharmony_ci    return displayToDisplayOrientationMap_.at(rotation);
334e0dac50fSopenharmony_ci}
335e0dac50fSopenharmony_ci
336e0dac50fSopenharmony_ciRotation ScreenRotationController::ConvertDeviceToDisplayRotation(DeviceRotation deviceRotation)
337e0dac50fSopenharmony_ci{
338e0dac50fSopenharmony_ci    if (deviceRotation == DeviceRotation::INVALID) {
339e0dac50fSopenharmony_ci        return GetCurrentDisplayRotation();
340e0dac50fSopenharmony_ci    }
341e0dac50fSopenharmony_ci    if (deviceToDisplayRotationMap_.empty()) {
342e0dac50fSopenharmony_ci        ProcessRotationMapping();
343e0dac50fSopenharmony_ci    }
344e0dac50fSopenharmony_ci    return deviceToDisplayRotationMap_.at(deviceRotation);
345e0dac50fSopenharmony_ci}
346e0dac50fSopenharmony_ci
347e0dac50fSopenharmony_civoid ScreenRotationController::ProcessRotationMapping()
348e0dac50fSopenharmony_ci{
349e0dac50fSopenharmony_ci    sptr<SupportedScreenModes> modes =
350e0dac50fSopenharmony_ci        DisplayManagerServiceInner::GetInstance().GetScreenModesByDisplayId(defaultDisplayId_);
351e0dac50fSopenharmony_ci
352e0dac50fSopenharmony_ci    // 0 means PORTRAIT, 1 means LANDSCAPE.
353e0dac50fSopenharmony_ci    defaultDeviceRotation_ = (modes == nullptr || modes->width_ < modes->height_) ? 0 : 1;
354e0dac50fSopenharmony_ci
355e0dac50fSopenharmony_ci    if (deviceToDisplayRotationMap_.empty()) {
356e0dac50fSopenharmony_ci        deviceToDisplayRotationMap_ = {
357e0dac50fSopenharmony_ci            {DeviceRotation::ROTATION_PORTRAIT,
358e0dac50fSopenharmony_ci                defaultDeviceRotation_ == 0 ? Rotation::ROTATION_0 : Rotation::ROTATION_90},
359e0dac50fSopenharmony_ci            {DeviceRotation::ROTATION_LANDSCAPE,
360e0dac50fSopenharmony_ci                defaultDeviceRotation_ == 1 ? Rotation::ROTATION_0 : Rotation::ROTATION_90},
361e0dac50fSopenharmony_ci            {DeviceRotation::ROTATION_PORTRAIT_INVERTED,
362e0dac50fSopenharmony_ci                defaultDeviceRotation_ == 0 ? Rotation::ROTATION_180 : Rotation::ROTATION_270},
363e0dac50fSopenharmony_ci            {DeviceRotation::ROTATION_LANDSCAPE_INVERTED,
364e0dac50fSopenharmony_ci                defaultDeviceRotation_ == 1 ? Rotation::ROTATION_180 : Rotation::ROTATION_270},
365e0dac50fSopenharmony_ci        };
366e0dac50fSopenharmony_ci    }
367e0dac50fSopenharmony_ci    if (displayToDisplayOrientationMap_.empty()) {
368e0dac50fSopenharmony_ci        displayToDisplayOrientationMap_ = {
369e0dac50fSopenharmony_ci            {defaultDeviceRotation_ == 0 ? Rotation::ROTATION_0 : Rotation::ROTATION_90,
370e0dac50fSopenharmony_ci                DisplayOrientation::PORTRAIT},
371e0dac50fSopenharmony_ci            {defaultDeviceRotation_ == 1 ? Rotation::ROTATION_0 : Rotation::ROTATION_90,
372e0dac50fSopenharmony_ci                DisplayOrientation::LANDSCAPE},
373e0dac50fSopenharmony_ci            {defaultDeviceRotation_ == 0 ? Rotation::ROTATION_180 : Rotation::ROTATION_270,
374e0dac50fSopenharmony_ci                DisplayOrientation::PORTRAIT_INVERTED},
375e0dac50fSopenharmony_ci            {defaultDeviceRotation_ == 1 ? Rotation::ROTATION_180 : Rotation::ROTATION_270,
376e0dac50fSopenharmony_ci                DisplayOrientation::LANDSCAPE_INVERTED},
377e0dac50fSopenharmony_ci        };
378e0dac50fSopenharmony_ci    }
379e0dac50fSopenharmony_ci    if (sensorToDeviceRotationMap_.empty()) {
380e0dac50fSopenharmony_ci        sensorToDeviceRotationMap_ = {
381e0dac50fSopenharmony_ci            {SensorRotation::ROTATION_0, CalcDeviceRotation(SensorRotation::ROTATION_0)},
382e0dac50fSopenharmony_ci            {SensorRotation::ROTATION_90, CalcDeviceRotation(SensorRotation::ROTATION_90)},
383e0dac50fSopenharmony_ci            {SensorRotation::ROTATION_180, CalcDeviceRotation(SensorRotation::ROTATION_180)},
384e0dac50fSopenharmony_ci            {SensorRotation::ROTATION_270, CalcDeviceRotation(SensorRotation::ROTATION_270)},
385e0dac50fSopenharmony_ci            {SensorRotation::INVALID, DeviceRotation::INVALID},
386e0dac50fSopenharmony_ci        };
387e0dac50fSopenharmony_ci    }
388e0dac50fSopenharmony_ci}
389e0dac50fSopenharmony_ci
390e0dac50fSopenharmony_cibool ScreenRotationController::IsDeviceRotationVertical(DeviceRotation deviceRotation)
391e0dac50fSopenharmony_ci{
392e0dac50fSopenharmony_ci    return (deviceRotation == DeviceRotation::ROTATION_PORTRAIT) ||
393e0dac50fSopenharmony_ci        (deviceRotation == DeviceRotation::ROTATION_PORTRAIT_INVERTED);
394e0dac50fSopenharmony_ci}
395e0dac50fSopenharmony_ci
396e0dac50fSopenharmony_cibool ScreenRotationController::IsDeviceRotationHorizontal(DeviceRotation deviceRotation)
397e0dac50fSopenharmony_ci{
398e0dac50fSopenharmony_ci    return (deviceRotation == DeviceRotation::ROTATION_LANDSCAPE) ||
399e0dac50fSopenharmony_ci        (deviceRotation == DeviceRotation::ROTATION_LANDSCAPE_INVERTED);
400e0dac50fSopenharmony_ci}
401e0dac50fSopenharmony_ci
402e0dac50fSopenharmony_cibool ScreenRotationController::IsCurrentDisplayVertical()
403e0dac50fSopenharmony_ci{
404e0dac50fSopenharmony_ci    return IsDisplayRotationVertical(GetCurrentDisplayRotation());
405e0dac50fSopenharmony_ci}
406e0dac50fSopenharmony_ci
407e0dac50fSopenharmony_cibool ScreenRotationController::IsCurrentDisplayHorizontal()
408e0dac50fSopenharmony_ci{
409e0dac50fSopenharmony_ci    return IsDisplayRotationHorizontal(GetCurrentDisplayRotation());
410e0dac50fSopenharmony_ci}
411e0dac50fSopenharmony_ci
412e0dac50fSopenharmony_cibool ScreenRotationController::IsDefaultDisplayRotationPortrait()
413e0dac50fSopenharmony_ci{
414e0dac50fSopenharmony_ci    return Rotation::ROTATION_0 == ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_PORTRAIT);
415e0dac50fSopenharmony_ci}
416e0dac50fSopenharmony_ci
417e0dac50fSopenharmony_cibool ScreenRotationController::IsDisplayRotationVertical(Rotation rotation)
418e0dac50fSopenharmony_ci{
419e0dac50fSopenharmony_ci    return (rotation == ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_PORTRAIT)) ||
420e0dac50fSopenharmony_ci        (rotation == ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_PORTRAIT_INVERTED));
421e0dac50fSopenharmony_ci}
422e0dac50fSopenharmony_ci
423e0dac50fSopenharmony_cibool ScreenRotationController::IsDisplayRotationHorizontal(Rotation rotation)
424e0dac50fSopenharmony_ci{
425e0dac50fSopenharmony_ci    return (rotation == ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_LANDSCAPE)) ||
426e0dac50fSopenharmony_ci        (rotation == ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_LANDSCAPE_INVERTED));
427e0dac50fSopenharmony_ci}
428e0dac50fSopenharmony_ci
429e0dac50fSopenharmony_civoid ScreenRotationController::ProcessSwitchToSensorUnrelatedOrientation(Orientation orientation, bool withAnimation)
430e0dac50fSopenharmony_ci{
431e0dac50fSopenharmony_ci    if (lastOrientationType_ == orientation) {
432e0dac50fSopenharmony_ci        return;
433e0dac50fSopenharmony_ci    }
434e0dac50fSopenharmony_ci    lastOrientationType_ = orientation;
435e0dac50fSopenharmony_ci    switch (orientation) {
436e0dac50fSopenharmony_ci        case Orientation::UNSPECIFIED: {
437e0dac50fSopenharmony_ci            SetScreenRotation(Rotation::ROTATION_0, withAnimation);
438e0dac50fSopenharmony_ci            break;
439e0dac50fSopenharmony_ci        }
440e0dac50fSopenharmony_ci        case Orientation::VERTICAL: {
441e0dac50fSopenharmony_ci            SetScreenRotation(ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_PORTRAIT), withAnimation);
442e0dac50fSopenharmony_ci            break;
443e0dac50fSopenharmony_ci        }
444e0dac50fSopenharmony_ci        case Orientation::REVERSE_VERTICAL: {
445e0dac50fSopenharmony_ci            SetScreenRotation(ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_PORTRAIT_INVERTED),
446e0dac50fSopenharmony_ci                withAnimation);
447e0dac50fSopenharmony_ci            break;
448e0dac50fSopenharmony_ci        }
449e0dac50fSopenharmony_ci        case Orientation::HORIZONTAL: {
450e0dac50fSopenharmony_ci            SetScreenRotation(ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_LANDSCAPE), withAnimation);
451e0dac50fSopenharmony_ci            break;
452e0dac50fSopenharmony_ci        }
453e0dac50fSopenharmony_ci        case Orientation::REVERSE_HORIZONTAL: {
454e0dac50fSopenharmony_ci            SetScreenRotation(ConvertDeviceToDisplayRotation(DeviceRotation::ROTATION_LANDSCAPE_INVERTED),
455e0dac50fSopenharmony_ci                withAnimation);
456e0dac50fSopenharmony_ci            break;
457e0dac50fSopenharmony_ci        }
458e0dac50fSopenharmony_ci        default: {
459e0dac50fSopenharmony_ci            return;
460e0dac50fSopenharmony_ci        }
461e0dac50fSopenharmony_ci    }
462e0dac50fSopenharmony_ci}
463e0dac50fSopenharmony_ci
464e0dac50fSopenharmony_civoid ScreenRotationController::ProcessOrientationSwitch(Orientation orientation, bool withAnimation)
465e0dac50fSopenharmony_ci{
466e0dac50fSopenharmony_ci    if (!IsSensorRelatedOrientation(orientation)) {
467e0dac50fSopenharmony_ci        ProcessSwitchToSensorUnrelatedOrientation(orientation, withAnimation);
468e0dac50fSopenharmony_ci    } else {
469e0dac50fSopenharmony_ci        ProcessSwitchToSensorRelatedOrientation(orientation, lastSensorRotationConverted_);
470e0dac50fSopenharmony_ci    }
471e0dac50fSopenharmony_ci}
472e0dac50fSopenharmony_ci} // Rosen
473e0dac50fSopenharmony_ci} // OHOS