Merge "Allow HUNs to be shown over Overlay Window." into rvc-dev am: 4785a0669a

Change-Id: Id47de9075e5858cfe5c72d755ed0fb2ac3152522
This commit is contained in:
Abhijoy Saha
2020-05-07 00:32:25 +00:00
committed by Automerger Merge Worker
11 changed files with 646 additions and 203 deletions

View File

@@ -73,7 +73,7 @@ public class CarNavigationBarController {
}
/**
* Hides all navigation bars.
* Hides all system bars.
*/
public void hideBars() {
if (mTopView != null) {
@@ -85,7 +85,7 @@ public class CarNavigationBarController {
}
/**
* Shows all navigation bars.
* Shows all system bars.
*/
public void showBars() {
if (mTopView != null) {

View File

@@ -29,41 +29,40 @@ import android.widget.FrameLayout;
import com.android.car.notification.R;
import com.android.car.notification.headsup.CarHeadsUpNotificationContainer;
import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.car.window.OverlayViewGlobalStateController;
import com.android.systemui.dagger.qualifiers.Main;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Lazy;
/**
* A controller for SysUI's HUN display.
*/
@Singleton
public class CarHeadsUpNotificationSystemContainer implements CarHeadsUpNotificationContainer {
private final CarDeviceProvisionedController mCarDeviceProvisionedController;
private final Lazy<NotificationPanelViewController> mNotificationPanelViewControllerLazy;
private final OverlayViewGlobalStateController mOverlayViewGlobalStateController;
private final ViewGroup mWindow;
private final FrameLayout mHeadsUpContentFrame;
private final boolean mEnableHeadsUpNotificationWhenNotificationShadeOpen;
@Inject
CarHeadsUpNotificationSystemContainer(Context context,
@Main Resources resources,
CarDeviceProvisionedController deviceProvisionedController,
WindowManager windowManager,
Lazy<NotificationPanelViewController> notificationPanelViewControllerLazy) {
OverlayViewGlobalStateController overlayViewGlobalStateController) {
mCarDeviceProvisionedController = deviceProvisionedController;
mNotificationPanelViewControllerLazy = notificationPanelViewControllerLazy;
mOverlayViewGlobalStateController = overlayViewGlobalStateController;
boolean showOnBottom = resources.getBoolean(R.bool.config_showHeadsUpNotificationOnBottom);
// Use TYPE_STATUS_BAR_SUB_PANEL window type since we need to find a window that is above
// status bar but below navigation bar.
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
@@ -78,15 +77,11 @@ public class CarHeadsUpNotificationSystemContainer implements CarHeadsUpNotifica
windowManager.addView(mWindow, lp);
mWindow.setVisibility(View.INVISIBLE);
mHeadsUpContentFrame = mWindow.findViewById(R.id.headsup_content);
mEnableHeadsUpNotificationWhenNotificationShadeOpen = resources.getBoolean(
R.bool.config_enableHeadsUpNotificationWhenNotificationShadeOpen);
}
private void animateShow() {
if ((mEnableHeadsUpNotificationWhenNotificationShadeOpen
|| !mNotificationPanelViewControllerLazy.get().isPanelExpanded())
&& mCarDeviceProvisionedController.isCurrentUserFullySetup()) {
if (mCarDeviceProvisionedController.isCurrentUserFullySetup()
&& mOverlayViewGlobalStateController.shouldShowHUN()) {
mWindow.setVisibility(View.VISIBLE);
}
}

View File

@@ -73,6 +73,7 @@ public class NotificationPanelViewController extends OverlayPanelViewController
private final CarNotificationListener mCarNotificationListener;
private final NotificationClickHandlerFactory mNotificationClickHandlerFactory;
private final StatusBarStateController mStatusBarStateController;
private final boolean mEnableHeadsUpNotificationWhenNotificationShadeOpen;
private float mInitialBackgroundAlpha;
private float mBackgroundAlphaDiff;
@@ -144,6 +145,10 @@ public class NotificationPanelViewController extends OverlayPanelViewController
+ " percentage");
}
mBackgroundAlphaDiff = finalBackgroundAlpha - mInitialBackgroundAlpha;
mEnableHeadsUpNotificationWhenNotificationShadeOpen = mResources.getBoolean(
com.android.car.notification.R.bool
.config_enableHeadsUpNotificationWhenNotificationShadeOpen);
}
@Override
@@ -151,6 +156,16 @@ public class NotificationPanelViewController extends OverlayPanelViewController
reinflate();
}
@Override
protected boolean shouldShowNavigationBar() {
return true;
}
@Override
protected boolean shouldShowHUN() {
return mEnableHeadsUpNotificationWhenNotificationShadeOpen;
}
/** Reinflates the view. */
public void reinflate() {
ViewGroup container = (ViewGroup) getLayout();

View File

@@ -375,10 +375,10 @@ public abstract class OverlayPanelViewController extends OverlayViewController {
}
if (visible && !getOverlayViewGlobalStateController().isWindowVisible()) {
getOverlayViewGlobalStateController().setWindowVisible(true);
getOverlayViewGlobalStateController().showView(/* panelViewController= */ this);
}
if (!visible && getOverlayViewGlobalStateController().isWindowVisible()) {
getOverlayViewGlobalStateController().setWindowVisible(false);
getOverlayViewGlobalStateController().hideView(/* panelViewController= */ this);
}
getLayout().setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
getOverlayViewGlobalStateController().setWindowFocusable(visible);

View File

@@ -54,7 +54,6 @@ public class OverlayViewController {
mOverlayViewGlobalStateController.hideView(/* viewController= */ this, this::hide);
}
/**
* Inflate layout owned by controller.
*/
@@ -72,7 +71,7 @@ public class OverlayViewController {
}
/**
* Returns [@code true} if layout owned by controller has been inflated.
* Returns {@code true} if layout owned by controller has been inflated.
*/
public final boolean isInflated() {
return mLayout != null;
@@ -125,4 +124,18 @@ public class OverlayViewController {
protected final OverlayViewGlobalStateController getOverlayViewGlobalStateController() {
return mOverlayViewGlobalStateController;
}
/**
* Returns {@code true} if heads up notifications should be displayed over this view.
*/
protected boolean shouldShowHUN() {
return true;
}
/**
* Returns {@code true} if navigation bar should be displayed over this view.
*/
protected boolean shouldShowNavigationBar() {
return false;
}
}

View File

@@ -16,14 +16,17 @@
package com.android.systemui.car.window;
import android.annotation.Nullable;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import com.android.systemui.car.navigationbar.CarNavigationBarController;
import java.util.HashSet;
import java.util.Set;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -39,11 +42,17 @@ import javax.inject.Singleton;
*/
@Singleton
public class OverlayViewGlobalStateController {
private static final boolean DEBUG = false;
private static final String TAG = OverlayViewGlobalStateController.class.getSimpleName();
private static final int UNKNOWN_Z_ORDER = -1;
private final SystemUIOverlayWindowController mSystemUIOverlayWindowController;
private final CarNavigationBarController mCarNavigationBarController;
@VisibleForTesting
Set<String> mShownSet;
Map<OverlayViewController, Integer> mZOrderMap;
@VisibleForTesting
SortedMap<Integer, OverlayViewController> mZOrderVisibleSortedMap;
@VisibleForTesting
OverlayViewController mHighestZOrder;
@Inject
public OverlayViewGlobalStateController(
@@ -52,7 +61,8 @@ public class OverlayViewGlobalStateController {
mSystemUIOverlayWindowController = systemUIOverlayWindowController;
mSystemUIOverlayWindowController.attach();
mCarNavigationBarController = carNavigationBarController;
mShownSet = new HashSet<>();
mZOrderMap = new HashMap<>();
mZOrderVisibleSortedMap = new TreeMap<>();
}
/**
@@ -66,51 +76,127 @@ public class OverlayViewGlobalStateController {
}
/**
* Show content in Overlay Window.
* Show content in Overlay Window using {@link OverlayPanelViewController}.
*
* This calls {@link OverlayViewGlobalStateController#showView(OverlayViewController, Runnable)}
* where the runnable is nullified since the actual showing of the panel is handled by the
* controller itself.
*/
public void showView(OverlayViewController viewController, Runnable show) {
if (mShownSet.isEmpty()) {
mCarNavigationBarController.hideBars();
setWindowVisible(true);
}
inflateView(viewController);
show.run();
mShownSet.add(viewController.getClass().getName());
Log.d(TAG, "Content shown: " + viewController.getClass().getName());
public void showView(OverlayPanelViewController panelViewController) {
showView(panelViewController, /* show= */ null);
}
/**
* Hide content in Overlay Window.
* Show content in Overlay Window using {@link OverlayViewController}.
*/
public void hideView(OverlayViewController viewController, Runnable hide) {
public void showView(OverlayViewController viewController, @Nullable Runnable show) {
debugLog();
if (mZOrderVisibleSortedMap.isEmpty()) {
setWindowVisible(true);
}
if (!(viewController instanceof OverlayPanelViewController)) {
inflateView(viewController);
}
if (show != null) {
show.run();
}
updateInternalsWhenShowingView(viewController);
refreshNavigationBarVisibility();
Log.d(TAG, "Content shown: " + viewController.getClass().getName());
debugLog();
}
private void updateInternalsWhenShowingView(OverlayViewController viewController) {
int zOrder;
if (mZOrderMap.containsKey(viewController)) {
zOrder = mZOrderMap.get(viewController);
} else {
zOrder = mSystemUIOverlayWindowController.getBaseLayout().indexOfChild(
viewController.getLayout());
mZOrderMap.put(viewController, zOrder);
}
mZOrderVisibleSortedMap.put(zOrder, viewController);
refreshHighestZOrderWhenShowingView(viewController);
}
private void refreshHighestZOrderWhenShowingView(OverlayViewController viewController) {
if (mZOrderMap.getOrDefault(mHighestZOrder, UNKNOWN_Z_ORDER) < mZOrderMap.get(
viewController)) {
mHighestZOrder = viewController;
}
}
/**
* Hide content in Overlay Window using {@link OverlayPanelViewController}.
*
* This calls {@link OverlayViewGlobalStateController#hideView(OverlayViewController, Runnable)}
* where the runnable is nullified since the actual hiding of the panel is handled by the
* controller itself.
*/
public void hideView(OverlayPanelViewController panelViewController) {
hideView(panelViewController, /* hide= */ null);
}
/**
* Hide content in Overlay Window using {@link OverlayViewController}.
*/
public void hideView(OverlayViewController viewController, @Nullable Runnable hide) {
debugLog();
if (!viewController.isInflated()) {
Log.d(TAG, "Content cannot be hidden since it isn't inflated: "
+ viewController.getClass().getName());
return;
}
if (!mShownSet.contains(viewController.getClass().getName())) {
Log.d(TAG, "Content cannot be hidden since it isn't shown: "
if (!mZOrderMap.containsKey(viewController)) {
Log.d(TAG, "Content cannot be hidden since it has never been shown: "
+ viewController.getClass().getName());
return;
}
if (!mZOrderVisibleSortedMap.containsKey(mZOrderMap.get(viewController))) {
Log.d(TAG, "Content cannot be hidden since it isn't currently shown: "
+ viewController.getClass().getName());
return;
}
hide.run();
mShownSet.remove(viewController.getClass().getName());
if (hide != null) {
hide.run();
}
if (mShownSet.isEmpty()) {
mCarNavigationBarController.showBars();
mZOrderVisibleSortedMap.remove(mZOrderMap.get(viewController));
refreshHighestZOrderWhenHidingView(viewController);
refreshNavigationBarVisibility();
if (mZOrderVisibleSortedMap.isEmpty()) {
setWindowVisible(false);
}
Log.d(TAG, "Content hidden: " + viewController.getClass().getName());
debugLog();
}
/** Sets the window visibility state. */
public void setWindowVisible(boolean expanded) {
mSystemUIOverlayWindowController.setWindowVisible(expanded);
private void refreshHighestZOrderWhenHidingView(OverlayViewController viewController) {
if (mZOrderVisibleSortedMap.isEmpty()) {
mHighestZOrder = null;
return;
}
if (!mHighestZOrder.equals(viewController)) {
return;
}
mHighestZOrder = mZOrderVisibleSortedMap.get(mZOrderVisibleSortedMap.lastKey());
}
private void refreshNavigationBarVisibility() {
if (mZOrderVisibleSortedMap.isEmpty() || mHighestZOrder.shouldShowNavigationBar()) {
mCarNavigationBarController.showBars();
} else {
mCarNavigationBarController.hideBars();
}
}
/** Returns {@code true} is the window is visible. */
@@ -118,13 +204,14 @@ public class OverlayViewGlobalStateController {
return mSystemUIOverlayWindowController.isWindowVisible();
}
/** Sets the focusable flag of the sysui overlawy window. */
public void setWindowFocusable(boolean focusable) {
mSystemUIOverlayWindowController.setWindowFocusable(focusable);
private void setWindowVisible(boolean visible) {
mSystemUIOverlayWindowController.setWindowVisible(visible);
}
/** Sets the {@link android.view.WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM} flag of the
* sysui overlay window */
/**
* Sets the {@link android.view.WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM} flag of the
* sysui overlay window.
*/
public void setWindowNeedsInput(boolean needsInput) {
mSystemUIOverlayWindowController.setWindowNeedsInput(needsInput);
}
@@ -134,10 +221,34 @@ public class OverlayViewGlobalStateController {
return mSystemUIOverlayWindowController.isWindowFocusable();
}
/** Sets the focusable flag of the sysui overlawy window. */
public void setWindowFocusable(boolean focusable) {
mSystemUIOverlayWindowController.setWindowFocusable(focusable);
}
/** Inflates the view controlled by the given view controller. */
public void inflateView(OverlayViewController viewController) {
if (!viewController.isInflated()) {
viewController.inflate(mSystemUIOverlayWindowController.getBaseLayout());
}
}
/**
* Return {@code true} if OverlayWindow is in a state where HUNs should be displayed above it.
*/
public boolean shouldShowHUN() {
return mZOrderVisibleSortedMap.isEmpty() || mHighestZOrder.shouldShowHUN();
}
private void debugLog() {
if (!DEBUG) {
return;
}
Log.d(TAG, "mHighestZOrder: " + mHighestZOrder);
Log.d(TAG, "mZOrderVisibleSortedMap.size(): " + mZOrderVisibleSortedMap.size());
Log.d(TAG, "mZOrderVisibleSortedMap: " + mZOrderVisibleSortedMap);
Log.d(TAG, "mZOrderMap.size(): " + mZOrderMap.size());
Log.d(TAG, "mZOrderMap: " + mZOrderMap);
}
}

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!-- Fullscreen views in sysui should be listed here in increasing Z order. -->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewStub android:id="@+id/overlay_view_controller_stub_1"
android:inflatedId="@+id/overlay_view_controller_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="@layout/overlay_view_controller_stub"/>
<ViewStub android:id="@+id/overlay_view_controller_stub_2"
android:inflatedId="@+id/overlay_view_controller_2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="@layout/overlay_view_controller_stub"/>
<ViewStub android:id="@+id/overlay_view_controller_stub_3"
android:inflatedId="@+id/overlay_view_controller_3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="@layout/overlay_view_controller_stub"/>
</FrameLayout>

View File

@@ -16,9 +16,10 @@
package com.android.systemui.car.keyguard;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
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.verify;
@@ -29,7 +30,6 @@ import android.os.Handler;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.internal.widget.LockPatternUtils;
@@ -40,7 +40,6 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.car.navigationbar.CarNavigationBarController;
import com.android.systemui.car.window.OverlayViewGlobalStateController;
import com.android.systemui.car.window.SystemUIOverlayWindowController;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
@@ -51,6 +50,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -61,28 +61,20 @@ import dagger.Lazy;
public class CarKeyguardViewControllerTest extends SysuiTestCase {
private TestableCarKeyguardViewController mCarKeyguardViewController;
private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
private ViewGroup mBaseLayout;
@Mock
private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
@Mock
private KeyguardBouncer mBouncer;
@Mock
private CarNavigationBarController mCarNavigationBarController;
@Mock
private SystemUIOverlayWindowController mSystemUIOverlayWindowController;
@Mock
private CarKeyguardViewController.OnKeyguardCancelClickedListener mCancelClickedListener;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mOverlayViewGlobalStateController = new OverlayViewGlobalStateController(
mCarNavigationBarController, mSystemUIOverlayWindowController);
mBaseLayout = (ViewGroup) LayoutInflater.from(mContext).inflate(
R.layout.sysui_overlay_window, /* root= */ null);
when(mSystemUIOverlayWindowController.getBaseLayout()).thenReturn(mBaseLayout);
mCarKeyguardViewController = new TestableCarKeyguardViewController(
mContext,
Handler.getMain(),
@@ -98,6 +90,8 @@ public class CarKeyguardViewControllerTest extends SysuiTestCase {
mock(FalsingManager.class),
() -> mock(KeyguardBypassController.class)
);
mCarKeyguardViewController.inflate((ViewGroup) LayoutInflater.from(mContext).inflate(
R.layout.sysui_overlay_window, /* root= */ null));
}
@Test
@@ -113,8 +107,7 @@ public class CarKeyguardViewControllerTest extends SysuiTestCase {
when(mBouncer.isSecure()).thenReturn(true);
mCarKeyguardViewController.show(/* options= */ null);
assertThat(mBaseLayout.findViewById(R.id.keyguard_container).getVisibility()).isEqualTo(
View.VISIBLE);
verify(mOverlayViewGlobalStateController).showView(eq(mCarKeyguardViewController), any());
}
@Test
@@ -130,8 +123,17 @@ public class CarKeyguardViewControllerTest extends SysuiTestCase {
when(mBouncer.isSecure()).thenReturn(false);
mCarKeyguardViewController.show(/* options= */ null);
assertThat(mBaseLayout.findViewById(R.id.keyguard_container).getVisibility()).isEqualTo(
View.GONE);
// Here we check for both showView and hideView since the current implementation of show
// with bouncer being not secure has the following method execution orders:
// 1) show -> start -> showView
// 2) show -> reset -> dismissAndCollapse -> hide -> stop -> hideView
// Hence, we want to make sure that showView is called before hideView and not in any
// other combination.
InOrder inOrder = inOrder(mOverlayViewGlobalStateController);
inOrder.verify(mOverlayViewGlobalStateController).showView(eq(mCarKeyguardViewController),
any());
inOrder.verify(mOverlayViewGlobalStateController).hideView(eq(mCarKeyguardViewController),
any());
}
@Test
@@ -156,8 +158,11 @@ public class CarKeyguardViewControllerTest extends SysuiTestCase {
mCarKeyguardViewController.show(/* options= */ null);
mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0);
assertThat(mBaseLayout.findViewById(R.id.keyguard_container).getVisibility()).isEqualTo(
View.GONE);
InOrder inOrder = inOrder(mOverlayViewGlobalStateController);
inOrder.verify(mOverlayViewGlobalStateController).showView(eq(mCarKeyguardViewController),
any());
inOrder.verify(mOverlayViewGlobalStateController).hideView(eq(mCarKeyguardViewController),
any());
}
@Test

View File

@@ -28,9 +28,9 @@ import android.view.WindowManager;
import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.car.window.OverlayViewGlobalStateController;
import org.junit.Before;
import org.junit.Test;
@@ -42,12 +42,11 @@ import org.mockito.MockitoAnnotations;
@TestableLooper.RunWithLooper
@SmallTest
public class CarHeadsUpNotificationSystemContainerTest extends SysuiTestCase {
private CarHeadsUpNotificationSystemContainer mDefaultController;
private CarHeadsUpNotificationSystemContainer mOverrideEnabledController;
private CarHeadsUpNotificationSystemContainer mCarHeadsUpNotificationSystemContainer;
@Mock
private CarDeviceProvisionedController mCarDeviceProvisionedController;
@Mock
private NotificationPanelViewController mNotificationPanelViewController;
private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
@Mock
private WindowManager mWindowManager;
@@ -58,76 +57,63 @@ public class CarHeadsUpNotificationSystemContainerTest extends SysuiTestCase {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
MockitoAnnotations.initMocks(/* testClass= */this);
when(mNotificationPanelViewController.isPanelExpanded()).thenReturn(false);
when(mCarDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
when(mCarDeviceProvisionedController.isCurrentUserSetupInProgress()).thenReturn(false);
when(mOverlayViewGlobalStateController.shouldShowHUN()).thenReturn(true);
when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(true);
TestableResources testableResources = mContext.getOrCreateTestableResources();
testableResources.addOverride(
R.bool.config_enableHeadsUpNotificationWhenNotificationShadeOpen, false);
mDefaultController = new CarHeadsUpNotificationSystemContainer(mContext,
mCarHeadsUpNotificationSystemContainer = new CarHeadsUpNotificationSystemContainer(mContext,
testableResources.getResources(), mCarDeviceProvisionedController, mWindowManager,
() -> mNotificationPanelViewController);
testableResources.addOverride(
R.bool.config_enableHeadsUpNotificationWhenNotificationShadeOpen, true);
mOverrideEnabledController = new CarHeadsUpNotificationSystemContainer(mContext,
testableResources.getResources(), mCarDeviceProvisionedController, mWindowManager,
() -> mNotificationPanelViewController);
mOverlayViewGlobalStateController);
}
@Test
public void testDisplayNotification_firstNotification_isVisible() {
mDefaultController.displayNotification(mNotificationView);
assertThat(mDefaultController.isVisible()).isTrue();
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
}
@Test
public void testRemoveNotification_lastNotification_isInvisible() {
mDefaultController.displayNotification(mNotificationView);
mDefaultController.removeNotification(mNotificationView);
assertThat(mDefaultController.isVisible()).isFalse();
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
mCarHeadsUpNotificationSystemContainer.removeNotification(mNotificationView);
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isFalse();
}
@Test
public void testRemoveNotification_nonLastNotification_isVisible() {
mDefaultController.displayNotification(mNotificationView);
mDefaultController.displayNotification(mNotificationView2);
mDefaultController.removeNotification(mNotificationView);
assertThat(mDefaultController.isVisible()).isTrue();
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView2);
mCarHeadsUpNotificationSystemContainer.removeNotification(mNotificationView);
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
}
@Test
public void testDisplayNotification_userSetupInProgress_isInvisible() {
when(mCarDeviceProvisionedController.isCurrentUserSetupInProgress()).thenReturn(true);
mDefaultController.displayNotification(mNotificationView);
assertThat(mDefaultController.isVisible()).isFalse();
public void testDisplayNotification_userFullySetupTrue_isInvisible() {
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
}
@Test
public void testDisplayNotification_userSetupIncomplete_isInvisible() {
when(mCarDeviceProvisionedController.isCurrentUserSetup()).thenReturn(false);
mDefaultController.displayNotification(mNotificationView);
assertThat(mDefaultController.isVisible()).isFalse();
public void testDisplayNotification_userFullySetupFalse_isInvisible() {
when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(false);
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isFalse();
}
@Test
public void testDisplayNotification_notificationPanelExpanded_isInvisible() {
when(mNotificationPanelViewController.isPanelExpanded()).thenReturn(true);
mDefaultController.displayNotification(mNotificationView);
assertThat(mDefaultController.isVisible()).isFalse();
public void testDisplayNotification_overlayWindowStateShouldShowHUNFalse_isInvisible() {
when(mOverlayViewGlobalStateController.shouldShowHUN()).thenReturn(false);
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isFalse();
}
@Test
public void testDisplayNotification_notificationPanelExpandedEnabledHUNWhenOpen_isVisible() {
when(mNotificationPanelViewController.isPanelExpanded()).thenReturn(true);
mOverrideEnabledController.displayNotification(mNotificationView);
assertThat(mOverrideEnabledController.isVisible()).isTrue();
public void testDisplayNotification_overlayWindowStateShouldShowHUNTrue_isVisible() {
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
}
}

View File

@@ -339,7 +339,7 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase {
mOverlayPanelViewController.setPanelVisible(true);
verify(mOverlayViewGlobalStateController).setWindowVisible(true);
verify(mOverlayViewGlobalStateController).showView(mOverlayPanelViewController);
}
@Test
@@ -349,7 +349,7 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase {
mOverlayPanelViewController.setPanelVisible(true);
verify(mOverlayViewGlobalStateController, never()).setWindowVisible(true);
verify(mOverlayViewGlobalStateController, never()).showView(mOverlayPanelViewController);
}
@Test
@@ -377,7 +377,7 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase {
mOverlayPanelViewController.setPanelVisible(false);
verify(mOverlayViewGlobalStateController).setWindowVisible(false);
verify(mOverlayViewGlobalStateController).hideView(mOverlayPanelViewController);
}
@Test
@@ -387,7 +387,7 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase {
mOverlayPanelViewController.setPanelVisible(false);
verify(mOverlayViewGlobalStateController, never()).setWindowVisible(false);
verify(mOverlayViewGlobalStateController, never()).hideView(mOverlayPanelViewController);
}
@Test
@@ -428,10 +428,6 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase {
private static class TestOverlayPanelViewController extends OverlayPanelViewController {
private boolean mShouldAnimateCollapsePanel;
private boolean mShouldAnimateExpandPanel;
private boolean mShouldAllowClosingScroll;
boolean mOnAnimateCollapsePanelCalled;
boolean mAnimateCollapsePanelCalled;
boolean mOnAnimateExpandPanelCalled;
@@ -440,6 +436,9 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase {
boolean mOnExpandAnimationEndCalled;
boolean mOnOpenScrollStartEnd;
List<Integer> mOnScrollHeights;
private boolean mShouldAnimateCollapsePanel;
private boolean mShouldAnimateExpandPanel;
private boolean mShouldAllowClosingScroll;
TestOverlayPanelViewController(
Context context,

View File

@@ -24,25 +24,33 @@ import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.view.ViewStub;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.car.navigationbar.CarNavigationBarController;
import com.android.systemui.tests.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.Arrays;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@SmallTest
public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
private static final String MOCK_OVERLAY_VIEW_CONTROLLER_NAME = "OverlayViewController";
private static final int OVERLAY_VIEW_CONTROLLER_1_Z_ORDER = 0;
private static final int OVERLAY_VIEW_CONTROLLER_2_Z_ORDER = 1;
private static final int OVERLAY_PANEL_VIEW_CONTROLLER_Z_ORDER = 2;
private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
private ViewGroup mBaseLayout;
@@ -54,7 +62,11 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
@Mock
private OverlayViewMediator mOverlayViewMediator;
@Mock
private OverlayViewController mOverlayViewController;
private OverlayViewController mOverlayViewController1;
@Mock
private OverlayViewController mOverlayViewController2;
@Mock
private OverlayPanelViewController mOverlayPanelViewController;
@Mock
private Runnable mRunnable;
@@ -62,14 +74,15 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
public void setUp() {
MockitoAnnotations.initMocks(/* testClass= */ this);
mBaseLayout = (ViewGroup) LayoutInflater.from(mContext).inflate(
R.layout.overlay_view_global_state_controller_test, /* root= */ null);
when(mSystemUIOverlayWindowController.getBaseLayout()).thenReturn(mBaseLayout);
mOverlayViewGlobalStateController = new OverlayViewGlobalStateController(
mCarNavigationBarController, mSystemUIOverlayWindowController);
verify(mSystemUIOverlayWindowController).attach();
mBaseLayout = new FrameLayout(mContext);
when(mSystemUIOverlayWindowController.getBaseLayout()).thenReturn(mBaseLayout);
}
@Test
@@ -87,182 +100,445 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
}
@Test
public void showView_nothingAlreadyShown_navigationBarsHidden() {
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
public void showView_nothingAlreadyShown_shouldShowNavBarFalse_navigationBarsHidden() {
setupOverlayViewController1();
when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(false);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
verify(mCarNavigationBarController).hideBars();
}
@Test
public void showView_nothingAlreadyShown_windowIsExpanded() {
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
public void showView_nothingAlreadyShown_shouldShowNavBarTrue_navigationBarsShown() {
setupOverlayViewController1();
when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(true);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
verify(mCarNavigationBarController).showBars();
}
@Test
public void showView_nothingAlreadyShown_windowIsSetVisible() {
setupOverlayViewController1();
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
verify(mSystemUIOverlayWindowController).setWindowVisible(true);
}
@Test
public void showView_somethingAlreadyShown_navigationBarsHidden() {
mOverlayViewGlobalStateController.mShownSet.add(MOCK_OVERLAY_VIEW_CONTROLLER_NAME);
public void showView_nothingAlreadyShown_newHighestZOrder() {
setupOverlayViewController1();
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
verify(mCarNavigationBarController, never()).hideBars();
assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
mOverlayViewController1);
}
@Test
public void showView_somethingAlreadyShown_windowIsExpanded() {
mOverlayViewGlobalStateController.mShownSet.add(MOCK_OVERLAY_VIEW_CONTROLLER_NAME);
public void showView_nothingAlreadyShown_newHighestZOrder_isVisible() {
setupOverlayViewController1();
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsKey(
OVERLAY_VIEW_CONTROLLER_1_Z_ORDER)).isTrue();
}
@Test
public void showView_newHighestZOrder() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
mOverlayViewController2);
}
@Test
public void showView_newHighestZOrder_shouldShowNavBarFalse_navigationBarsHidden() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
when(mOverlayViewController2.shouldShowNavigationBar()).thenReturn(false);
mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
verify(mCarNavigationBarController).hideBars();
}
@Test
public void showView_newHighestZOrder_shouldShowNavBarTrue_navigationBarsShown() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
when(mOverlayViewController2.shouldShowNavigationBar()).thenReturn(true);
mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
verify(mCarNavigationBarController).showBars();
}
@Test
public void showView_newHighestZOrder_correctViewsShown() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.keySet().toArray())
.isEqualTo(Arrays.asList(OVERLAY_VIEW_CONTROLLER_1_Z_ORDER,
OVERLAY_VIEW_CONTROLLER_2_Z_ORDER).toArray());
}
@Test
public void showView_oldHighestZOrder() {
setupOverlayViewController2();
setOverlayViewControllerAsShowing(mOverlayViewController2);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
mOverlayViewController2);
}
@Test
public void showView_oldHighestZOrder_shouldShowNavBarFalse_navigationBarsHidden() {
setupOverlayViewController2();
setOverlayViewControllerAsShowing(mOverlayViewController2);
when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(true);
when(mOverlayViewController2.shouldShowNavigationBar()).thenReturn(false);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
verify(mCarNavigationBarController).hideBars();
}
@Test
public void showView_oldHighestZOrder_shouldShowNavBarTrue_navigationBarsShown() {
setupOverlayViewController2();
setOverlayViewControllerAsShowing(mOverlayViewController2);
when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(false);
when(mOverlayViewController2.shouldShowNavigationBar()).thenReturn(true);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
verify(mCarNavigationBarController).showBars();
}
@Test
public void showView_oldHighestZOrder_correctViewsShown() {
setupOverlayViewController1();
setupOverlayViewController2();
setOverlayViewControllerAsShowing(mOverlayViewController2);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.keySet().toArray())
.isEqualTo(Arrays.asList(OVERLAY_VIEW_CONTROLLER_1_Z_ORDER,
OVERLAY_VIEW_CONTROLLER_2_Z_ORDER).toArray());
}
@Test
public void showView_somethingAlreadyShown_windowVisibleNotCalled() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
verify(mSystemUIOverlayWindowController, never()).setWindowVisible(true);
}
@Test
public void showView_viewControllerNotInflated_inflateViewController() {
when(mOverlayViewController.isInflated()).thenReturn(false);
setupOverlayViewController2();
when(mOverlayViewController2.isInflated()).thenReturn(false);
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
verify(mOverlayViewController).inflate(mBaseLayout);
verify(mOverlayViewController2).inflate(mBaseLayout);
}
@Test
public void showView_viewControllerInflated_inflateViewControllerNotCalled() {
when(mOverlayViewController.isInflated()).thenReturn(true);
setupOverlayViewController2();
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
verify(mOverlayViewController, never()).inflate(mBaseLayout);
verify(mOverlayViewController2, never()).inflate(mBaseLayout);
}
@Test
public void showView_panelViewController_inflateViewControllerNotCalled() {
setupOverlayPanelViewController();
mOverlayViewGlobalStateController.showView(mOverlayPanelViewController, mRunnable);
verify(mOverlayPanelViewController, never()).inflate(mBaseLayout);
verify(mOverlayPanelViewController, never()).isInflated();
}
@Test
public void showView_showRunnableCalled() {
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
setupOverlayViewController1();
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
verify(mRunnable).run();
}
@Test
public void showView_overlayViewControllerAddedToShownSet() {
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
assertThat(mOverlayViewGlobalStateController.mShownSet.contains(
mOverlayViewController.getClass().getName())).isTrue();
}
@Test
public void hideView_viewControllerNotInflated_hideRunnableNotCalled() {
when(mOverlayViewController.isInflated()).thenReturn(false);
when(mOverlayViewController2.isInflated()).thenReturn(false);
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
verify(mRunnable, never()).run();
}
@Test
public void hideView_nothingShown_hideRunnableNotCalled() {
when(mOverlayViewController.isInflated()).thenReturn(true);
mOverlayViewGlobalStateController.mShownSet.clear();
when(mOverlayViewController2.isInflated()).thenReturn(true);
mOverlayViewGlobalStateController.mZOrderMap.clear();
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
verify(mRunnable, never()).run();
}
@Test
public void hideView_viewControllerNotShown_hideRunnableNotCalled() {
when(mOverlayViewController.isInflated()).thenReturn(true);
mOverlayViewGlobalStateController.mShownSet.add(MOCK_OVERLAY_VIEW_CONTROLLER_NAME);
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
when(mOverlayViewController2.isInflated()).thenReturn(true);
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
verify(mRunnable, never()).run();
}
@Test
public void hideView_viewControllerShown_hideRunnableCalled() {
when(mOverlayViewController.isInflated()).thenReturn(true);
mOverlayViewGlobalStateController.mShownSet.add(
mOverlayViewController.getClass().getName());
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
verify(mRunnable).run();
}
@Test
public void hideView_viewControllerOnlyShown_nothingShown() {
when(mOverlayViewController.isInflated()).thenReturn(true);
mOverlayViewGlobalStateController.mShownSet.add(
mOverlayViewController.getClass().getName());
public void hideView_viewControllerOnlyShown_noHighestZOrder() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
assertThat(mOverlayViewGlobalStateController.mShownSet.isEmpty()).isTrue();
assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isNull();
}
@Test
public void hideView_viewControllerNotOnlyShown_navigationBarNotShown() {
when(mOverlayViewController.isInflated()).thenReturn(true);
mOverlayViewGlobalStateController.mShownSet.add(
mOverlayViewController.getClass().getName());
mOverlayViewGlobalStateController.mShownSet.add(MOCK_OVERLAY_VIEW_CONTROLLER_NAME);
public void hideView_viewControllerOnlyShown_nothingShown() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
verify(mCarNavigationBarController, never()).showBars();
assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.isEmpty()).isTrue();
}
@Test
public void hideView_viewControllerOnlyShown_viewControllerNotShown() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsKey(
OVERLAY_VIEW_CONTROLLER_1_Z_ORDER)).isFalse();
}
@Test
public void hideView_newHighestZOrder_twoViewsShown() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
setOverlayViewControllerAsShowing(mOverlayViewController2);
mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
mOverlayViewController1);
}
@Test
public void hideView_newHighestZOrder_threeViewsShown() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
setOverlayViewControllerAsShowing(mOverlayViewController2);
setupOverlayPanelViewController();
setOverlayViewControllerAsShowing(mOverlayPanelViewController);
mOverlayViewGlobalStateController.hideView(mOverlayPanelViewController, mRunnable);
assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
mOverlayViewController2);
}
@Test
public void hideView_newHighestZOrder_shouldShowNavBarFalse_navigationBarHidden() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
setOverlayViewControllerAsShowing(mOverlayViewController2);
when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(false);
mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
verify(mCarNavigationBarController).hideBars();
}
@Test
public void hideView_newHighestZOrder_shouldShowNavBarTrue_navigationBarShown() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
setOverlayViewControllerAsShowing(mOverlayViewController2);
when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(true);
mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
verify(mCarNavigationBarController).showBars();
}
@Test
public void hideView_oldHighestZOrder() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
setOverlayViewControllerAsShowing(mOverlayViewController2);
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
mOverlayViewController2);
}
@Test
public void hideView_oldHighestZOrder_shouldShowNavBarFalse_navigationBarHidden() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
setOverlayViewControllerAsShowing(mOverlayViewController2);
when(mOverlayViewController2.shouldShowNavigationBar()).thenReturn(false);
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
verify(mCarNavigationBarController).hideBars();
}
@Test
public void hideView_oldHighestZOrder_shouldShowNavBarTrue_navigationBarShown() {
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
setOverlayViewControllerAsShowing(mOverlayViewController2);
when(mOverlayViewController2.shouldShowNavigationBar()).thenReturn(true);
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
verify(mCarNavigationBarController).showBars();
}
@Test
public void hideView_viewControllerNotOnlyShown_windowNotCollapsed() {
when(mOverlayViewController.isInflated()).thenReturn(true);
mOverlayViewGlobalStateController.mShownSet.add(
mOverlayViewController.getClass().getName());
mOverlayViewGlobalStateController.mShownSet.add(MOCK_OVERLAY_VIEW_CONTROLLER_NAME);
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
setupOverlayViewController2();
setOverlayViewControllerAsShowing(mOverlayViewController2);
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
verify(mSystemUIOverlayWindowController, never()).setWindowVisible(false);
}
@Test
public void hideView_viewControllerOnlyShown_navigationBarShown() {
when(mOverlayViewController.isInflated()).thenReturn(true);
mOverlayViewGlobalStateController.mShownSet.add(
mOverlayViewController.getClass().getName());
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
verify(mCarNavigationBarController).showBars();
}
@Test
public void hideView_viewControllerOnlyShown_windowCollapsed() {
when(mOverlayViewController.isInflated()).thenReturn(true);
mOverlayViewGlobalStateController.mShownSet.add(
mOverlayViewController.getClass().getName());
setupOverlayViewController1();
setOverlayViewControllerAsShowing(mOverlayViewController1);
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
verify(mSystemUIOverlayWindowController).setWindowVisible(false);
}
@Test
public void inflateView_notInflated_inflates() {
when(mOverlayViewController.isInflated()).thenReturn(false);
when(mOverlayViewController2.isInflated()).thenReturn(false);
mOverlayViewGlobalStateController.inflateView(mOverlayViewController);
mOverlayViewGlobalStateController.inflateView(mOverlayViewController2);
verify(mOverlayViewController).inflate(mBaseLayout);
verify(mOverlayViewController2).inflate(mBaseLayout);
}
@Test
public void inflateView_alreadyInflated_doesNotInflate() {
when(mOverlayViewController.isInflated()).thenReturn(true);
when(mOverlayViewController2.isInflated()).thenReturn(true);
mOverlayViewGlobalStateController.inflateView(mOverlayViewController);
mOverlayViewGlobalStateController.inflateView(mOverlayViewController2);
verify(mOverlayViewController, never()).inflate(mBaseLayout);
verify(mOverlayViewController2, never()).inflate(mBaseLayout);
}
private void setupOverlayViewController1() {
setupOverlayViewController(mOverlayViewController1, R.id.overlay_view_controller_stub_1,
R.id.overlay_view_controller_1);
}
private void setupOverlayViewController2() {
setupOverlayViewController(mOverlayViewController2, R.id.overlay_view_controller_stub_2,
R.id.overlay_view_controller_2);
}
private void setupOverlayPanelViewController() {
setupOverlayViewController(mOverlayPanelViewController, R.id.overlay_view_controller_stub_3,
R.id.overlay_view_controller_3);
}
private void setupOverlayViewController(OverlayViewController overlayViewController,
int stubId, int inflatedId) {
ViewStub viewStub = mBaseLayout.findViewById(stubId);
View layout;
if (viewStub == null) {
layout = mBaseLayout.findViewById(inflatedId);
} else {
layout = viewStub.inflate();
}
when(overlayViewController.getLayout()).thenReturn(layout);
when(overlayViewController.isInflated()).thenReturn(true);
}
private void setOverlayViewControllerAsShowing(OverlayViewController overlayViewController) {
mOverlayViewGlobalStateController.showView(overlayViewController, /* show= */ null);
Mockito.reset(mCarNavigationBarController, mSystemUIOverlayWindowController);
when(mSystemUIOverlayWindowController.getBaseLayout()).thenReturn(mBaseLayout);
}
}