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

Commit 48076b2b authored by Tiger Huang's avatar Tiger Huang Committed by Android (Google) Code Review
Browse files

Merge "Refine simulateLayoutDisplay"

parents 4092e531 54670769
Loading
Loading
Loading
Loading
+54 −113
Original line number Original line Diff line number Diff line
@@ -118,9 +118,9 @@ import android.os.Message;
import android.os.SystemClock;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.PrintWriterPrinter;
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.util.Slog;
import android.util.SparseArray;
import android.view.DisplayCutout;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.Gravity;
@@ -283,15 +283,12 @@ public class DisplayPolicy {
    @WindowManagerPolicy.AltBarPosition
    @WindowManagerPolicy.AltBarPosition
    private int mExtraNavBarAltPosition = ALT_BAR_UNKNOWN;
    private int mExtraNavBarAltPosition = ALT_BAR_UNKNOWN;


    /** See {@link #getNavigationBarFrameHeight} */
    private final ArraySet<WindowState> mInsetsSourceWindowsExceptIme = new ArraySet<>();
    private int[] mNavigationBarFrameHeightForRotationDefault = new int[4];


    private boolean mIsFreeformWindowOverlappingWithNavBar;
    private boolean mIsFreeformWindowOverlappingWithNavBar;


    private boolean mLastImmersiveMode;
    private boolean mLastImmersiveMode;


    private final SparseArray<Rect> mBarContentFrames = new SparseArray<>();

    // The windows we were told about in focusChanged.
    // The windows we were told about in focusChanged.
    private WindowState mFocusedWindow;
    private WindowState mFocusedWindow;
    private WindowState mLastFocusedWindow;
    private WindowState mLastFocusedWindow;
@@ -339,9 +336,11 @@ public class DisplayPolicy {
    private long mPendingPanicGestureUptime;
    private long mPendingPanicGestureUptime;


    private static final Rect sTmpRect = new Rect();
    private static final Rect sTmpRect = new Rect();
    private static final Rect sTmpDecorFrame = new Rect();
    private static final Rect sTmpLastParentFrame = new Rect();
    private static final Rect sTmpLastParentFrame = new Rect();
    private static final Rect sTmpDisplayFrameBounds = new Rect();
    private static final Rect sTmpDisplayCutoutSafe = new Rect();
    private static final Rect sTmpDisplayFrame = new Rect();
    private static final Rect sTmpParentFrame = new Rect();
    private static final Rect sTmpFrame = new Rect();


    private final WindowLayout mWindowLayout = new WindowLayout();
    private final WindowLayout mWindowLayout = new WindowLayout();


@@ -1093,6 +1092,7 @@ public class DisplayPolicy {
                mDisplayContent.setInsetProvider(
                mDisplayContent.setInsetProvider(
                        ITYPE_TOP_MANDATORY_GESTURES, win, gestureFrameProvider);
                        ITYPE_TOP_MANDATORY_GESTURES, win, gestureFrameProvider);
                mDisplayContent.setInsetProvider(ITYPE_TOP_TAPPABLE_ELEMENT, win, null);
                mDisplayContent.setInsetProvider(ITYPE_TOP_TAPPABLE_ELEMENT, win, null);
                mInsetsSourceWindowsExceptIme.add(win);
                break;
                break;
            case TYPE_NAVIGATION_BAR:
            case TYPE_NAVIGATION_BAR:
                mNavigationBar = win;
                mNavigationBar = win;
@@ -1137,6 +1137,7 @@ public class DisplayPolicy {
                                inOutFrame.setEmpty();
                                inOutFrame.setEmpty();
                            }
                            }
                        });
                        });
                mInsetsSourceWindowsExceptIme.add(win);
                if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
                if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
                break;
                break;
            default:
            default:
