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

Commit 7ae38300 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Use consistent animation when forcibly hiding non system overlay

There are several non system overlay window types. When hiding the
windows with animation, their specified exit animations may be used.

This avoids ugly jump cut and inconsistent duration when these
windows are requested to be hidden.

Bug: 408215749
Flag: EXEMPT bugfix
Test: WindowManagerServiceTests testUpdateOverlayWindows_ \
      multipleWindowsRequestHiding_hideOverlaysWithAnyUids
Test: Show multiple windows with different overlay types and
      window animations by non system apps. Launch Settings
      and check the windows are fading out in a short time.
Change-Id: Ie7bb2663892d608715aa077e2170eae4c03a4e36
parent 55cba851
Loading
Loading
Loading
Loading
+13 −7
Original line number Diff line number Diff line
@@ -361,8 +361,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    private boolean mAppOpVisibility = true;

    boolean mPermanentlyHidden; // the window should never be shown again
    // This is a non-system overlay window that is currently force hidden.
    private boolean mForceHideNonSystemOverlayWindow;
    /** This is a non-system overlay window that is currently force hidden. */
    private boolean mIsForceHiddenNonSystemOverlayWindow;
    boolean mHidden = true;    // Used to determine if to show child windows.
    private boolean mDragResizing;
    private boolean mDragResizingChangeReported = true;
@@ -2910,7 +2910,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            // Being hidden due to owner package being suspended.
            return false;
        }
        if (mForceHideNonSystemOverlayWindow) {
        if (mIsForceHiddenNonSystemOverlayWindow) {
            // This is an alert window that is currently force hidden.
            return false;
        }
@@ -2987,6 +2987,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        return true;
    }

    boolean isForceHiddenNonSystemOverlayWindow() {
        return mIsForceHiddenNonSystemOverlayWindow;
    }

    void setForceHideNonSystemOverlayWindowIfNeeded(boolean forceHide) {
        final int baseType = getBaseType();
        if (mSession.mCanAddInternalSystemWindow
@@ -2999,10 +3003,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            return;
        }

        if (mForceHideNonSystemOverlayWindow == forceHide) {
        if (mIsForceHiddenNonSystemOverlayWindow == forceHide) {
            return;
        }
        mForceHideNonSystemOverlayWindow = forceHide;
        mIsForceHiddenNonSystemOverlayWindow = forceHide;
        if (forceHide) {
            hide(true /* doAnimation */, true /* requestAnim */);
        } else {
@@ -4010,7 +4014,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            }
        }
        if (!isVisibleByPolicy() || !mLegacyPolicyVisibilityAfterAnim || !mAppOpVisibility
                || isParentWindowHidden() || mPermanentlyHidden || mForceHideNonSystemOverlayWindow
                || isParentWindowHidden() || mPermanentlyHidden
                || mIsForceHiddenNonSystemOverlayWindow
                || mHiddenWhileSuspended) {
            pw.println(prefix + "mPolicyVisibility=" + isVisibleByPolicy()
                    + " mLegacyPolicyVisibilityAfterAnim=" + mLegacyPolicyVisibilityAfterAnim
@@ -4018,7 +4023,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                    + " parentHidden=" + isParentWindowHidden()
                    + " mPermanentlyHidden=" + mPermanentlyHidden
                    + " mHiddenWhileSuspended=" + mHiddenWhileSuspended
                    + " mForceHideNonSystemOverlayWindow=" + mForceHideNonSystemOverlayWindow);
                    + " mIsForceHiddenNonSystemOverlayWindow="
                    + mIsForceHiddenNonSystemOverlayWindow);
        }
        if (!mRelayoutCalled || mLayoutNeeded) {
            pw.println(prefix + "mRelayoutCalled=" + mRelayoutCalled
+5 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

@@ -529,6 +530,10 @@ class WindowStateAnimator {
                    a = AnimationUtils.loadAnimation(mContext, anim);
                    Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
                }
            } else if (!isEntrance && mWin.isForceHiddenNonSystemOverlayWindow()) {
                a = new AlphaAnimation(1f, 0f);
                a.setDuration(mContext.getResources().getInteger(
                        com.android.internal.R.integer.config_shortAnimTime));
            } else {
                switch (transit) {
                    case WindowManagerPolicy.TRANSIT_ENTER:
+10 −0
Original line number Diff line number Diff line
@@ -1418,6 +1418,7 @@ public class WindowManagerServiceTests extends WindowTestsBase {
    public void testUpdateOverlayWindows_multipleWindowsRequestHiding_hideOverlaysWithAnyUids() {
        WindowState overlayWindow = newWindowBuilder("overlay_window",
                TYPE_APPLICATION_OVERLAY).build();
        setFieldValue(overlayWindow.mSession, "mCanAddInternalSystemWindow", false);
        WindowState appWindow1 = newWindowBuilder("app_window_1", TYPE_APPLICATION).build();
        WindowState appWindow2 = newWindowBuilder("app_window_2", TYPE_APPLICATION).build();
        makeWindowVisible(appWindow1, appWindow2, overlayWindow);
@@ -1437,6 +1438,11 @@ public class WindowManagerServiceTests extends WindowTestsBase {
        mWm.updateNonSystemOverlayWindowsVisibilityIfNeeded(appWindow2, true);

        verify(overlayWindow).setForceHideNonSystemOverlayWindowIfNeeded(true);
        assertTrue(overlayWindow.isForceHiddenNonSystemOverlayWindow());
        assertNotNull(overlayWindow.getAnimation());
        assertEquals(mContext.getResources().getInteger(
                com.android.internal.R.integer.config_shortAnimTime),
                overlayWindow.getAnimation().getDurationHint());
    }

    @Test
@@ -1462,6 +1468,10 @@ public class WindowManagerServiceTests extends WindowTestsBase {
        doReturn(true).when(app2).hideNonSystemOverlayWindowsWhenVisible();

        makeWindowVisible(saw, app1, app2);
        spyOn(saw.mWinAnimator);
        // Disable animation so visibility policy flag can be set immediately to verify.
        doReturn(false).when(saw.mWinAnimator).applyAnimationLocked(
                anyInt(), anyBoolean());
        assertThat(saw.isVisibleByPolicy()).isTrue();

        // Two hideNonSystemOverlayWindows windows: SAW is hidden.