From a4a58efe8203d63a9a6bf78b0fa9f2992b25871b Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Wed, 27 Jan 2016 02:10:08 -0800 Subject: [PATCH] Fix app staying in drag resizing when undocking When dismissing the docked stack, the fullscreen stack stayed in drag resize mode because it got a relayout, but because the bounds didn't change (it switches to the fullscreen layout a bit earlier) it never called WM.relayoutWindow, so it stayed in drag resize mode indefinitely. To fix this, introduce forceRelayout in Window.resized(), which makes sure the client always calls relayoutWindow. Set this to true whenever drag resizing is changing. For some very weird reason this also broke that home button was not responding anymore. Bug: 26806532 Change-Id: I4b39c1c419a166aa7093c31226f2a4915f642328 --- .../service/wallpaper/WallpaperService.java | 2 +- core/java/android/view/IWindow.aidl | 2 +- core/java/android/view/SurfaceView.java | 5 +++-- core/java/android/view/ViewRootImpl.java | 17 ++++++++++++----- .../com/android/internal/view/BaseIWindow.java | 2 +- .../java/com/android/server/wm/WindowState.java | 3 ++- .../layoutlib/bridge/android/BridgeWindow.java | 2 +- 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index cd196072e981c..a98551752181a 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -271,7 +271,7 @@ public abstract class WallpaperService extends Service { @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, Rect backDropRect) { + Configuration newConfig, Rect backDropRect, boolean forceLayout) { Message msg = mCaller.obtainMessageIO(MSG_WINDOW_RESIZED, reportDraw ? 1 : 0, outsets); mCaller.sendMessage(msg); diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index c5ed39af5fb80..3688d50d9fe3f 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -49,7 +49,7 @@ oneway interface IWindow { void resized(in Rect frame, in Rect overscanInsets, in Rect contentInsets, in Rect visibleInsets, in Rect stableInsets, in Rect outsets, boolean reportDraw, - in Configuration newConfig, in Rect backDropFrame); + in Configuration newConfig, in Rect backDropFrame, boolean forceLayout); void moved(int newX, int newY); void dispatchAppVisibility(boolean visible); void dispatchGetNewSurface(); diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 9f6d3e5acf543..5b48e2893fc74 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -698,7 +698,7 @@ public class SurfaceView extends View { @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, Rect backDropRect) { + Configuration newConfig, Rect backDropRect, boolean forceLayout) { SurfaceView surfaceView = mSurfaceView.get(); if (surfaceView != null) { if (DEBUG) Log.v( @@ -711,7 +711,8 @@ public class SurfaceView extends View { surfaceView.mReportDrawNeeded = true; surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG); } else if (surfaceView.mWinFrame.width() != frame.width() - || surfaceView.mWinFrame.height() != frame.height()) { + || surfaceView.mWinFrame.height() != frame.height() + || forceLayout) { surfaceView.mUpdateWindowNeeded = true; surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 25eecc490ea94..98e32891e033f 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -16,6 +16,7 @@ package android.view; +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; @@ -263,6 +264,7 @@ public final class ViewRootImpl implements ViewParent, boolean mNewSurfaceNeeded; boolean mHasHadWindowFocus; boolean mLastWasImTarget; + boolean mForceNextWindowRelayout; CountDownLatch mWindowDrawCountDown; boolean mIsDrawing; @@ -1625,7 +1627,8 @@ public final class ViewRootImpl implements ViewParent, final boolean isViewVisible = viewVisibility == View.VISIBLE; if (mFirst || windowShouldResize || insetsChanged || - viewVisibilityChanged || params != null) { + viewVisibilityChanged || params != null || mForceNextWindowRelayout) { + mForceNextWindowRelayout = false; if (isViewVisible) { // If this window is giving internal insets to the window @@ -3366,7 +3369,8 @@ public final class ViewRootImpl implements ViewParent, && mPendingVisibleInsets.equals(args.arg3) && mPendingOutsets.equals(args.arg7) && mPendingBackDropFrame.equals(args.arg8) - && args.arg4 == null) { + && args.arg4 == null + && args.argi1 == 0) { break; } } // fall through... @@ -3386,6 +3390,7 @@ public final class ViewRootImpl implements ViewParent, mPendingVisibleInsets.set((Rect) args.arg3); mPendingOutsets.set((Rect) args.arg7); mPendingBackDropFrame.set((Rect) args.arg8); + mForceNextWindowRelayout = args.argi1 != 0; args.recycle(); @@ -5830,7 +5835,7 @@ public final class ViewRootImpl implements ViewParent, public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, Rect backDropFrame) { + Configuration newConfig, Rect backDropFrame, boolean forceLayout) { if (DEBUG_LAYOUT) Log.v(mTag, "Resizing " + this + ": frame=" + frame.toShortString() + " contentInsets=" + contentInsets.toShortString() + " visibleInsets=" + visibleInsets.toShortString() @@ -5864,6 +5869,7 @@ public final class ViewRootImpl implements ViewParent, args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets; args.arg7 = sameProcessCall ? new Rect(outsets) : outsets; args.arg8 = sameProcessCall ? new Rect(backDropFrame) : backDropFrame; + args.argi1 = forceLayout ? 1 : 0; msg.obj = args; mHandler.sendMessage(msg); } @@ -6879,11 +6885,12 @@ public final class ViewRootImpl implements ViewParent, @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, Rect backDropFrame) { + Configuration newConfig, Rect backDropFrame, boolean forceLayout) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchResized(frame, overscanInsets, contentInsets, - visibleInsets, stableInsets, outsets, reportDraw, newConfig, backDropFrame); + visibleInsets, stableInsets, outsets, reportDraw, newConfig, backDropFrame, + forceLayout); } } diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index 7dfc15d9195e3..bcc310f7a9fa8 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -38,7 +38,7 @@ public class BaseIWindow extends IWindow.Stub { @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig, - Rect backDropFrame) { + Rect backDropFrame, boolean forceLayout) { if (reportDraw) { try { mSession.finishDrawing(this); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index e8de90c93f0aa..c541b3f6f56be 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2061,7 +2061,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig) throws RemoteException { mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets, - reportDraw, newConfig, getBackdropFrame(frame)); + reportDraw, newConfig, getBackdropFrame(frame), + isDragResizeChanged() /* forceRelayout */); } public void registerFocusObserver(IWindowFocusObserver observer) { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java index a3f3821c56908..2000fbc0fa474 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java @@ -50,7 +50,7 @@ public final class BridgeWindow implements IWindow { @Override public void resized(Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5, Rect rect6, - boolean b, Configuration configuration, Rect rect7) throws RemoteException { + boolean b, Configuration configuration, Rect rect7, boolean b2) throws RemoteException { // pass for now. }