Loading packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java +8 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java +7 −0 Original line number Diff line number Diff line Loading @@ -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; } } packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java +56 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -63,6 +70,7 @@ public class OverlayViewGlobalStateController { mCarNavigationBarController = carNavigationBarController; mZOrderMap = new HashMap<>(); mZOrderVisibleSortedMap = new TreeMap<>(); mViewsHiddenForOcclusion = new HashSet<>(); } /** Loading Loading @@ -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); } Loading Loading @@ -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()); Loading Loading @@ -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; Loading @@ -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()); } } packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java +13 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java +75 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java +8 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading
packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java +7 −0 Original line number Diff line number Diff line Loading @@ -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; } }
packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java +56 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -63,6 +70,7 @@ public class OverlayViewGlobalStateController { mCarNavigationBarController = carNavigationBarController; mZOrderMap = new HashMap<>(); mZOrderVisibleSortedMap = new TreeMap<>(); mViewsHiddenForOcclusion = new HashSet<>(); } /** Loading Loading @@ -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); } Loading Loading @@ -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()); Loading Loading @@ -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; Loading @@ -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()); } }
packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java +13 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading
packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java +75 −0 Original line number Diff line number Diff line Loading @@ -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); Loading