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

Commit eb5a5920 authored by Tiger Huang's avatar Tiger Huang
Browse files

Do not dispatch system UI visibility during traversal

Otherwise, mRecomputeGlobalAttributes set within the callbacks might be
cleared in the traversal.

This CL also prevents dispatching non-existing insets sources to the
client. For example, if a display doesn't have a navigation bar, the
insets state dispatched by window manager won't contain the navigation
bar source. So that WindowInsets.isVisible(ITYPE_NAVIGATION_BAR) returns
false on such display.

Fix: 155787445
Fix: 155796402
Test: atest WindowInsetsControllerTests InsetsAnimationControlImplTest
Change-Id: I3104191b34c08e14ffb31d7228c832a84629a97b
parent 28382c8f
Loading
Loading
Loading
Loading
+7 −11
Original line number Diff line number Diff line
@@ -567,11 +567,15 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
    private void updateState(InsetsState newState) {
        mState.setDisplayFrame(newState.getDisplayFrame());
        for (int i = newState.getSourcesCount() - 1; i >= 0; i--) {
            InsetsSource source = newState.sourceAt(i);
            getSourceConsumer(source.getType()).updateSource(source);
            final InsetsSource source = newState.sourceAt(i);
            final int type = source.getType();
            final InsetsSourceConsumer consumer = getSourceConsumer(type);
            consumer.updateSource(source);
            mHost.updateCompatSysUiVisibility(type, source.isVisible(),
                    consumer.getControl() != null);
        }
        for (int i = mState.getSourcesCount() - 1; i >= 0; i--) {
            InsetsSource source = mState.sourceAt(i);
            final InsetsSource source = mState.sourceAt(i);
            if (newState.peekSource(source.getType()) == null) {
                mState.removeSource(source.getType());
            }
@@ -1005,14 +1009,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        updateRequestedState();
    }

    /**
     * @see ViewRootImpl#updateCompatSysUiVisibility(int, boolean, boolean)
     */
    public void updateCompatSysUiVisibility(@InternalInsetsType int type, boolean visible,
            boolean hasControl) {
        mHost.updateCompatSysUiVisibility(type, visible, hasControl);
    }

    /**
     * Called when current window gains focus.
     */
+2 −10
Original line number Diff line number Diff line
@@ -200,20 +200,12 @@ public class InsetsSourceConsumer {
    }

    boolean applyLocalVisibilityOverride() {
        InsetsSource source = mState.peekSource(mType);
        final boolean isVisible = source != null && source.isVisible();
        final boolean hasControl = mSourceControl != null;

        // We still need to let the legacy app know the visibility change even if we don't have the
        // control.
        mController.updateCompatSysUiVisibility(
                mType, hasControl ? mRequestedVisible : isVisible, hasControl);

        // If we don't have control, we are not able to change the visibility.
        if (!hasControl) {
        if (mSourceControl == null) {
            return false;
        }
        if (isVisible == mRequestedVisible) {
        if (mState.getSource(mType).isVisible() == mRequestedVisible) {
            return false;
        }
        mState.getSource(mType).setVisible(mRequestedVisible);
+5 −4
Original line number Diff line number Diff line
@@ -1967,6 +1967,10 @@ public final class ViewRootImpl implements ViewParent,
            mCompatibleVisibilityInfo.globalVisibility =
                    (mCompatibleVisibilityInfo.globalVisibility & ~View.SYSTEM_UI_FLAG_LOW_PROFILE)
                            | (mAttachInfo.mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
            if (mDispatchedSystemUiVisibility != mCompatibleVisibilityInfo.globalVisibility) {
                mHandler.sendMessage(mHandler.obtainMessage(
                        MSG_DISPATCH_SYSTEM_UI_VISIBILITY, mCompatibleVisibilityInfo));
            }
            if (mAttachInfo.mKeepScreenOn != oldScreenOn
                    || mAttachInfo.mSystemUiVisibility != params.subtreeSystemUiVisibility
                    || mAttachInfo.mHasSystemUiListeners != params.hasSystemUiListeners) {
@@ -2020,7 +2024,7 @@ public final class ViewRootImpl implements ViewParent,
            info.globalVisibility |= systemUiFlag;
        }
        if (mDispatchedSystemUiVisibility != info.globalVisibility) {
            scheduleTraversals();
            mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPATCH_SYSTEM_UI_VISIBILITY, info));
        }
    }

@@ -2468,9 +2472,6 @@ public final class ViewRootImpl implements ViewParent,
            mAttachInfo.mForceReportNewAttributes = false;
            params = lp;
        }
        if (sNewInsetsMode == NEW_INSETS_MODE_FULL) {
            handleDispatchSystemUiVisibilityChanged(mCompatibleVisibilityInfo);
        }

        if (mFirst || mAttachInfo.mViewVisibilityChanged) {
            mAttachInfo.mViewVisibilityChanged = false;
+0 −5
Original line number Diff line number Diff line
@@ -26,11 +26,8 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -98,8 +95,6 @@ public class InsetsAnimationControlImplTest {
    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        doNothing().when(mMockController).updateCompatSysUiVisibility(
                anyInt(), anyBoolean(), anyBoolean());
        mTopLeash = new SurfaceControl.Builder(mSession)
                .setName("testSurface")
                .build();
+5 −4
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Display;
import android.view.InsetsState;
import android.view.InsetsSource;
import android.view.MagnificationSpec;
import android.view.Surface;
import android.view.Surface.OutOfResourcesException;
@@ -80,6 +80,7 @@ final class AccessibilityController {

    private final WindowManagerService mService;

    private static final Rect EMPTY_RECT = new Rect();
    private static final float[] sTempFloats = new float[9];

    public AccessibilityController(WindowManagerService service) {
@@ -1166,9 +1167,9 @@ final class AccessibilityController {
    }

    static Rect getNavBarInsets(DisplayContent displayContent) {
        final InsetsState insetsState =
                displayContent.getInsetsStateController().getRawInsetsState();
        return insetsState.getSource(ITYPE_NAVIGATION_BAR).getFrame();
        final InsetsSource source = displayContent.getInsetsStateController().getRawInsetsState()
                .peekSource(ITYPE_NAVIGATION_BAR);
        return source != null ? source.getFrame() : EMPTY_RECT;
    }

    /**
Loading