首先是横竖屏切换的代码,主要是在windowsmanagerservice里面处理的。 参考了: Android 7.1 屏幕旋转流程分析 Android 7.1 WindowManagerService 屏幕旋转流程分析 (二) Android 7.1 WindowManagerService 屏幕旋转流程分析 (三) Android 7.1 ActivityManagerService 屏幕旋转流程分析 (四) WindowManagerService 大致完成三件事,首先更新屏幕方向,然后具体实施屏幕旋转,最后通知AMS configuration变更。 framework/base/services/core/java/com/android/server/wm/WindowManagerService.java 3858: private void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) { 这个函数即首先调用displayContent.updateRotationUnchecked();更新rotation,然后调用performSurfacePlacement()做屏幕的绘制,最后调用sendNewConfiguration()发送Configuration变更事件。
/* try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } */ do { mTraversalScheduled = false;
因为最终是在SurfaceFlinger里面进行合成显示,需要在java和native间调用切换,通过增加log,最终发现是请求切换的高宽没有送到native层 正确log: 10-16 10:31:23.744 141 141 E Layer : doTransaction geometry (layer=0x714a93067000 ‘com.tencent.tmgp.sgame/com.tencent.midas.proxyactivity.APMidasPayProxyActivity#1’), req(1280, 672) >cur (720, 1232), sizeChanged: 1 错误log: 10-16 10:31:23.744 141 141 E Layer : doTransaction geometry (layer=0x714a93067000 ‘com.tencent.tmgp.sgame/com.tencent.midas.proxyactivity.APMidasPayProxyActivity#1’), req(720, 1280) >cur (720, 1232), sizeChanged: 1
向上跟踪, 发现是setSize没有执行: framework/nativelibs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSize( const sp& sc, uint32_t w, uint32_t h) {
这个是native的api, base里面调过来的,在setSurfaceBoundariesLocked里面有个开关mInRelayout, 发生错误的时候这个值是false。 services/core/java/com/android/server/wm/WindowStateAnimator.java void setSurfaceBoundariesLocked(final boolean recoveringMemory) {…
final boolean relayout = !w.mRelayoutCalled || w.mInRelayout; if (relayout) { mSurfaceResized = mSurfaceController.setSizeInTransaction( mTmpSize.width(), mTmpSize.height(), recoveringMemory); } else {diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 7a2c28bd5c8…730afb59227 100644 — a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1975,6 +1975,9 @@ public class WindowManagerService extends IWindowManager.Stub
win.mRelayoutCalled = true; win.mInRelayout = true; if (requestedWidth != win.mFrame.width() || requestedWidth != win.mRequestedWidth ||win.isNeedReLayout()) { win.mNeedRelayout = true; } win.mViewVisibility = viewVisibility; if (DEBUG_SCREEN_ON) {diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index bee70a01194…d2d7984529e 100644 — a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -475,6 +475,8 @@ class WindowState extends WindowContainer implements WindowManagerP
boolean mInRelayout;boolean mNeedRelayout;
/** * If the application has called relayout() with changes that can * impact its window’s size, we need to perform a layout pass on it @@ -1550,6 +1552,13 @@ class WindowState extends WindowContainer implements WindowManagerP && !mAnimatingExit && !mDestroying; }
boolean isNeedReLayout() {
if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) { return true; } return false;}
/** * Is this window currently on-screen? It is on-screen either if it * is visible or it is currently running an animation before no longer diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 410e1587924…beb8479d5bf 100644 — a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -888,7 +888,7 @@ class WindowStateAnimator { // However, this would be unsafe, as the client may be in the middle // of producing a frame at the old size, having just completed layout // to find the surface size changed underneath it.
final boolean relayout = !w.mRelayoutCalled || w.mInRelayout; final boolean relayout = !w.mRelayoutCalled || w.mInRelayout || w.mNeedRelayout; if (relayout) { mSurfaceResized = mSurfaceController.setSizeInTransaction( mTmpSize.width(), mTmpSize.height(), recoveringMemory);– 2.17.1
