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

Commit 263f63f0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add occlusion logic to OverlayViewGlobalStateController and...

Merge "Add occlusion logic to OverlayViewGlobalStateController and CarKeyguardViewController" into rvc-dev am: 8920f765

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11635056

Change-Id: Id485c34052025828b89d76fd447493fac2ab3b0b
parents d07e7e46 8920f765
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -218,6 +218,14 @@ public class CarKeyguardViewController extends OverlayViewController implements
        }
    }

    @Override
    public void setOccluded(boolean occluded, boolean animate) {
        getOverlayViewGlobalStateController().setOccluded(occluded);
        if (!occluded) {
            reset(/* hideBouncerWhenShowing= */ false);
        }
    }

    @Override
    public void onCancelClicked() {
        if (mBouncer == null) return;
@@ -314,11 +322,6 @@ public class CarKeyguardViewController extends OverlayViewController implements
        // no-op
    }

    @Override
    public void setOccluded(boolean occluded, boolean animate) {
        // no-op
    }

    @Override
    public boolean shouldDisableWindowAnimationsForUnlock() {
        return false;
+7 −0
Original line number Diff line number Diff line
@@ -138,4 +138,11 @@ public class OverlayViewController {
    protected boolean shouldShowNavigationBar() {
        return false;
    }

    /**
     * Returns {@code true} if this view should be hidden during the occluded state.
     */
    protected boolean shouldShowWhenOccluded() {
        return false;
    }
}
+56 −0
Original line number Diff line number Diff line
@@ -24,7 +24,9 @@ import androidx.annotation.VisibleForTesting;
import com.android.systemui.car.navigationbar.CarNavigationBarController;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

@@ -47,11 +49,16 @@ public class OverlayViewGlobalStateController {
    private static final int UNKNOWN_Z_ORDER = -1;
    private final SystemUIOverlayWindowController mSystemUIOverlayWindowController;
    private final CarNavigationBarController mCarNavigationBarController;

    private boolean mIsOccluded;

    @VisibleForTesting
    Map<OverlayViewController, Integer> mZOrderMap;
    @VisibleForTesting
    SortedMap<Integer, OverlayViewController> mZOrderVisibleSortedMap;
    @VisibleForTesting
    Set<OverlayViewController> mViewsHiddenForOcclusion;
    @VisibleForTesting
    OverlayViewController mHighestZOrder;

    @Inject
@@ -63,6 +70,7 @@ public class OverlayViewGlobalStateController {
        mCarNavigationBarController = carNavigationBarController;
        mZOrderMap = new HashMap<>();
        mZOrderVisibleSortedMap = new TreeMap<>();
        mViewsHiddenForOcclusion = new HashSet<>();
    }

    /**
@@ -91,6 +99,10 @@ public class OverlayViewGlobalStateController {
     */
    public void showView(OverlayViewController viewController, @Nullable Runnable show) {
        debugLog();
        if (mIsOccluded && !viewController.shouldShowWhenOccluded()) {
            mViewsHiddenForOcclusion.add(viewController);
            return;
        }
        if (mZOrderVisibleSortedMap.isEmpty()) {
            setWindowVisible(true);
        }
@@ -147,6 +159,10 @@ public class OverlayViewGlobalStateController {
     */
    public void hideView(OverlayViewController viewController, @Nullable Runnable hide) {
        debugLog();
        if (mIsOccluded && mViewsHiddenForOcclusion.contains(viewController)) {
            mViewsHiddenForOcclusion.remove(viewController);
            return;
        }
        if (!viewController.isInflated()) {
            Log.d(TAG, "Content cannot be hidden since it isn't inflated: "
                    + viewController.getClass().getName());
@@ -240,6 +256,43 @@ public class OverlayViewGlobalStateController {
        return mZOrderVisibleSortedMap.isEmpty() || mHighestZOrder.shouldShowHUN();
    }

    /**
     * Set the OverlayViewWindow to be in occluded or unoccluded state. When OverlayViewWindow is
     * occluded, all views mounted to it that are not configured to be shown during occlusion will
     * be hidden.
     */
    public void setOccluded(boolean occluded) {
        if (occluded) {
            // Hide views before setting mIsOccluded to true so the regular hideView logic is used,
            // not the one used during occlusion.
            hideViewsForOcclusion();
            mIsOccluded = true;
        } else {
            mIsOccluded = false;
            // show views after setting mIsOccluded to false so the regular showView logic is used,
            // not the one used during occlusion.
            showViewsHiddenForOcclusion();
        }
    }

    private void hideViewsForOcclusion() {
        HashSet<OverlayViewController> viewsCurrentlyShowing = new HashSet<>(
                mZOrderVisibleSortedMap.values());
        viewsCurrentlyShowing.forEach(overlayController -> {
            if (!overlayController.shouldShowWhenOccluded()) {
                hideView(overlayController, overlayController::hideInternal);
                mViewsHiddenForOcclusion.add(overlayController);
            }
        });
    }

    private void showViewsHiddenForOcclusion() {
        mViewsHiddenForOcclusion.forEach(overlayViewController -> {
            showView(overlayViewController, overlayViewController::showInternal);
        });
        mViewsHiddenForOcclusion.clear();
    }

    private void debugLog() {
        if (!DEBUG) {
            return;
@@ -250,5 +303,8 @@ public class OverlayViewGlobalStateController {
        Log.d(TAG, "mZOrderVisibleSortedMap: " + mZOrderVisibleSortedMap);
        Log.d(TAG, "mZOrderMap.size(): " + mZOrderMap.size());
        Log.d(TAG, "mZOrderMap: " + mZOrderMap);
        Log.d(TAG, "mIsOccluded: " + mIsOccluded);
        Log.d(TAG, "mViewsHiddenForOcclusion: " + mViewsHiddenForOcclusion);
        Log.d(TAG, "mViewsHiddenForOcclusion.size(): " + mViewsHiddenForOcclusion.size());
    }
}
+13 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@@ -168,6 +169,18 @@ public class CarKeyguardViewControllerTest extends SysuiTestCase {
                any());
    }

    @Test
    public void setOccludedFalse_currentlyOccluded_bouncerReset() {
        when(mBouncer.isSecure()).thenReturn(true);
        mCarKeyguardViewController.show(/* options= */ null);
        mCarKeyguardViewController.setOccluded(/* occluded= */ true, /* animate= */ false);
        reset(mBouncer);

        mCarKeyguardViewController.setOccluded(/* occluded= */ false, /* animate= */ false);

        verify(mBouncer).show(/* resetSecuritySelection= */ true);
    }

    @Test
    public void onCancelClicked_callsCancelClickedListener() {
        when(mBouncer.isSecure()).thenReturn(true);
+75 −0
Original line number Diff line number Diff line
@@ -490,6 +490,81 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
        verify(mSystemUIOverlayWindowController).setWindowVisible(false);
    }

    @Test
    public void setOccludedTrue_viewToHideWhenOccludedVisible_viewHidden() {
        setupOverlayViewController1();
        setOverlayViewControllerAsShowing(mOverlayViewController1);
        when(mOverlayViewController1.shouldShowWhenOccluded()).thenReturn(false);

        mOverlayViewGlobalStateController.setOccluded(true);

        assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsValue(
                mOverlayViewController1)).isFalse();
    }

    @Test
    public void setOccludedTrue_viewToNotHideWhenOccludedVisible_viewShown() {
        setupOverlayViewController1();
        setOverlayViewControllerAsShowing(mOverlayViewController1);
        when(mOverlayViewController1.shouldShowWhenOccluded()).thenReturn(true);

        mOverlayViewGlobalStateController.setOccluded(true);

        assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsValue(
                mOverlayViewController1)).isTrue();
    }

    @Test
    public void hideViewAndThenSetOccludedTrue_viewHiddenForOcclusion_viewHiddenAfterOcclusion() {
        setupOverlayViewController1();
        setOverlayViewControllerAsShowing(mOverlayViewController1);
        when(mOverlayViewController1.shouldShowWhenOccluded()).thenReturn(false);
        mOverlayViewGlobalStateController.setOccluded(true);

        mOverlayViewGlobalStateController.hideView(mOverlayViewController1, /* runnable= */ null);
        mOverlayViewGlobalStateController.setOccluded(false);

        assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsValue(
                mOverlayViewController1)).isFalse();
    }

    @Test
    public void setOccludedTrueAndThenShowView_viewToNotHideForOcclusion_viewShown() {
        setupOverlayViewController1();
        when(mOverlayViewController1.shouldShowWhenOccluded()).thenReturn(true);

        mOverlayViewGlobalStateController.setOccluded(true);
        setOverlayViewControllerAsShowing(mOverlayViewController1);

        assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsValue(
                mOverlayViewController1)).isTrue();
    }

    @Test
    public void setOccludedTrueAndThenShowView_viewToHideForOcclusion_viewHidden() {
        setupOverlayViewController1();
        when(mOverlayViewController1.shouldShowWhenOccluded()).thenReturn(false);

        mOverlayViewGlobalStateController.setOccluded(true);
        setOverlayViewControllerAsShowing(mOverlayViewController1);

        assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsValue(
                mOverlayViewController1)).isFalse();
    }

    @Test
    public void setOccludedFalse_viewShownAfterSetOccludedTrue_viewToHideForOcclusion_viewShown() {
        setupOverlayViewController1();
        when(mOverlayViewController1.shouldShowWhenOccluded()).thenReturn(false);
        mOverlayViewGlobalStateController.setOccluded(true);
        setOverlayViewControllerAsShowing(mOverlayViewController1);

        mOverlayViewGlobalStateController.setOccluded(false);

        assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsValue(
                mOverlayViewController1)).isTrue();
    }

    @Test
    public void inflateView_notInflated_inflates() {
        when(mOverlayViewController2.isInflated()).thenReturn(false);