OSDN Git Service

Relayout window when rotated landscape <-> seascape
authorAndrii Kulian <akulian@google.com>
Wed, 11 Jan 2017 08:36:44 +0000 (00:36 -0800)
committerAndrii Kulian <akulian@google.com>
Fri, 13 Jan 2017 01:28:18 +0000 (01:28 +0000)
When 180 degree rotation happens there is no real configuration
change, so an application window could miss an update, which
caused visual artifacts.
In this CL layout is forced when rotation changes.

Test: Unit tests in ag/1778638.
Bug: 33607506
Change-Id: Ia1e3375212bade9061d6e1d9679604e67c50da20

core/java/android/view/ViewRootImpl.java
services/core/java/com/android/server/wm/WindowManagerService.java
services/core/java/com/android/server/wm/WindowState.java

index b42f769..36825dd 100644 (file)
@@ -1724,6 +1724,7 @@ public final class ViewRootImpl implements ViewParent,
         final int surfaceGenerationId = mSurface.getGenerationId();
 
         final boolean isViewVisible = viewVisibility == View.VISIBLE;
+        final boolean windowRelayoutWasForced = mForceNextWindowRelayout;
         if (mFirst || windowShouldResize || insetsChanged ||
                 viewVisibilityChanged || params != null || mForceNextWindowRelayout) {
             mForceNextWindowRelayout = false;
@@ -1888,7 +1889,7 @@ public final class ViewRootImpl implements ViewParent,
                         mAttachInfo.mThreadedRenderer.destroy();
                     }
                 } else if ((surfaceGenerationId != mSurface.getGenerationId()
-                        || surfaceSizeChanged)
+                        || surfaceSizeChanged || windowRelayoutWasForced)
                         && mSurfaceHolder == null
                         && mAttachInfo.mThreadedRenderer != null) {
                     mFullRedrawNeeded = true;
index 38cb543..332a9b9 100644 (file)
@@ -4465,7 +4465,7 @@ public class WindowManagerService extends IWindowManager.Stub
                 mRoot.mOrientationChangeComplete = false;
                 w.mLastFreezeDuration = 0;
             }
-
+            w.mReportOrientationChanged = true;
         }, true /* traverseTopToBottom */);
 
         if (rotateSeamlessly) {
index 3daad43..3816d5d 100644 (file)
@@ -429,6 +429,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
     int mLastVisibleLayoutRotation = -1;
 
     /**
+     * Set when we need to report the orientation change to client to trigger a relayout.
+     */
+    boolean mReportOrientationChanged;
+
+    /**
      * How long we last kept the screen frozen.
      */
     int mLastFreezeDuration;
@@ -1093,7 +1098,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                 || mFrameSizeChanged
                 || configChanged
                 || dragResizingChanged
-                || !isResizedWhileNotDragResizingReported()) {
+                || !isResizedWhileNotDragResizingReported()
+                || mReportOrientationChanged) {
             if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
                 Slog.v(TAG_WM, "Resize reasons for w=" + this + ": "
                         + " contentInsetsChanged=" + mContentInsetsChanged
@@ -1108,7 +1114,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                         + " configChanged=" + configChanged
                         + " dragResizingChanged=" + dragResizingChanged
                         + " resizedWhileNotDragResizingReported="
-                        + isResizedWhileNotDragResizingReported());
+                        + isResizedWhileNotDragResizingReported()
+                        + " reportOrientationChanged=" + mReportOrientationChanged);
             }
 
             // If it's a dead window left on screen, and the configuration changed, there is nothing
@@ -3004,6 +3011,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
             final Rect stableInsets = mLastStableInsets;
             final Rect outsets = mLastOutsets;
             final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING;
+            final boolean reportOrientation = mReportOrientationChanged;
             if (mAttrs.type != WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
                     && mClient instanceof IWindow.Stub) {
                 // To prevent deadlock simulate one-way call if win.mClient is a local object.
@@ -3012,7 +3020,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                     public void run() {
                         try {
                             dispatchResized(frame, overscanInsets, contentInsets, visibleInsets,
-                                    stableInsets, outsets, reportDraw, newConfig);
+                                    stableInsets, outsets, reportDraw, newConfig,
+                                    reportOrientation);
                         } catch (RemoteException e) {
                             // Not a remote call, RemoteException won't be raised.
                         }
@@ -3020,7 +3029,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                 });
             } else {
                 dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets,
-                        outsets, reportDraw, newConfig);
+                        outsets, reportDraw, newConfig, reportOrientation);
             }
 
             //TODO (multidisplay): Accessibility supported only for the default display.
@@ -3036,6 +3045,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
             mFrameSizeChanged = false;
             mResizedWhileNotDragResizingReported = true;
             mWinAnimator.mSurfaceResized = false;
+            mReportOrientationChanged = false;
         } catch (RemoteException e) {
             mOrientationChanging = false;
             mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
@@ -3076,8 +3086,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
 
     private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
             Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
-            Configuration newConfig) throws RemoteException {
-        final boolean forceRelayout = isDragResizeChanged() || mResizedWhileNotDragResizing;
+            Configuration newConfig, boolean reportOrientation) throws RemoteException {
+        final boolean forceRelayout = isDragResizeChanged() || mResizedWhileNotDragResizing
+                || reportOrientation;
 
         mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets,
                 reportDraw, newConfig, getBackdropFrame(frame),
@@ -3370,11 +3381,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                     pw.print(" mDestroying="); pw.print(mDestroying);
                     pw.print(" mRemoved="); pw.println(mRemoved);
         }
-        if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
+        if (mOrientationChanging || mAppFreezing || mTurnOnScreen
+                || mReportOrientationChanged) {
             pw.print(prefix); pw.print("mOrientationChanging=");
                     pw.print(mOrientationChanging);
                     pw.print(" mAppFreezing="); pw.print(mAppFreezing);
                     pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
+                    pw.print(" mReportOrientationChanged="); pw.println(mReportOrientationChanged);
         }
         if (mLastFreezeDuration != 0) {
             pw.print(prefix); pw.print("mLastFreezeDuration=");