@@ -1170,6 +1171,7 @@ public class DisplayPolicy {
                                windowState, inOutFrame) -> inOutFrame.inset(
                                windowState, inOutFrame) -> inOutFrame.inset(
                                windowState.getLayoutingAttrs(displayFrames.mRotation)
                                windowState.getLayoutingAttrs(displayFrames.mRotation)
                                        .providedInternalInsets), imeFrameProvider);
                                        .providedInternalInsets), imeFrameProvider);
                        mInsetsSourceWindowsExceptIme.add(win);
                    }
                    }
                }
                }
                break;
                break;
@@ -1253,6 +1255,7 @@ public class DisplayPolicy {
        if (mLastFocusedWindow == win) {
        if (mLastFocusedWindow == win) {
            mLastFocusedWindow = null;
            mLastFocusedWindow = null;
        }
        }
        mInsetsSourceWindowsExceptIme.remove(win);
    }
    }


    private int getStatusBarHeight(DisplayFrames displayFrames) {
    private int getStatusBarHeight(DisplayFrames displayFrames) {
@@ -1433,49 +1436,22 @@ public class DisplayPolicy {
        return mForceShowSystemBars;
        return mForceShowSystemBars;
    }
    }


    private void simulateLayoutDecorWindow(WindowState win, DisplayFrames displayFrames,
            WindowFrames simulatedWindowFrames, Consumer<Rect> layout) {
        win.setSimulatedWindowFrames(simulatedWindowFrames);
        final int requestedHeight = win.mRequestedHeight;
        final int requestedWidth = win.mRequestedWidth;
        // Without a full layout process, in order to layout the system bars correctly, we need
        // to set the requested size and the initial display frames to the window.
        WindowManager.LayoutParams params = win.getLayoutingAttrs(displayFrames.mRotation);
        win.setRequestedSize(params.width, params.height);
        sTmpDecorFrame.set(0, 0, displayFrames.mDisplayWidth, displayFrames.mDisplayHeight);
        simulatedWindowFrames.setFrames(sTmpDecorFrame /* parentFrame */,
                sTmpDecorFrame /* displayFrame */);
        simulatedWindowFrames.mIsSimulatingDecorWindow = true;
        final Rect contentFrame = new Rect();
        try {
            layout.accept(contentFrame);
        } finally {
            win.setSimulatedWindowFrames(null);
            win.setRequestedSize(requestedWidth, requestedHeight);
        }
        mDisplayContent.getInsetsStateController().computeSimulatedState(
                win, displayFrames, simulatedWindowFrames);
    }

    /**
    /**
     * Computes the frames of display (its logical size, rotation and cutout should already be set)
     * Computes the frames of display (its logical size, rotation and cutout should already be set)
     * used to layout window. This method only changes the given display frames, insets state and
     * used to layout window. This method only changes the given display frames, insets state and
     * some temporal states, but doesn't change the window frames used to show on screen.
     * some temporal states, but doesn't change the window frames used to show on screen.
     */
     */
    void simulateLayoutDisplay(DisplayFrames displayFrames) {
    void simulateLayoutDisplay(DisplayFrames displayFrames) {
        final InsetsStateController insetsStateController =
        final InsetsStateController controller = mDisplayContent.getInsetsStateController();
                mDisplayContent.getInsetsStateController();
        for (int i = mInsetsSourceWindowsExceptIme.size() - 1; i >= 0; i--) {
        for (int type = 0; type < InsetsState.SIZE; type++) {
            final WindowState win = mInsetsSourceWindowsExceptIme.valueAt(i);
            final InsetsSourceProvider provider =
            mWindowLayout.computeWindowFrames(win.getLayoutingAttrs(displayFrames.mRotation),
                    insetsStateController.peekSourceProvider(type);
                    displayFrames.mInsetsState, displayFrames.mDisplayCutoutSafe,
            if (provider == null || !provider.hasWindow()
                    displayFrames.mUnrestricted, win.getWindowingMode(), UNSPECIFIED_LENGTH,
                    || provider.mWin.getControllableInsetProvider() != provider) {
                    UNSPECIFIED_LENGTH, win.getRequestedVisibilities(),
                continue;
                    null /* attachedWindowFrame */, win.mGlobalScale,
            }
                    sTmpDisplayFrame, sTmpParentFrame, sTmpFrame);
            final WindowFrames simulatedWindowFrames = new WindowFrames();
            controller.computeSimulatedState(win, displayFrames, sTmpFrame);
            simulateLayoutDecorWindow(provider.mWin, displayFrames, simulatedWindowFrames,
                    contentFrame -> simulateLayoutForContentFrame(displayFrames,
                            provider.mWin, contentFrame));
        }
        }
    }
    }


@@ -1483,25 +1459,6 @@ public class DisplayPolicy {
        mSystemGestures.onDisplayInfoChanged(info);
        mSystemGestures.onDisplayInfoChanged(info);
    }
    }


    private void simulateLayoutForContentFrame(DisplayFrames displayFrames, WindowState win,
            Rect simulatedContentFrame) {
        layoutWindowLw(win, null /* attached */, displayFrames);
        final Rect contentFrame = sTmpRect;
        contentFrame.set(win.getLayoutingWindowFrames().mFrame);
        // Excluding the display cutout before set to the simulated content frame.
        contentFrame.intersect(displayFrames.mDisplayCutoutSafe);
        simulatedContentFrame.set(contentFrame);
    }

    private boolean canReceiveInput(WindowState win) {
        boolean notFocusable =
                (win.getAttrs().flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0;
        boolean altFocusableIm =
                (win.getAttrs().flags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0;
        boolean notFocusableForIm = notFocusable ^ altFocusableIm;
        return !notFocusableForIm;
    }

    /**
    /**
     * Called for each window attached to the window manager as layout is proceeding. The
     * Called for each window attached to the window manager as layout is proceeding. The
     * implementation of this function must take care of setting the window's frame, either here or
     * implementation of this function must take care of setting the window's frame, either here or
@@ -1514,51 +1471,37 @@ public class DisplayPolicy {
     * @param displayFrames The display frames.
     * @param displayFrames The display frames.
     */
     */
    public void layoutWindowLw(WindowState win, WindowState attached, DisplayFrames displayFrames) {
    public void layoutWindowLw(WindowState win, WindowState attached, DisplayFrames displayFrames) {
        final WindowManager.LayoutParams attrs = win.getLayoutingAttrs(displayFrames.mRotation);

        final int type = attrs.type;
        final int fl = attrs.flags;
        final int sim = attrs.softInputMode;


        // This window might be in the simulated environment.
        // We invoke this to get the proper DisplayFrames.
        displayFrames = win.getDisplayFrames(displayFrames);
        displayFrames = win.getDisplayFrames(displayFrames);
        final WindowFrames windowFrames = win.getLayoutingWindowFrames();


        final WindowManager.LayoutParams attrs = win.getLayoutingAttrs(displayFrames.mRotation);
        final WindowFrames windowFrames = win.getWindowFrames();
        final Rect pf = windowFrames.mParentFrame;
        final Rect pf = windowFrames.mParentFrame;
        final Rect df = windowFrames.mDisplayFrame;
        final Rect df = windowFrames.mDisplayFrame;
        final Rect f = windowFrames.mFrame;
        final Rect f = windowFrames.mFrame;
        final Rect attachedWindowFrame = attached != null ? attached.getFrame() : null;
        final Rect attachedWindowFrame = attached != null ? attached.getFrame() : null;
        sTmpLastParentFrame.set(pf);


        final Rect winBounds;
        // If this window has different LayoutParams for rotations, we cannot trust its requested
        final int requestedWidth;
        // size. Because it might have not sent its requested size for the new rotation.
        final int requestedHeight;
        final boolean trustedSize = attrs == win.mAttrs;
        if (windowFrames.mIsSimulatingDecorWindow) {
        final int requestedWidth = trustedSize ? win.mRequestedWidth : UNSPECIFIED_LENGTH;
            // Override the bounds in window token has many side effects. Directly use the display
        final int requestedHeight = trustedSize ? win.mRequestedHeight : UNSPECIFIED_LENGTH;
            // frame set for the simulated layout.

            winBounds = df;
        sTmpLastParentFrame.set(pf);

            // The view hierarchy has not been measured in the simulated layout. Use
            // UNSPECIFIED_LENGTH as the requested width and height so that WindowLayout will choose
            // the proper values in this case.
            requestedWidth = UNSPECIFIED_LENGTH;
            requestedHeight = UNSPECIFIED_LENGTH;
        } else {
            winBounds = win.getBounds();
            requestedWidth = win.mRequestedWidth;
            requestedHeight = win.mRequestedHeight;
        }


        final boolean clippedByDisplayCutout = mWindowLayout.computeWindowFrames(attrs,
        final boolean clippedByDisplayCutout = mWindowLayout.computeWindowFrames(attrs,
                win.getInsetsState(), displayFrames.mDisplayCutoutSafe,
                win.getInsetsState(), displayFrames.mDisplayCutoutSafe,
                winBounds, win.getWindowingMode(), requestedWidth, requestedHeight,
                win.getBounds(), win.getWindowingMode(), requestedWidth, requestedHeight,
                win.getRequestedVisibilities(), attachedWindowFrame, win.mGlobalScale,
                win.getRequestedVisibilities(), attachedWindowFrame, win.mGlobalScale,
                df, pf, f);
                df, pf, f);
        windowFrames.setParentFrameWasClippedByDisplayCutout(clippedByDisplayCutout);
        windowFrames.setParentFrameWasClippedByDisplayCutout(clippedByDisplayCutout);


        if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
        if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
                + ": sim=#" + Integer.toHexString(sim)
                + ": sim=#" + Integer.toHexString(attrs.softInputMode)
                + " attach=" + attached + " type=" + type
                + " attach=" + attached + " type=" + attrs.type
                + " flags=" + ViewDebug.flagsToString(LayoutParams.class, "flags", fl)
                + " flags=" + ViewDebug.flagsToString(LayoutParams.class, "flags", attrs.flags)
                + " pf=" + pf.toShortString() + " df=" + df.toShortString()
                + " pf=" + pf.toShortString() + " df=" + df.toShortString()
                + " f=" + f.toShortString());
                + " f=" + f.toShortString());


@@ -1566,10 +1509,8 @@ public class DisplayPolicy {
            windowFrames.setContentChanged(true);
            windowFrames.setContentChanged(true);
        }
        }


        if (!windowFrames.mIsSimulatingDecorWindow) {
        win.setFrame();
        win.setFrame();
    }
    }
    }


    WindowState getTopFullscreenOpaqueWindow() {
    WindowState getTopFullscreenOpaqueWindow() {
        return mTopFullscreenOpaqueWindowState;
        return mTopFullscreenOpaqueWindowState;
@@ -2510,22 +2451,22 @@ public class DisplayPolicy {
        return source != null && Rect.intersects(win.getFrame(), source.getFrame());
        return source != null && Rect.intersects(win.getFrame(), source.getFrame());
    }
    }


    private Rect getBarContentFrameForWindow(WindowState win, int windowType) {
    private Rect getBarContentFrameForWindow(WindowState win, @InternalInsetsType int type) {
        final Rect rotatedBarFrame = win.mToken.getFixedRotationBarContentFrame(windowType);
        final DisplayFrames displayFrames = win.getDisplayFrames(mDisplayContent.mDisplayFrames);
        if (rotatedBarFrame != null) {
        final InsetsState state = displayFrames.mInsetsState;
            return rotatedBarFrame;
        }
        // We only need a window specific information for the fixed rotation, use raw insets state
        // for all other cases.
        InsetsState insetsState = mDisplayContent.getInsetsStateController().getRawInsetsState();
        final Rect tmpRect = new Rect();
        final Rect tmpRect = new Rect();
        if (windowType == TYPE_NAVIGATION_BAR) {
        sTmpDisplayCutoutSafe.set(displayFrames.mDisplayCutoutSafe);
            tmpRect.set(insetsState.getSource(InsetsState.ITYPE_NAVIGATION_BAR).getFrame());
        if (type == ITYPE_STATUS_BAR) {
        }
            // The status bar content can extend into regular display cutout insets but not
        if (windowType == TYPE_STATUS_BAR) {
            // waterfall insets.
            tmpRect.set(insetsState.getSource(InsetsState.ITYPE_STATUS_BAR).getFrame());
            sTmpDisplayCutoutSafe.top =
                    Math.max(state.getDisplayCutout().getWaterfallInsets().top, 0);
        }
        final InsetsSource source = state.peekSource(type);
        if (source != null) {
            tmpRect.set(source.getFrame());
            tmpRect.intersect(sTmpDisplayCutoutSafe);
        }
        }
        tmpRect.intersect(mDisplayContent.mDisplayFrames.mDisplayCutoutSafe);
        return tmpRect;
        return tmpRect;
    }
    }


@@ -2539,11 +2480,11 @@ public class DisplayPolicy {
     * be drawn over letterboxed activity.
     * be drawn over letterboxed activity.
     */
     */
    @VisibleForTesting
    @VisibleForTesting
    boolean isFullyTransparentAllowed(WindowState win, int windowType) {
    boolean isFullyTransparentAllowed(WindowState win, @InternalInsetsType int type) {
        if (win == null) {
        if (win == null) {
            return true;
            return true;
        }
        }
        return win.isFullyTransparentBarAllowed(getBarContentFrameForWindow(win, windowType));
        return win.isFullyTransparentBarAllowed(getBarContentFrameForWindow(win, type));
    }
    }


    private boolean drawsBarBackground(WindowState win) {
    private boolean drawsBarBackground(WindowState win) {
@@ -2566,7 +2507,7 @@ public class DisplayPolicy {
        for (int i = mStatusBarBackgroundWindows.size() - 1; i >= 0; i--) {
        for (int i = mStatusBarBackgroundWindows.size() - 1; i >= 0; i--) {
            final WindowState window = mStatusBarBackgroundWindows.get(i);
            final WindowState window = mStatusBarBackgroundWindows.get(i);
            drawBackground &= drawsBarBackground(window);
            drawBackground &= drawsBarBackground(window);
            isFullyTransparentAllowed &= isFullyTransparentAllowed(window, TYPE_STATUS_BAR);
            isFullyTransparentAllowed &= isFullyTransparentAllowed(window, ITYPE_STATUS_BAR);
        }
        }


        if (drawBackground) {
        if (drawBackground) {
@@ -2606,7 +2547,7 @@ public class DisplayPolicy {
            }
            }
        }
        }


        if (!isFullyTransparentAllowed(mNavBarBackgroundWindow, TYPE_NAVIGATION_BAR)) {
        if (!isFullyTransparentAllowed(mNavBarBackgroundWindow, ITYPE_NAVIGATION_BAR)) {
            appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
            appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
        }
        }


+2 −2
Original line number Original line Diff line number Diff line
@@ -236,12 +236,12 @@ class InsetsSourceProvider {
    }
    }


    /** @return A new source computed by the specified window frame in the given display frames. */
    /** @return A new source computed by the specified window frame in the given display frames. */
    InsetsSource createSimulatedSource(DisplayFrames displayFrames, WindowFrames windowFrames) {
    InsetsSource createSimulatedSource(DisplayFrames displayFrames, Rect winFrame) {
        // Don't copy visible frame because it might not be calculated in the provided display
        // Don't copy visible frame because it might not be calculated in the provided display
        // frames and it is not significant for this usage.
        // frames and it is not significant for this usage.
        final InsetsSource source = new InsetsSource(mSource.getType());
        final InsetsSource source = new InsetsSource(mSource.getType());
        source.setVisible(mSource.isVisible());
        source.setVisible(mSource.isVisible());
        mTmpRect.set(windowFrames.mFrame);
        mTmpRect.set(winFrame);
        if (mFrameProvider != null) {
        if (mFrameProvider != null) {
            mFrameProvider.accept(displayFrames, mWin, mTmpRect);
            mFrameProvider.accept(displayFrames, mWin, mTmpRect);
        }
        }
+4 −4
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.app.WindowConfiguration;
import android.app.WindowConfiguration.WindowingMode;
import android.app.WindowConfiguration.WindowingMode;
import android.graphics.Rect;
import android.os.Trace;
import android.os.Trace;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
@@ -385,15 +386,14 @@ class InsetsStateController {
     *
     *
     * @param win The owner window of insets provider.
     * @param win The owner window of insets provider.
     * @param displayFrames The display frames to create insets source.
     * @param displayFrames The display frames to create insets source.
     * @param windowFrames The specified frames to represent the owner window.
     * @param winFrame The frame of the insets source window.
     */
     */
    void computeSimulatedState(WindowState win, DisplayFrames displayFrames,
    void computeSimulatedState(WindowState win, DisplayFrames displayFrames, Rect winFrame) {
            WindowFrames windowFrames) {
        final InsetsState state = displayFrames.mInsetsState;
        final InsetsState state = displayFrames.mInsetsState;
        for (int i = mProviders.size() - 1; i >= 0; i--) {
        for (int i = mProviders.size() - 1; i >= 0; i--) {
            final InsetsSourceProvider provider = mProviders.valueAt(i);
            final InsetsSourceProvider provider = mProviders.valueAt(i);
            if (provider.mWin == win) {
            if (provider.mWin == win) {
                state.addSource(provider.createSimulatedSource(displayFrames, windowFrames));
                state.addSource(provider.createSimulatedSource(displayFrames, winFrame));
            }
            }
        }
        }
    }
    }
+0 −5
Original line number Original line Diff line number Diff line
@@ -71,11 +71,6 @@ public class WindowFrames {
    // screen size compatibility mode.
    // screen size compatibility mode.
    final Rect mCompatFrame = new Rect();
    final Rect mCompatFrame = new Rect();


    /**
     * {@code true} if the window frame is a simulated frame and attached to a decor window.
     */
    boolean mIsSimulatingDecorWindow = false;

    /**
    /**
     * Whether the parent frame would have been different if there was no display cutout.
     * Whether the parent frame would have been different if there was no display cutout.
     */
     */
+3 −22
Original line number Original line Diff line number Diff line
@@ -466,9 +466,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP


    private final ClientWindowFrames mClientWindowFrames = new ClientWindowFrames();
    private final ClientWindowFrames mClientWindowFrames = new ClientWindowFrames();


    /** The frames used to compute a temporal layout appearance. */
    private WindowFrames mSimulatedWindowFrames;

    /**
    /**
     * List of rects where system gestures should be ignored.
     * List of rects where system gestures should be ignored.
     *
     *
@@ -1513,9 +1510,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP


    /** @return The display frames in use by this window. */
    /** @return The display frames in use by this window. */
    DisplayFrames getDisplayFrames(DisplayFrames originalFrames) {
    DisplayFrames getDisplayFrames(DisplayFrames originalFrames) {
        final DisplayFrames diplayFrames = mToken.getFixedRotationTransformDisplayFrames();
        final DisplayFrames displayFrames = mToken.getFixedRotationTransformDisplayFrames();
        if (diplayFrames != null) {
        if (displayFrames != null) {
            return diplayFrames;
            return displayFrames;
        }
        }
        return originalFrames;
        return originalFrames;
    }
    }
@@ -5502,22 +5499,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        return mWindowFrames;
        return mWindowFrames;
    }
    }


    /**
     * If the simulated frame is set, the computed result won't be used in real layout. So this
     * frames must be cleared when the simulated computation is done.
     */
    void setSimulatedWindowFrames(WindowFrames windowFrames) {
        mSimulatedWindowFrames = windowFrames;
    }

    /**
     * Use this method only when the simulated frames may be set, so it is clearer that the calling
     * path may be used to simulate layout.
     */
    WindowFrames getLayoutingWindowFrames() {
        return mSimulatedWindowFrames != null ? mSimulatedWindowFrames : mWindowFrames;
    }

    void resetContentChanged() {
    void resetContentChanged() {
        mWindowFrames.setContentChanged(false);
        mWindowFrames.setContentChanged(false);
    }
    }
Loading