Android是支持屏幕进行旋转的,通过旋转使得屏幕呈现出竖屏或者横屏的布局。目前网上文章对10.0以上的源码分析流程很少,现分析如下:
文章目录
- 设置的辅助功能打开或者关闭自动旋转功能
- 1.packages/apps/Settings/src/com/android/settings/accessibility/AccessibilitySettings.java
- 2.frameworks/base/core/java/com/android/internal/view/RotationPolicy.java
- 3.frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
- 4.frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java
- 5. frameworks/base/services/core/java/com/android/server/wm/DisplayWindowSettings.java
- 6.frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
设置的辅助功能打开或者关闭自动旋转功能
1.packages/apps/Settings/src/com/android/settings/accessibility/AccessibilitySettings.java
1.1 onPreferenceTreeClick(Preference preference)
1.2 handleLockScreenRotationPreferenceClick()
2.frameworks/base/core/java/com/android/internal/view/RotationPolicy.java
2.1 setRotationLockForAccessibility(Context context, final boolean enabled)
自动旋转屏幕,打开为1,关闭为0,默认为0。
可以通过:
adb shell settings get system hide_rotation_lock_toggle_for_accessibility 0
辅助功能的自动旋转屏幕开关,0表示打开。1表示关闭。
2.2 private static void setRotationLock(final boolean enabled, final int rotation) 看准参数,里边有个重载方法。
调用WindowManagerService的两个方法,根据enable状态调用对应方法,freezeRotation()不允许转屏,thawRotation()允许转屏。分两路走流程。
3.frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
3.1freezeRotation(int rotation) 或 thawRotation()
冻结旋转
解冻旋转
3.2 freezeDisplayRotation(int displayId, int rotation) 或 thawDisplayRotation(int displayId)
3.3 wms在调用freezeRotation()或thawRotation()后调用6.2 的updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) 更新未检查的旋转角度
4.frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java
4.1 freezeRotation(int rotation) 或 thawRotation()
4.2 setUserRotation(int userRotationMode, int userRotation) 该方法会在Settings.System中写入值。
冻结旋转freezeRotation: 会存储accelerometer_rotation 值为1,解冻旋转为0。
adb shell settings get system accelerometer_rotation 0
旋转状态,0表示不支持旋转。1表示支持旋转。
自动旋转关闭时:
adb shell settings get system user_rotation
用户旋转横竖屏:0表示竖屏,1表示横屏。
自动旋转快打开时:
值为上一次旋转值。
4.3 DisplayRotation.java构造函数中创建了SettingsObserver对象,其observe()方法将监听Settings.System.USER_ROTATION和Settings.System.ACCELEROMETER_ROTATION的值,监听到该值后调用onChange。
onChange方法,调用updateSettings()方法,最后调用WindowManagerService的更新旋转角度,见6.2方法。
updateSettings()方法其主要的工作是根据需要监听传感器数据,据此判断是否要转屏,如果传感器传回的值改变,则对configuration的各种更新。函数updateSettings()如它的名字主要更新设置信息。如果UserRotation(朝向信息,如Surface.ROTATION_0)和UserRotationMode(USER_ROTATION_FREE vs. USER_ROTATION_LOCKED)有更新,就设置标记 shouldUpdateRotation 为true表示接下去需要更新rotation相关信息。
5. frameworks/base/services/core/java/com/android/server/wm/DisplayWindowSettings.java
5.1 setUserRotation(DisplayContent displayContent, int rotationMode, int rotation)
5.2 writeSettingsIfNeeded(Entry changedEntry, DisplayInfo displayInfo)
5.3writeSettings()
6.frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
6.1 updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) 调用当前类的updateRotationUnchecked方法
6.2 updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) 更新未检查的旋转角度