在14.0系统产品rom定制化开发中,对于处理屏幕旋转方向,首先有kernel底层处理,从底层驱动gsensor 中获取数据,从而判断屏幕方向的,
然后事件上报后 最后由WMS就是WindowManagerService 来处理旋转的相关事件,接下来看下强制app横屏显示功能如何实现
framework/base/services/java/com/android/server/wm/DisplayRotation.java
在系统中wms主要是处理屏幕相关的核心类,WMS中在处理屏幕自动旋转,主要是调用
DisplayRotation的freezeRotation方法锁定用户指定的屏幕方向,调用thawRotation方法,解锁用户固定屏幕,
恢复屏幕自动旋转。最后调用updateRotationUnchecked,发送新的Configuration变化,
以及如果布局发生变化,也会重新计算布局。
通过上述源码分析,在系统中关于处理屏幕方法的系统中就是DisplayRotation.java 里负责处理的,这里根据系统当前的旋转方向
具体需要看源码然后分析具体的旋转功能
- int rotationForOrientation(@ScreenOrientation int orientation,
- @Surface.Rotation int lastRotation) {
-
- if (isFixedToUserRotation()) {
- return mUserRotation;
- }
-
- int sensorRotation = mOrientationListener != null
- ? mOrientationListener.getProposedRotation() // may be -1
- : -1;
- if (sensorRotation < 0) {
- sensorRotation = lastRotation;
- }
-
- final int lidState = mDisplayPolicy.getLidState();
- final int dockMode = mDisplayPolicy.getDockMode();
- final boolean hdmiPlugged = mDisplayPolicy.isHdmiPlugged();
- final boolean carDockEnablesAccelerometer =
- mDisplayPolicy.isCarDockEnablesAccelerometer();
- final boolean deskDockEnablesAccelerometer =
- mDisplayPolicy.isDeskDockEnablesAccelerometer();
-
- final int preferredRotation;
- if (!isDefaultDisplay) {
- preferredRotation = mUserRotation;
- } else if (lidState == LID_OPEN && mLidOpenRotation >= 0) {
- preferredRotation = mLidOpenRotation;
- } else if (dockMode == Intent.EXTRA_DOCK_STATE_CAR
- && (carDockEnablesAccelerometer || mCarDockRotation >= 0)) {
- preferredRotation = carDockEnablesAccelerometer ? sensorRotation : mCarDockRotation;
- } else if ((dockMode == Intent.EXTRA_DOCK_STATE_DESK
- || dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
- || dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
- && (deskDockEnablesAccelerometer || mDeskDockRotation >= 0)) {
- preferredRotation = deskDockEnablesAccelerometer ? sensorRotation : mDeskDockRotation;
- } else if (hdmiPlugged && mDemoHdmiRotationLock) {
- preferredRotation = mDemoHdmiRotation;
- } else if (hdmiPlugged && dockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED
- && mUndockedHdmiRotation >= 0) {
- preferredRotation = mUndockedHdmiRotation;
- } else if (mDemoRotationLock) {
- preferredRotation = mDemoRotation;
- } else if (mDisplayPolicy.isPersistentVrModeEnabled()) {
- preferredRotation = mPortraitRotation;
- } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
- preferredRotation = lastRotation;
- } else if (!mSupportAutoRotation) {
- preferredRotation = -1;
- } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
- && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
- || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
- || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
- || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER))
- || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
- || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
- || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
- if (mAllowAllRotations == ALLOW_ALL_ROTATIONS_UNDEFINED) {
- mAllowAllRotations = mContext.getResources().getBoolean(
- R.bool.config_allowAllRotations)
- ? ALLOW_ALL_ROTATIONS_ENABLED
- : ALLOW_ALL_ROTATIONS_DISABLED;
- }
- if (sensorRotation != Surface.ROTATION_180
- || mAllowAllRotations == ALLOW_ALL_ROTATIONS_ENABLED
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
- preferredRotation = sensorRotation;
- } else {
- preferredRotation = lastRotation;
- }
- } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
- && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
- && orientation != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
- && orientation != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
- && orientation != ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
- && orientation != ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT) {
- preferredRotation = mUserRotation;
- } else {
- // No overriding preference.
- // We will do exactly what the application asked us to do.
- preferredRotation = -1;
- }
-
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
- // Return portrait unless overridden.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- return mPortraitRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
- // Return landscape unless overridden.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- return mLandscapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
- // Return reverse portrait unless overridden.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- return mUpsideDownRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
- // Return seascape unless overridden.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- return mSeascapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
- case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
- // Return either landscape rotation.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- if (isLandscapeOrSeascape(lastRotation)) {
- return lastRotation;
- }
- return mLandscapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
- case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
- // Return either portrait rotation.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- if (isAnyPortrait(lastRotation)) {
- return lastRotation;
- }
- return mPortraitRotation;
-
- default:
- if (preferredRotation >= 0) {
- return preferredRotation;
- }
- return Surface.ROTATION_0;
- }
- }
在上述的DisplayRotation.java的相关源码中分析得知,系统在开机过程中,首选在wms中先调用rotationForOrientation函数来获取rotation,来获取当前屏幕的旋转方向,获取当前的屏幕方向后,在根据当前屏幕方向来进行具体的系统方向旋转,最终会调用到
rotationForOrientation(int orientation, int lastRotation) 来获取屏幕的方向值,在具体负责处理app具体的方向旋转当app进入
到activity后由rotationForOrientation()来判断屏幕需要显示的方向,最后处理屏幕的具体旋转方向
具体是在
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
- // Return portrait unless overridden.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- - return mPortraitRotation;
- + return Surface.ROTATION_90;
-
- case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
- // Return landscape unless overridden.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- return mLandscapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
- // Return reverse portrait unless overridden.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- return mUpsideDownRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
- // Return seascape unless overridden.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- return mSeascapeRotation;
在上述的DisplayRotation.java的相关源码中分析得知,系统判定屏幕旋转方向具体是在rotationForOrientation(int orientation, int lastRotation) 中
当处理屏幕旋转方向时,根据当前屏幕旋转的方向,需要处理是根据
case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT的时候,判断当前需要旋转到什么方向,
这时候系统在进入app的时候当设置屏幕方向的时候,如果需要横屏显示这时候就需要设置方向旋转90度,所以在上面判断如果当前是竖屏,在这里设置旋转90的屏幕方向就可以了从而实现功能