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

Commit 84cc5e32 authored by Filip Gruszczynski's avatar Filip Gruszczynski
Browse files

Split code out from WMS.realyoutWindow.

Change-Id: If57237013d87d864c219e5f6415de3d360cbbe75
parent adf0698b
Loading
Loading
Loading
Loading
+133 −172
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.StatusBarManager.DISABLE_MASK;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
@@ -31,8 +32,6 @@ import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHA
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -46,6 +45,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;

import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
@@ -2537,11 +2538,8 @@ public class WindowManagerService extends IWindowManager.Stub
            Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
            Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Configuration outConfig,
            Surface outSurface) {
        boolean toBeDisplayed = false;
        boolean inTouchMode;
        int result = 0;
        boolean configChanged;
        boolean surfaceChanged = false;
        boolean dragResizing = false;
        boolean hasStatusBarPermission =
                mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
                        == PackageManager.PERMISSION_GRANTED;
@@ -2558,31 +2556,21 @@ public class WindowManagerService extends IWindowManager.Stub
                win.setRequestedSize(requestedWidth, requestedHeight);
            }

            int attrChanges = 0;
            int flagChanges = 0;
            if (attrs != null) {
                mPolicy.adjustWindowParamsLw(attrs);
            }

                // if they don't have the permission, mask out the status bar bits
            int systemUiVisibility = 0;
            if (attrs != null) {
                systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
                if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
                if (seq == win.mSeq) {
                    int systemUiVisibility = attrs.systemUiVisibility
                            | attrs.subtreeSystemUiVisibility;
                    if ((systemUiVisibility & DISABLE_MASK) != 0) {
                        if (!hasStatusBarPermission) {
                        systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
                    }
                            systemUiVisibility &= ~DISABLE_MASK;
                        }
                    }

            if (attrs != null && seq == win.mSeq) {
                    win.mSystemUiVisibility = systemUiVisibility;
                }

            winAnimator.mSurfaceDestroyDeferred =
                    (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;

            int attrChanges = 0;
            int flagChanges = 0;
            if (attrs != null) {
                if (win.mAttrs.type != attrs.type) {
                    throw new IllegalArgumentException(
                            "Window type can not be changed after the window is added.");
@@ -2597,30 +2585,15 @@ public class WindowManagerService extends IWindowManager.Stub

            if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
                    + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);

            winAnimator.mSurfaceDestroyDeferred = (flags & RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
            win.mEnforceSizeCompat =
                    (win.mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0;

            if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
                winAnimator.mAlpha = attrs.alpha;
            }

            final boolean scaledWindow =
                ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);

            if (scaledWindow) {
                // requested{Width|Height} Surface's physical size
                // attrs.{width|height} Size on screen
                win.mHScale = (attrs.width  != requestedWidth)  ?
                        (attrs.width  / (float)requestedWidth) : 1.0f;
                win.mVScale = (attrs.height != requestedHeight) ?
                        (attrs.height / (float)requestedHeight) : 1.0f;
            } else {
                win.mHScale = win.mVScale = 1;
            }
            win.setWindowScale(requestedWidth, requestedHeight);

            boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;

            final boolean isDefaultDisplay = win.isDefaultDisplay();
            boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
                    || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
@@ -2644,78 +2617,10 @@ public class WindowManagerService extends IWindowManager.Stub
            }
            if (viewVisibility == View.VISIBLE &&
                    (win.mAppToken == null || !win.mAppToken.clientHidden)) {
                toBeDisplayed = !win.isVisibleLw();
                if (win.mExiting) {
                    winAnimator.cancelExitAnimationForNextAnimationLocked();
                    win.mExiting = false;
                }
                if (win.mDestroying) {
                    win.mDestroying = false;
                    mDestroySurface.remove(win);
                }
                if (oldVisibility == View.GONE) {
                    winAnimator.mEnterAnimationPending = true;
                }
                winAnimator.mEnteringAnimation = true;
                if (toBeDisplayed) {
                    if ((win.mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
                            == SOFT_INPUT_ADJUST_RESIZE) {
                        win.mLayoutNeeded = true;
                    }
                    if (win.isDrawnLw() && okToDisplay()) {
                        winAnimator.applyEnterAnimationLocked();
                    }
                    if ((win.mAttrs.flags
                            & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
                        if (DEBUG_VISIBILITY) Slog.v(TAG,
                                "Relayout window turning screen on: " + win);
                        win.mTurnOnScreen = true;
                    }
                    if (win.isConfigChanged()) {
                        if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win
                                + " visible with new config: " + mCurConfiguration);
                        outConfig.setTo(mCurConfiguration);
                    }
                }
                if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
                    // If the format can be changed in place yaay!
                    // If not, fall back to a surface re-build
                    if (!winAnimator.tryChangeFormatInPlaceLocked()) {
                        winAnimator.destroySurfaceLocked();
                        toBeDisplayed = true;
                        surfaceChanged = true;
                    }
                }

                // If we're starting a drag-resize, we'll be changing the surface size as well as
                // notifying the client to render to with an offset from the surface's top-left.
                if (win.isDragResizeChanged()) {
                    win.setDragResizing();
                    if (win.mHasSurface) {
                        winAnimator.preserveSurfaceLocked();
                        toBeDisplayed = true;
                    }
                }
                dragResizing = win.isDragResizing();
                if (win.isAnimatingWithSavedSurface()) {
                    // If we're animating with a saved surface now, request client to report draw.
                    // We still need to know when the real thing is drawn.
                    toBeDisplayed = true;
                }
                result = relayoutVisibleWindow(outConfig, result, win, winAnimator, attrChanges,
                        oldVisibility);
                try {
                    if (!win.mHasSurface) {
                        surfaceChanged = true;
                    }
                    SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
                    if (surfaceControl != null) {
                        outSurface.copyFrom(surfaceControl);
                        if (SHOW_TRANSACTIONS) Slog.i(TAG,
                                "  OUT SURFACE " + outSurface + ": copied");
                    } else {
                        // For some reason there isn't a surface.  Clear the
                        // caller's object so they see the same state.
                        outSurface.release();
                    }
                    result = createSurfaceControl(outSurface, result, win, winAnimator);
                } catch (Exception e) {
                    mInputMonitor.updateInputWindowsLw(true /*force*/);

@@ -2725,27 +2630,14 @@ public class WindowManagerService extends IWindowManager.Stub
                    Binder.restoreCallingIdentity(origId);
                    return 0;
                }
                if (toBeDisplayed) {
                if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
                    focusMayChange = isDefaultDisplay;
                }
                if (win.mAttrs.type == TYPE_INPUT_METHOD
                        && mInputMethodWindow == null) {
                if (win.mAttrs.type == TYPE_INPUT_METHOD && mInputMethodWindow == null) {
                    mInputMethodWindow = win;
                    imMayMove = true;
                }
                if (win.mAttrs.type == TYPE_BASE_APPLICATION
                        && win.mAppToken != null
                        && win.mAppToken.startingWindow != null) {
                    // Special handling of starting window over the base
                    // window of the app: propagate lock screen flags to it,
                    // to provide the correct semantics while starting.
                    final int mask =
                        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                        | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
                    WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
                    sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
                }
                win.adjustStartingWindowFlags();
            } else {
                winAnimator.mEnterAnimationPending = false;
                winAnimator.mEnteringAnimation = false;
@@ -2759,41 +2651,14 @@ public class WindowManagerService extends IWindowManager.Stub
                    // don't want to destroy the saved surface.
                    // If we are not currently running the exit animation, we
                    // need to see about starting one.
                    if (!win.mExiting && !win.isAnimatingWithSavedSurface()) {
                        surfaceChanged = true;
                        // Try starting an animation; if there isn't one, we
                        // can destroy the surface right away.
                        int transit = WindowManagerPolicy.TRANSIT_EXIT;
                        if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
                            transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
                        }
                        if (win.isWinVisibleLw() &&
                                winAnimator.applyAnimationLocked(transit, false)) {
                            focusMayChange = isDefaultDisplay;
                            win.mExiting = true;
                        } else if (win.mWinAnimator.isAnimating()) {
                            // Currently in a hide animation... turn this into
                            // an exit.
                            win.mExiting = true;
                        } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
                            // If the wallpaper is currently behind this
                            // window, we need to change both of them inside
                            // of a transaction to avoid artifacts.
                            win.mExiting = true;
                            win.mWinAnimator.mAnimating = true;
                        } else {
                            if (mInputMethodWindow == win) {
                                mInputMethodWindow = null;
                            }
                            if (!win.shouldSaveSurface()) {
                                winAnimator.destroySurfaceLocked();
                            }
                        }
                        //TODO (multidisplay): Magnification is supported only for the default
                        if (mAccessibilityController != null
                                && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
                            mAccessibilityController.onWindowTransitionLocked(win, transit);
                        }
                    final boolean notExitingOrAnimating =
                            !win.mExiting && !win.isAnimatingWithSavedSurface();
                    result |= notExitingOrAnimating
                            ? RELAYOUT_RES_SURFACE_CHANGED : 0;
                    if (notExitingOrAnimating) {
                        focusMayChange = tryStartingAnimation(win, winAnimator, isDefaultDisplay,
                                focusMayChange);

                    }
                }

@@ -2812,6 +2677,7 @@ public class WindowManagerService extends IWindowManager.Stub

            // updateFocusedWindowLocked() already assigned layers so we only need to
            // reassign them at this point if the IM window state gets shuffled
            boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
            if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) {
                // Little hack here -- we -should- be able to rely on the
                // function to return true if the IME has moved and needs
@@ -2855,7 +2721,7 @@ public class WindowManagerService extends IWindowManager.Stub
            if (localLOGV || DEBUG_FOCUS) Slog.v(
                TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);

            inTouchMode = mInTouchMode;
            result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0;

            mInputMonitor.updateInputWindowsLw(true /*force*/);

@@ -2867,13 +2733,108 @@ public class WindowManagerService extends IWindowManager.Stub
        if (configChanged) {
            sendNewConfiguration();
        }

        Binder.restoreCallingIdentity(origId);
        return result;
    }

    private boolean tryStartingAnimation(WindowState win, WindowStateAnimator winAnimator,
            boolean isDefaultDisplay, boolean focusMayChange) {
        // Try starting an animation; if there isn't one, we
        // can destroy the surface right away.
        int transit = WindowManagerPolicy.TRANSIT_EXIT;
        if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
            transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
        }
        if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
            focusMayChange = isDefaultDisplay;
            win.mExiting = true;
        } else if (win.mWinAnimator.isAnimating()) {
            // Currently in a hide animation... turn this into
            // an exit.
            win.mExiting = true;
        } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
            // If the wallpaper is currently behind this
            // window, we need to change both of them inside
            // of a transaction to avoid artifacts.
            win.mExiting = true;
            win.mWinAnimator.mAnimating = true;
        } else {
            if (mInputMethodWindow == win) {
                mInputMethodWindow = null;
            }
            if (!win.shouldSaveSurface()) {
                winAnimator.destroySurfaceLocked();
            }
        }
        //TODO (multidisplay): Magnification is supported only for the default
        if (mAccessibilityController != null
                && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
            mAccessibilityController.onWindowTransitionLocked(win, transit);
        }
        return focusMayChange;
    }

    private int createSurfaceControl(Surface outSurface, int result, WindowState win,
            WindowStateAnimator winAnimator) {
        if (!win.mHasSurface) {
            result |= RELAYOUT_RES_SURFACE_CHANGED;
        }
        SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
        if (surfaceControl != null) {
            outSurface.copyFrom(surfaceControl);
            if (SHOW_TRANSACTIONS) Slog.i(TAG, "  OUT SURFACE " + outSurface + ": copied");
        } else {
            // For some reason there isn't a surface.  Clear the
            // caller's object so they see the same state.
            outSurface.release();
        }
        return result;
    }

        return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
                | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
                | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
                | (dragResizing ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING : 0);
    private int relayoutVisibleWindow(Configuration outConfig, int result, WindowState win,
            WindowStateAnimator winAnimator, int attrChanges, int oldVisibility) {
        result |= !win.isVisibleLw() ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0;
        if (win.mExiting) {
            winAnimator.cancelExitAnimationForNextAnimationLocked();
            win.mExiting = false;
        }
        if (win.mDestroying) {
            win.mDestroying = false;
            mDestroySurface.remove(win);
        }
        if (oldVisibility == View.GONE) {
            winAnimator.mEnterAnimationPending = true;
        }
        winAnimator.mEnteringAnimation = true;
        if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
            win.prepareWindowToDisplayDuringRelayout(outConfig);
        }
        if ((attrChanges& LayoutParams.FORMAT_CHANGED) != 0) {
            // If the format can be changed in place yaay!
            // If not, fall back to a surface re-build
            if (!winAnimator.tryChangeFormatInPlaceLocked()) {
                winAnimator.destroySurfaceLocked();
                result |= RELAYOUT_RES_SURFACE_CHANGED
                        | WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
            }
        }

        // If we're starting a drag-resize, we'll be changing the surface size as well as
        // notifying the client to render to with an offset from the surface's top-left.
        if (win.isDragResizeChanged()) {
            win.setDragResizing();
            if (win.mHasSurface) {
                winAnimator.preserveSurfaceLocked();
                result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
            }
        }
        result |= win.isDragResizing() ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING : 0;
        if (win.isAnimatingWithSavedSurface()) {
            // If we're animating with a saved surface now, request client to report draw.
            // We still need to know when the real thing is drawn.
            result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
        }
        return result;
    }

    public void performDeferredDestroyWindow(Session session, IWindow client) {
+56 −1
Original line number Diff line number Diff line
@@ -18,12 +18,19 @@ package com.android.server.wm;

import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
@@ -606,7 +613,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
        final int ph = mContainingFrame.height();

        int w,h;
        if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) {
        if ((mAttrs.flags & FLAG_SCALED) != 0) {
            if (mAttrs.width < 0) {
                w = pw;
            } else if (mEnforceSizeCompat) {
@@ -1447,6 +1454,54 @@ final class WindowState implements WindowManagerPolicy.WindowState {
        }
    }

    void prepareWindowToDisplayDuringRelayout(Configuration outConfig) {
        if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
                == SOFT_INPUT_ADJUST_RESIZE) {
            mLayoutNeeded = true;
        }
        if (isDrawnLw() && mService.okToDisplay()) {
            mWinAnimator.applyEnterAnimationLocked();
        }
        if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) {
            if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this);
            mTurnOnScreen = true;
        }
        if (isConfigChanged()) {
            if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this + " visible with new config: "
                    + mService.mCurConfiguration);
            outConfig.setTo(mService.mCurConfiguration);
        }
    }

    void adjustStartingWindowFlags() {
        if (mAttrs.type == TYPE_BASE_APPLICATION && mAppToken != null
                && mAppToken.startingWindow != null) {
            // Special handling of starting window over the base
            // window of the app: propagate lock screen flags to it,
            // to provide the correct semantics while starting.
            final int mask = FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD
                    | FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
            WindowManager.LayoutParams sa = mAppToken.startingWindow.mAttrs;
            sa.flags = (sa.flags & ~mask) | (mAttrs.flags & mask);
        }
    }

    void setWindowScale(int requestedWidth, int requestedHeight) {
        final boolean scaledWindow = (mAttrs.flags & FLAG_SCALED) != 0;

        if (scaledWindow) {
            // requested{Width|Height} Surface's physical size
            // attrs.{width|height} Size on screen
            // TODO: We don't check if attrs != null here. Is it implicitly checked?
            mHScale = (mAttrs.width  != requestedWidth)  ?
                    (mAttrs.width  / (float)requestedWidth) : 1.0f;
            mVScale = (mAttrs.height != requestedHeight) ?
                    (mAttrs.height / (float)requestedHeight) : 1.0f;
        } else {
            mHScale = mVScale = 1;
        }
    }

    private class DeathRecipient implements IBinder.DeathRecipient {
        @Override
        public void binderDied() {