问题描述
系统打开自动转屏,
app中设置 android:screenOrientation="portrait"为0度(竖屏)
实测 app仍然随着手机转动而转动
问题分析
通过观察
此手机 的独特性是其屏幕尺寸 长宽相等 是个square方屏。
问题解决
代码中的问题 记录如下
frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
/**
* If this is true, we would not rotate the display for apps. The rotation would be either the
* sensor rotation or the user rotation, controlled by
* {@link WindowManagerPolicy.UserRotationMode}.
*/
// 如果是true,我们不会旋转应用程序的显示。
//旋转可以是传感器旋转或用户旋转 ,由 WindowManagerPolicy.UserRotationMode 控制
private boolean mIgnoreRotationForApps;
void configureDisplayPolicy() {
final int width = mBaseDisplayWidth;
final int height = mBaseDisplayHeight;
final int shortSize;
final int longSize;
if (width > height) {
shortSize = height;
longSize = width;
} else {
shortSize = width;
longSize = height;
}
final int shortSizeDp = shortSize * DENSITY_DEFAULT / mBaseDisplayDensity;
final int longSizeDp = longSize * DENSITY_DEFAULT / mBaseDisplayDensity;
mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors();
mDisplayRotation.configure(width, height, shortSizeDp, longSizeDp);
mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
// Not much of use to rotate the display for apps since it's close to square.
//因为它接近正方形,所以旋转应用程序的显示并没有多大用处。
mIgnoreRotationForApps = isNonDecorDisplayCloseToSquare(Surface.ROTATION_0, width, height);
}
private boolean isNonDecorDisplayCloseToSquare(int rotation, int width, int height) {
final DisplayCutout displayCutout =
calculateDisplayCutoutForRotation(rotation).getDisplayCutout();
final int uiMode = mWmService.mPolicy.getUiMode();
final int w = mDisplayPolicy.getNonDecorDisplayWidth(
width, height, rotation, uiMode, displayCutout);
final int h = mDisplayPolicy.getNonDecorDisplayHeight(
width, height, rotation, uiMode, displayCutout);
final float aspectRatio = Math.max(w, h) / (float) Math.min(w, h);
return aspectRatio <= mCloseToSquareMaxAspectRatio;
}
@Override
int getOrientation() {
final WindowManagerPolicy policy = mWmService.mPolicy;
if (mIgnoreRotationForApps) {
return SCREEN_ORIENTATION_USER;
}
if (mWmService.mDisplayFrozen) {
if (mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
+ " is frozen, return " + mLastWindowForcedOrientation);
// If the display is frozen, some activities may be in the middle of restarting, and
// thus have removed their old window. If the window has the flag to hide the lock
// screen, then the lock screen can re-appear and inflict its own orientation on us.
// Keep the orientation stable until this all settles down.
return mLastWindowForcedOrientation;
} else if (policy.isKeyguardLocked()) {
// Use the last orientation the while the display is frozen with the keyguard
// locked. This could be the keyguard forced orientation or from a SHOW_WHEN_LOCKED
// window. We don't want to check the show when locked window directly though as
// things aren't stable while the display is frozen, for example the window could be
// momentarily unavailable due to activity relaunch.
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
+ " is frozen while keyguard locked, return " + mLastOrientation);
return mLastOrientation;
}
} else {
final int orientation = mAboveAppWindowsContainers.getOrientation();
if (orientation != SCREEN_ORIENTATION_UNSET) {
return orientation;
}
}
// Top system windows are not requesting an orientation. Start searching from apps.
return mTaskStackContainers.getOrientation();
}
总结
如果屏幕是接近方形。 将忽略app的rotation设置