Merge "Add occlusion logic to OverlayViewGlobalStateController and CarKeyguardViewController" into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-06-03 04:12:06 +00:00
committed by Android (Google) Code Review
5 changed files with 159 additions and 5 deletions

View File

@@ -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 @Override
public void onCancelClicked() { public void onCancelClicked() {
if (mBouncer == null) return; if (mBouncer == null) return;
@@ -314,11 +322,6 @@ public class CarKeyguardViewController extends OverlayViewController implements
// no-op // no-op
} }
@Override
public void setOccluded(boolean occluded, boolean animate) {
// no-op
}
@Override @Override
public boolean shouldDisableWindowAnimationsForUnlock() { public boolean shouldDisableWindowAnimationsForUnlock() {
return false; return false;

View File

@@ -138,4 +138,11 @@ public class OverlayViewController {
protected boolean shouldShowNavigationBar() { protected boolean shouldShowNavigationBar() {
return false; return false;
} }
/**
* Returns {@code true} if this view should be hidden during the occluded state.
*/
protected boolean shouldShowWhenOccluded() {
return false;
}
} }

View File

@@ -24,7 +24,9 @@ import androidx.annotation.VisibleForTesting;
import com.android.systemui.car.navigationbar.CarNavigationBarController; import com.android.systemui.car.navigationbar.CarNavigationBarController;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
@@ -47,11 +49,16 @@ public class OverlayViewGlobalStateController {
private static final int UNKNOWN_Z_ORDER = -1; private static final int UNKNOWN_Z_ORDER = -1;
private final SystemUIOverlayWindowController mSystemUIOverlayWindowController; private final SystemUIOverlayWindowController mSystemUIOverlayWindowController;
private final CarNavigationBarController mCarNavigationBarController; private final CarNavigationBarController mCarNavigationBarController;
private boolean mIsOccluded;
@VisibleForTesting @VisibleForTesting
Map<OverlayViewController, Integer> mZOrderMap; Map<OverlayViewController, Integer> mZOrderMap;
@VisibleForTesting @VisibleForTesting
SortedMap<Integer, OverlayViewController> mZOrderVisibleSortedMap; SortedMap<Integer, OverlayViewController> mZOrderVisibleSortedMap;
@VisibleForTesting @VisibleForTesting
Set<OverlayViewController> mViewsHiddenForOcclusion;
@VisibleForTesting
OverlayViewController mHighestZOrder; OverlayViewController mHighestZOrder;
@Inject @Inject
@@ -63,6 +70,7 @@ public class OverlayViewGlobalStateController {
mCarNavigationBarController = carNavigationBarController; mCarNavigationBarController = carNavigationBarController;
mZOrderMap = new HashMap<>(); mZOrderMap = new HashMap<>();
mZOrderVisibleSortedMap = new TreeMap<>(); mZOrderVisibleSortedMap = new TreeMap<>();
mViewsHiddenForOcclusion = new HashSet<>();
} }
/** /**
@@ -91,6 +99,10 @@ public class OverlayViewGlobalStateController {
*/ */
public void showView(OverlayViewController viewController, @Nullable Runnable show) { public void showView(OverlayViewController viewController, @Nullable Runnable show) {
debugLog(); debugLog();
if (mIsOccluded && !viewController.shouldShowWhenOccluded()) {
mViewsHiddenForOcclusion.add(viewController);
return;
}
if (mZOrderVisibleSortedMap.isEmpty()) { if (mZOrderVisibleSortedMap.isEmpty()) {
setWindowVisible(true); setWindowVisible(true);
} }
@@ -147,6 +159,10 @@ public class OverlayViewGlobalStateController {
*/ */
public void hideView(OverlayViewController viewController, @Nullable Runnable hide) { public void hideView(OverlayViewController viewController, @Nullable Runnable hide) {
debugLog(); debugLog();
if (mIsOccluded && mViewsHiddenForOcclusion.contains(viewController)) {
mViewsHiddenForOcclusion.remove(viewController);
return;
}
if (!viewController.isInflated()) { if (!viewController.isInflated()) {
Log.d(TAG, "Content cannot be hidden since it isn't inflated: " Log.d(TAG, "Content cannot be hidden since it isn't inflated: "
+ viewController.getClass().getName()); + viewController.getClass().getName());
@@ -240,6 +256,43 @@ public class OverlayViewGlobalStateController {
return mZOrderVisibleSortedMap.isEmpty() || mHighestZOrder.shouldShowHUN(); 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() { private void debugLog() {
if (!DEBUG) { if (!DEBUG) {
return; return;
@@ -250,5 +303,8 @@ public class OverlayViewGlobalStateController {
Log.d(TAG, "mZOrderVisibleSortedMap: " + mZOrderVisibleSortedMap); Log.d(TAG, "mZOrderVisibleSortedMap: " + mZOrderVisibleSortedMap);
Log.d(TAG, "mZOrderMap.size(): " + mZOrderMap.size()); Log.d(TAG, "mZOrderMap.size(): " + mZOrderMap.size());
Log.d(TAG, "mZOrderMap: " + mZOrderMap); Log.d(TAG, "mZOrderMap: " + mZOrderMap);
Log.d(TAG, "mIsOccluded: " + mIsOccluded);
Log.d(TAG, "mViewsHiddenForOcclusion: " + mViewsHiddenForOcclusion);
Log.d(TAG, "mViewsHiddenForOcclusion.size(): " + mViewsHiddenForOcclusion.size());
} }
} }

View File

@@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -168,6 +169,18 @@ public class CarKeyguardViewControllerTest extends SysuiTestCase {
any()); 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 @Test
public void onCancelClicked_callsCancelClickedListener() { public void onCancelClicked_callsCancelClickedListener() {
when(mBouncer.isSecure()).thenReturn(true); when(mBouncer.isSecure()).thenReturn(true);

View File

@@ -490,6 +490,81 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
verify(mSystemUIOverlayWindowController).setWindowVisible(false); 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 @Test
public void inflateView_notInflated_inflates() { public void inflateView_notInflated_inflates() {
when(mOverlayViewController2.isInflated()).thenReturn(false); when(mOverlayViewController2.isInflated()).thenReturn(false);