前期说明
-
为什么需要 “横屏”?
根据产品需求, 另外是硬件上没有GSensor.
-
为什么需要 “缩放”?
横屏后, 第三方APK显示异常, 例如微信视频聊天, 整体画面会被拉伸或者是倒置, 所以强制横屏&缩放优化后, 效果图如下:
如何实现
主要修改:
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
关键变量 & 函数:
// 旋转函数
1. WindowManagerService::updateRotationUncheckedLocked()
int rotation; //局部变量, 决定应用程序显示方向.
2. WindowManagerService::updateDisplayAndOrientationLocked()
boolean mAltOrientation; //全局变量
// 焦点改变函数
3. WindowManagerService::setFocusedApp()
代码修改
- 新增API
// API: doForceRotationSpecificApp: specific activity rotation direction.
// doForceDisplaySizeSpecificApp: specific activity window size.
private boolean mAlreadyForcedDisplaySize = false;
// 用于读取自定义 '旋屏' 配置
private int doForceRotationSpecificApp(AppWindowToken focusad) {
return SystemProperties.getInt("custom.system.disp_rotation", Surface.ROTATION_0);
}
// 用于强制应用横屏, 这里演示微信视频(com.tencent.mm/.plugin.voip.ui.VideoActivity)
private void doForceDisplaySizeSpecificApp(AppWindowToken focusad) {
if (null != focusad) {
if ((focusad.token + "").contains("com.tencent.mm") &&
(focusad.token + "").contains("plugin.voip.ui.VideoActivity")) {
mAlreadyForcedDisplaySize = true;
final DisplayContent displayContent = getDisplayContentLocked(Display.DEFAULT_DISPLAY);
if (displayContent != null) {
setForcedDisplaySize(Display.DEFAULT_DISPLAY, (int)(displayContent.mInitialDisplayWidth / 2.2f), displayContent.mInitialDisplayHeight);
}
} else {
if (mAlreadyForcedDisplaySize) {
clearForcedDisplaySize(Display.DEFAULT_DISPLAY);
mAlreadyForcedDisplaySize = false;
}
}
}
}
- 强制缩放:
WindowManagerService::setFocusedApp()
if (changed) {
mFocusedApp = newFocus;
doForceDisplaySizeSpecificApp(mFocusedApp);
...
}
- 强制横屏:
WindowManagerService::updateRotationUncheckedLocked()
//int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
// doForceRotationSpecificApp 添加可以通过build.prop 配置显示方向
int rotation = doForceRotationSpecificApp(mFocusedApp);
if (rotation > Surface.ROTATION_270) {
rotation = Surface.ROTATION_0;
}
WindowManagerService::updateDisplayAndOrientationLocked()
// 直接注释掉防止, APK设置旋转
//if (mAltOrientation) {
if (false) {
if (realdw > realdh) {
// Turn landscape into portrait.
int maxw = (int)(realdh / 1.3f);
if (maxw < realdw) {
dw = maxw;
}
} else {
// Turn portrait into landscape.
int maxh = (int)(realdw / 1.3f);
if (maxh < realdh) {
dh = maxh;
}
}
}
[补充]: 有问题可以邮件沟通 iFinelio Tower <308662170@qq.com>