Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4846ee3c authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Optimize window relayouts when dragging divider

- Communicate the resize mode to ViewRootImpl. If it is a docked
divider resize, do not call relayout for every traversal.
- Do not call Task.resizeWindows() unconditionally when changing
Stack bounds. It might be just a move.
- However, not calling relayout breaks layout bounds while
relaunching. To fix that, do the following:
-- Inform ViewRootImpl that the activity just relaunched, and force
a relayout call in the next traversal so the client can pick up
the unfrozen bounds.
-- When unfreezing the bounds, cause a traversal in window manager.

Bug: 25015474
Change-Id: Iab9a445dabce4f6ec1e25957038fe40a4be65246
parent 8a47292e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -4362,6 +4362,9 @@ public final class ActivityThread {
        if (!tmp.onlyLocalRequest) {
            try {
                ActivityManagerNative.getDefault().activityRelaunched(r.token);
                if (r.window != null) {
                    r.window.reportActivityRelaunched();
                }
            } catch (RemoteException e) {
                // If the system process has died, it's game over for everyone.
            }
+29 −3
Original line number Diff line number Diff line
@@ -144,6 +144,9 @@ public final class ViewRootImpl implements ViewParent,
     */
    static final int MAX_TRACKBALL_DELAY = 250;

    private static final int RESIZE_MODE_FREEFORM = 0;
    private static final int RESIZE_MODE_DOCKED_DIVIDER = 1;

    static final ThreadLocal<HandlerActionQueue> sRunQueues = new ThreadLocal<HandlerActionQueue>();

    static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList();
@@ -228,8 +231,10 @@ public final class ViewRootImpl implements ViewParent,
    boolean mIsAnimating;

    private boolean mDragResizing;
    private int mResizeMode;
    private int mCanvasOffsetX;
    private int mCanvasOffsetY;
    private boolean mActivityRelaunched;

    CompatibilityInfo.Translator mTranslator;

@@ -1592,12 +1597,17 @@ public final class ViewRootImpl implements ViewParent,
                        frame.width() < desiredWindowWidth && frame.width() != mWidth)
                || (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT &&
                        frame.height() < desiredWindowHeight && frame.height() != mHeight));
        windowShouldResize |= mDragResizing;
        windowShouldResize |= mDragResizing && mResizeMode == RESIZE_MODE_FREEFORM;

        // If the backdrop frame doesn't equal to a frame, we are starting a resize operation, so
        // force it to be resized.
        windowShouldResize |= !mPendingBackDropFrame.equals(mWinFrame);

        // If the activity was just relaunched, it might have unfrozen the task bounds (while
        // relaunching), so we need to force a call into window manager to pick up the latest
        // bounds.
        windowShouldResize |= mActivityRelaunched;

        // Determine whether to compute insets.
        // If there are no inset listeners remaining then we may still need to compute
        // insets in case the old insets were non-empty and must be reset.
@@ -1786,11 +1796,17 @@ public final class ViewRootImpl implements ViewParent,
                    }
                }

                final boolean dragResizing = (relayoutResult
                        & WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING) != 0;
                final boolean freeformResizing = (relayoutResult
                        & WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_FREEFORM) != 0;
                final boolean dockedResizing = (relayoutResult
                        & WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_DOCKED) != 0;
                final boolean dragResizing = freeformResizing || dockedResizing;
                if (mDragResizing != dragResizing) {
                    if (dragResizing) {
                        startDragResizing(mPendingBackDropFrame);
                        mResizeMode = freeformResizing
                                ? RESIZE_MODE_FREEFORM
                                : RESIZE_MODE_DOCKED_DIVIDER;
                    } else {
                        // We shouldn't come here, but if we come we should end the resize.
                        endDragResizing();
@@ -2074,6 +2090,7 @@ public final class ViewRootImpl implements ViewParent,
        mFirst = false;
        mWillDrawSoon = false;
        mNewSurfaceNeeded = false;
        mActivityRelaunched = false;
        mViewVisibility = viewVisibility;
        mHadWindowFocus = hasWindowFocus;

@@ -7025,6 +7042,15 @@ public final class ViewRootImpl implements ViewParent,
        }
    }

    /**
     * Tells this instance that its corresponding activity has just relaunched. In this case, we
     * need to force a relayout of the window to make sure we get the correct bounds from window
     * manager.
     */
    public void reportActivityRelaunched() {
        mActivityRelaunched = true;
    }

    /**
     * Class for managing the accessibility interaction connection
     * based on the global accessibility state.
+6 −0
Original line number Diff line number Diff line
@@ -2120,4 +2120,10 @@ public abstract class Window {
     * @hide
     */
    public abstract void onMultiWindowModeChanged();

    /**
     * Called when the activity just relaunched.
     * @hide
     */
    public abstract void reportActivityRelaunched();
}
+10 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.util.AndroidRuntimeException;
import android.util.ArraySet;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;

import com.android.internal.util.FastPrintWriter;

import java.io.FileDescriptor;
@@ -69,17 +70,24 @@ public final class WindowManagerGlobal {
     */
    public static final int RELAYOUT_RES_SURFACE_CHANGED = 0x4;

    /**
     * The window is being resized by dragging on the docked divider. The client should render
     * at (0, 0) and extend its background to the background frame passed into
     * {@link IWindow#resized}.
     */
    public static final int RELAYOUT_RES_DRAG_RESIZING_DOCKED = 0x8;

    /**
     * The window is being resized by dragging one of the window corners,
     * in this case the surface would be fullscreen-sized. The client should
     * render to the actual frame location (instead of (0,curScrollY)).
     */
    public static final int RELAYOUT_RES_DRAG_RESIZING = 0x8;
    public static final int RELAYOUT_RES_DRAG_RESIZING_FREEFORM = 0x10;

    /**
     * The window manager has changed the size of the surface from the last call.
     */
    public static final int RELAYOUT_RES_SURFACE_RESIZED = 0x10;
    public static final int RELAYOUT_RES_SURFACE_RESIZED = 0x20;

    /**
     * Flag for relayout: the client will be later giving
+7 −0
Original line number Diff line number Diff line
@@ -684,6 +684,13 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
        }
    }

    @Override
    public void reportActivityRelaunched() {
        if (mDecor != null && mDecor.getViewRootImpl() != null) {
            mDecor.getViewRootImpl().reportActivityRelaunched();
        }
    }

    private static void clearMenuViews(PanelFeatureState st) {
        // This can be called on config changes, so we should make sure
        // the views will be reconstructed based on the new orientation, etc.
Loading