Merge "Allow HUNs to be shown over Overlay Window." into rvc-dev am: 4785a0669a
Change-Id: I8cd1bc2b48594667867e70d1e0d84071f2350a6e
This commit is contained in:
@@ -73,7 +73,7 @@ public class CarNavigationBarController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hides all navigation bars.
|
* Hides all system bars.
|
||||||
*/
|
*/
|
||||||
public void hideBars() {
|
public void hideBars() {
|
||||||
if (mTopView != null) {
|
if (mTopView != null) {
|
||||||
@@ -85,7 +85,7 @@ public class CarNavigationBarController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows all navigation bars.
|
* Shows all system bars.
|
||||||
*/
|
*/
|
||||||
public void showBars() {
|
public void showBars() {
|
||||||
if (mTopView != null) {
|
if (mTopView != null) {
|
||||||
|
|||||||
@@ -29,41 +29,40 @@ import android.widget.FrameLayout;
|
|||||||
import com.android.car.notification.R;
|
import com.android.car.notification.R;
|
||||||
import com.android.car.notification.headsup.CarHeadsUpNotificationContainer;
|
import com.android.car.notification.headsup.CarHeadsUpNotificationContainer;
|
||||||
import com.android.systemui.car.CarDeviceProvisionedController;
|
import com.android.systemui.car.CarDeviceProvisionedController;
|
||||||
|
import com.android.systemui.car.window.OverlayViewGlobalStateController;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import dagger.Lazy;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A controller for SysUI's HUN display.
|
* A controller for SysUI's HUN display.
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CarHeadsUpNotificationSystemContainer implements CarHeadsUpNotificationContainer {
|
public class CarHeadsUpNotificationSystemContainer implements CarHeadsUpNotificationContainer {
|
||||||
private final CarDeviceProvisionedController mCarDeviceProvisionedController;
|
private final CarDeviceProvisionedController mCarDeviceProvisionedController;
|
||||||
private final Lazy<NotificationPanelViewController> mNotificationPanelViewControllerLazy;
|
private final OverlayViewGlobalStateController mOverlayViewGlobalStateController;
|
||||||
|
|
||||||
private final ViewGroup mWindow;
|
private final ViewGroup mWindow;
|
||||||
private final FrameLayout mHeadsUpContentFrame;
|
private final FrameLayout mHeadsUpContentFrame;
|
||||||
|
|
||||||
private final boolean mEnableHeadsUpNotificationWhenNotificationShadeOpen;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CarHeadsUpNotificationSystemContainer(Context context,
|
CarHeadsUpNotificationSystemContainer(Context context,
|
||||||
@Main Resources resources,
|
@Main Resources resources,
|
||||||
CarDeviceProvisionedController deviceProvisionedController,
|
CarDeviceProvisionedController deviceProvisionedController,
|
||||||
WindowManager windowManager,
|
WindowManager windowManager,
|
||||||
Lazy<NotificationPanelViewController> notificationPanelViewControllerLazy) {
|
OverlayViewGlobalStateController overlayViewGlobalStateController) {
|
||||||
mCarDeviceProvisionedController = deviceProvisionedController;
|
mCarDeviceProvisionedController = deviceProvisionedController;
|
||||||
mNotificationPanelViewControllerLazy = notificationPanelViewControllerLazy;
|
mOverlayViewGlobalStateController = overlayViewGlobalStateController;
|
||||||
|
|
||||||
boolean showOnBottom = resources.getBoolean(R.bool.config_showHeadsUpNotificationOnBottom);
|
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(
|
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||||
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
|
WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL,
|
||||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||||
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
|
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
|
||||||
PixelFormat.TRANSLUCENT);
|
PixelFormat.TRANSLUCENT);
|
||||||
@@ -78,15 +77,11 @@ public class CarHeadsUpNotificationSystemContainer implements CarHeadsUpNotifica
|
|||||||
windowManager.addView(mWindow, lp);
|
windowManager.addView(mWindow, lp);
|
||||||
mWindow.setVisibility(View.INVISIBLE);
|
mWindow.setVisibility(View.INVISIBLE);
|
||||||
mHeadsUpContentFrame = mWindow.findViewById(R.id.headsup_content);
|
mHeadsUpContentFrame = mWindow.findViewById(R.id.headsup_content);
|
||||||
|
|
||||||
mEnableHeadsUpNotificationWhenNotificationShadeOpen = resources.getBoolean(
|
|
||||||
R.bool.config_enableHeadsUpNotificationWhenNotificationShadeOpen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void animateShow() {
|
private void animateShow() {
|
||||||
if ((mEnableHeadsUpNotificationWhenNotificationShadeOpen
|
if (mCarDeviceProvisionedController.isCurrentUserFullySetup()
|
||||||
|| !mNotificationPanelViewControllerLazy.get().isPanelExpanded())
|
&& mOverlayViewGlobalStateController.shouldShowHUN()) {
|
||||||
&& mCarDeviceProvisionedController.isCurrentUserFullySetup()) {
|
|
||||||
mWindow.setVisibility(View.VISIBLE);
|
mWindow.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ public class NotificationPanelViewController extends OverlayPanelViewController
|
|||||||
private final CarNotificationListener mCarNotificationListener;
|
private final CarNotificationListener mCarNotificationListener;
|
||||||
private final NotificationClickHandlerFactory mNotificationClickHandlerFactory;
|
private final NotificationClickHandlerFactory mNotificationClickHandlerFactory;
|
||||||
private final StatusBarStateController mStatusBarStateController;
|
private final StatusBarStateController mStatusBarStateController;
|
||||||
|
private final boolean mEnableHeadsUpNotificationWhenNotificationShadeOpen;
|
||||||
|
|
||||||
private float mInitialBackgroundAlpha;
|
private float mInitialBackgroundAlpha;
|
||||||
private float mBackgroundAlphaDiff;
|
private float mBackgroundAlphaDiff;
|
||||||
@@ -144,6 +145,10 @@ public class NotificationPanelViewController extends OverlayPanelViewController
|
|||||||
+ " percentage");
|
+ " percentage");
|
||||||
}
|
}
|
||||||
mBackgroundAlphaDiff = finalBackgroundAlpha - mInitialBackgroundAlpha;
|
mBackgroundAlphaDiff = finalBackgroundAlpha - mInitialBackgroundAlpha;
|
||||||
|
|
||||||
|
mEnableHeadsUpNotificationWhenNotificationShadeOpen = mResources.getBoolean(
|
||||||
|
com.android.car.notification.R.bool
|
||||||
|
.config_enableHeadsUpNotificationWhenNotificationShadeOpen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -151,6 +156,16 @@ public class NotificationPanelViewController extends OverlayPanelViewController
|
|||||||
reinflate();
|
reinflate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldShowNavigationBar() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldShowHUN() {
|
||||||
|
return mEnableHeadsUpNotificationWhenNotificationShadeOpen;
|
||||||
|
}
|
||||||
|
|
||||||
/** Reinflates the view. */
|
/** Reinflates the view. */
|
||||||
public void reinflate() {
|
public void reinflate() {
|
||||||
ViewGroup container = (ViewGroup) getLayout();
|
ViewGroup container = (ViewGroup) getLayout();
|
||||||
|
|||||||
@@ -375,10 +375,10 @@ public abstract class OverlayPanelViewController extends OverlayViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (visible && !getOverlayViewGlobalStateController().isWindowVisible()) {
|
if (visible && !getOverlayViewGlobalStateController().isWindowVisible()) {
|
||||||
getOverlayViewGlobalStateController().setWindowVisible(true);
|
getOverlayViewGlobalStateController().showView(/* panelViewController= */ this);
|
||||||
}
|
}
|
||||||
if (!visible && getOverlayViewGlobalStateController().isWindowVisible()) {
|
if (!visible && getOverlayViewGlobalStateController().isWindowVisible()) {
|
||||||
getOverlayViewGlobalStateController().setWindowVisible(false);
|
getOverlayViewGlobalStateController().hideView(/* panelViewController= */ this);
|
||||||
}
|
}
|
||||||
getLayout().setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
|
getLayout().setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
|
||||||
getOverlayViewGlobalStateController().setWindowFocusable(visible);
|
getOverlayViewGlobalStateController().setWindowFocusable(visible);
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ public class OverlayViewController {
|
|||||||
mOverlayViewGlobalStateController.hideView(/* viewController= */ this, this::hide);
|
mOverlayViewGlobalStateController.hideView(/* viewController= */ this, this::hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inflate layout owned by controller.
|
* 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() {
|
public final boolean isInflated() {
|
||||||
return mLayout != null;
|
return mLayout != null;
|
||||||
@@ -125,4 +124,18 @@ public class OverlayViewController {
|
|||||||
protected final OverlayViewGlobalStateController getOverlayViewGlobalStateController() {
|
protected final OverlayViewGlobalStateController getOverlayViewGlobalStateController() {
|
||||||
return mOverlayViewGlobalStateController;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,14 +16,17 @@
|
|||||||
|
|
||||||
package com.android.systemui.car.window;
|
package com.android.systemui.car.window;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.systemui.car.navigationbar.CarNavigationBarController;
|
import com.android.systemui.car.navigationbar.CarNavigationBarController;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashMap;
|
||||||
import java.util.Set;
|
import java.util.Map;
|
||||||
|
import java.util.SortedMap;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@@ -39,11 +42,17 @@ import javax.inject.Singleton;
|
|||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class OverlayViewGlobalStateController {
|
public class OverlayViewGlobalStateController {
|
||||||
|
private static final boolean DEBUG = false;
|
||||||
private static final String TAG = OverlayViewGlobalStateController.class.getSimpleName();
|
private static final String TAG = OverlayViewGlobalStateController.class.getSimpleName();
|
||||||
|
private static final int UNKNOWN_Z_ORDER = -1;
|
||||||
private final SystemUIOverlayWindowController mSystemUIOverlayWindowController;
|
private final SystemUIOverlayWindowController mSystemUIOverlayWindowController;
|
||||||
private final CarNavigationBarController mCarNavigationBarController;
|
private final CarNavigationBarController mCarNavigationBarController;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Set<String> mShownSet;
|
Map<OverlayViewController, Integer> mZOrderMap;
|
||||||
|
@VisibleForTesting
|
||||||
|
SortedMap<Integer, OverlayViewController> mZOrderVisibleSortedMap;
|
||||||
|
@VisibleForTesting
|
||||||
|
OverlayViewController mHighestZOrder;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public OverlayViewGlobalStateController(
|
public OverlayViewGlobalStateController(
|
||||||
@@ -52,7 +61,8 @@ public class OverlayViewGlobalStateController {
|
|||||||
mSystemUIOverlayWindowController = systemUIOverlayWindowController;
|
mSystemUIOverlayWindowController = systemUIOverlayWindowController;
|
||||||
mSystemUIOverlayWindowController.attach();
|
mSystemUIOverlayWindowController.attach();
|
||||||
mCarNavigationBarController = carNavigationBarController;
|
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) {
|
public void showView(OverlayPanelViewController panelViewController) {
|
||||||
if (mShownSet.isEmpty()) {
|
showView(panelViewController, /* show= */ null);
|
||||||
mCarNavigationBarController.hideBars();
|
|
||||||
setWindowVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
inflateView(viewController);
|
|
||||||
|
|
||||||
show.run();
|
|
||||||
mShownSet.add(viewController.getClass().getName());
|
|
||||||
|
|
||||||
Log.d(TAG, "Content shown: " + viewController.getClass().getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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()) {
|
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());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!mShownSet.contains(viewController.getClass().getName())) {
|
if (!mZOrderMap.containsKey(viewController)) {
|
||||||
Log.d(TAG, "Content cannot be hidden since it isn't shown: "
|
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());
|
+ viewController.getClass().getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hide.run();
|
if (hide != null) {
|
||||||
mShownSet.remove(viewController.getClass().getName());
|
hide.run();
|
||||||
|
}
|
||||||
|
|
||||||
if (mShownSet.isEmpty()) {
|
mZOrderVisibleSortedMap.remove(mZOrderMap.get(viewController));
|
||||||
mCarNavigationBarController.showBars();
|
refreshHighestZOrderWhenHidingView(viewController);
|
||||||
|
refreshNavigationBarVisibility();
|
||||||
|
|
||||||
|
if (mZOrderVisibleSortedMap.isEmpty()) {
|
||||||
setWindowVisible(false);
|
setWindowVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Content hidden: " + viewController.getClass().getName());
|
Log.d(TAG, "Content hidden: " + viewController.getClass().getName());
|
||||||
|
debugLog();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the window visibility state. */
|
private void refreshHighestZOrderWhenHidingView(OverlayViewController viewController) {
|
||||||
public void setWindowVisible(boolean expanded) {
|
if (mZOrderVisibleSortedMap.isEmpty()) {
|
||||||
mSystemUIOverlayWindowController.setWindowVisible(expanded);
|
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. */
|
/** Returns {@code true} is the window is visible. */
|
||||||
@@ -118,13 +204,14 @@ public class OverlayViewGlobalStateController {
|
|||||||
return mSystemUIOverlayWindowController.isWindowVisible();
|
return mSystemUIOverlayWindowController.isWindowVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the focusable flag of the sysui overlawy window. */
|
private void setWindowVisible(boolean visible) {
|
||||||
public void setWindowFocusable(boolean focusable) {
|
mSystemUIOverlayWindowController.setWindowVisible(visible);
|
||||||
mSystemUIOverlayWindowController.setWindowFocusable(focusable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 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) {
|
public void setWindowNeedsInput(boolean needsInput) {
|
||||||
mSystemUIOverlayWindowController.setWindowNeedsInput(needsInput);
|
mSystemUIOverlayWindowController.setWindowNeedsInput(needsInput);
|
||||||
}
|
}
|
||||||
@@ -134,10 +221,34 @@ public class OverlayViewGlobalStateController {
|
|||||||
return mSystemUIOverlayWindowController.isWindowFocusable();
|
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. */
|
/** Inflates the view controlled by the given view controller. */
|
||||||
public void inflateView(OverlayViewController viewController) {
|
public void inflateView(OverlayViewController viewController) {
|
||||||
if (!viewController.isInflated()) {
|
if (!viewController.isInflated()) {
|
||||||
viewController.inflate(mSystemUIOverlayWindowController.getBaseLayout());
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
package com.android.systemui.car.keyguard;
|
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.anyBoolean;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
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.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -29,7 +30,6 @@ import android.os.Handler;
|
|||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
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.CarServiceProvider;
|
||||||
import com.android.systemui.car.navigationbar.CarNavigationBarController;
|
import com.android.systemui.car.navigationbar.CarNavigationBarController;
|
||||||
import com.android.systemui.car.window.OverlayViewGlobalStateController;
|
import com.android.systemui.car.window.OverlayViewGlobalStateController;
|
||||||
import com.android.systemui.car.window.SystemUIOverlayWindowController;
|
|
||||||
import com.android.systemui.keyguard.DismissCallbackRegistry;
|
import com.android.systemui.keyguard.DismissCallbackRegistry;
|
||||||
import com.android.systemui.plugins.FalsingManager;
|
import com.android.systemui.plugins.FalsingManager;
|
||||||
import com.android.systemui.statusbar.phone.BiometricUnlockController;
|
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.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.InOrder;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
@@ -61,28 +61,20 @@ import dagger.Lazy;
|
|||||||
public class CarKeyguardViewControllerTest extends SysuiTestCase {
|
public class CarKeyguardViewControllerTest extends SysuiTestCase {
|
||||||
|
|
||||||
private TestableCarKeyguardViewController mCarKeyguardViewController;
|
private TestableCarKeyguardViewController mCarKeyguardViewController;
|
||||||
private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
|
|
||||||
private ViewGroup mBaseLayout;
|
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
|
||||||
@Mock
|
@Mock
|
||||||
private KeyguardBouncer mBouncer;
|
private KeyguardBouncer mBouncer;
|
||||||
@Mock
|
@Mock
|
||||||
private CarNavigationBarController mCarNavigationBarController;
|
private CarNavigationBarController mCarNavigationBarController;
|
||||||
@Mock
|
@Mock
|
||||||
private SystemUIOverlayWindowController mSystemUIOverlayWindowController;
|
|
||||||
@Mock
|
|
||||||
private CarKeyguardViewController.OnKeyguardCancelClickedListener mCancelClickedListener;
|
private CarKeyguardViewController.OnKeyguardCancelClickedListener mCancelClickedListener;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
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(
|
mCarKeyguardViewController = new TestableCarKeyguardViewController(
|
||||||
mContext,
|
mContext,
|
||||||
Handler.getMain(),
|
Handler.getMain(),
|
||||||
@@ -98,6 +90,8 @@ public class CarKeyguardViewControllerTest extends SysuiTestCase {
|
|||||||
mock(FalsingManager.class),
|
mock(FalsingManager.class),
|
||||||
() -> mock(KeyguardBypassController.class)
|
() -> mock(KeyguardBypassController.class)
|
||||||
);
|
);
|
||||||
|
mCarKeyguardViewController.inflate((ViewGroup) LayoutInflater.from(mContext).inflate(
|
||||||
|
R.layout.sysui_overlay_window, /* root= */ null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -113,8 +107,7 @@ public class CarKeyguardViewControllerTest extends SysuiTestCase {
|
|||||||
when(mBouncer.isSecure()).thenReturn(true);
|
when(mBouncer.isSecure()).thenReturn(true);
|
||||||
mCarKeyguardViewController.show(/* options= */ null);
|
mCarKeyguardViewController.show(/* options= */ null);
|
||||||
|
|
||||||
assertThat(mBaseLayout.findViewById(R.id.keyguard_container).getVisibility()).isEqualTo(
|
verify(mOverlayViewGlobalStateController).showView(eq(mCarKeyguardViewController), any());
|
||||||
View.VISIBLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -130,8 +123,17 @@ public class CarKeyguardViewControllerTest extends SysuiTestCase {
|
|||||||
when(mBouncer.isSecure()).thenReturn(false);
|
when(mBouncer.isSecure()).thenReturn(false);
|
||||||
mCarKeyguardViewController.show(/* options= */ null);
|
mCarKeyguardViewController.show(/* options= */ null);
|
||||||
|
|
||||||
assertThat(mBaseLayout.findViewById(R.id.keyguard_container).getVisibility()).isEqualTo(
|
// Here we check for both showView and hideView since the current implementation of show
|
||||||
View.GONE);
|
// 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
|
@Test
|
||||||
@@ -156,8 +158,11 @@ public class CarKeyguardViewControllerTest extends SysuiTestCase {
|
|||||||
mCarKeyguardViewController.show(/* options= */ null);
|
mCarKeyguardViewController.show(/* options= */ null);
|
||||||
mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0);
|
mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0);
|
||||||
|
|
||||||
assertThat(mBaseLayout.findViewById(R.id.keyguard_container).getVisibility()).isEqualTo(
|
InOrder inOrder = inOrder(mOverlayViewGlobalStateController);
|
||||||
View.GONE);
|
inOrder.verify(mOverlayViewGlobalStateController).showView(eq(mCarKeyguardViewController),
|
||||||
|
any());
|
||||||
|
inOrder.verify(mOverlayViewGlobalStateController).hideView(eq(mCarKeyguardViewController),
|
||||||
|
any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ import android.view.WindowManager;
|
|||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.car.CarDeviceProvisionedController;
|
import com.android.systemui.car.CarDeviceProvisionedController;
|
||||||
|
import com.android.systemui.car.window.OverlayViewGlobalStateController;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -42,12 +42,11 @@ import org.mockito.MockitoAnnotations;
|
|||||||
@TestableLooper.RunWithLooper
|
@TestableLooper.RunWithLooper
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public class CarHeadsUpNotificationSystemContainerTest extends SysuiTestCase {
|
public class CarHeadsUpNotificationSystemContainerTest extends SysuiTestCase {
|
||||||
private CarHeadsUpNotificationSystemContainer mDefaultController;
|
private CarHeadsUpNotificationSystemContainer mCarHeadsUpNotificationSystemContainer;
|
||||||
private CarHeadsUpNotificationSystemContainer mOverrideEnabledController;
|
|
||||||
@Mock
|
@Mock
|
||||||
private CarDeviceProvisionedController mCarDeviceProvisionedController;
|
private CarDeviceProvisionedController mCarDeviceProvisionedController;
|
||||||
@Mock
|
@Mock
|
||||||
private NotificationPanelViewController mNotificationPanelViewController;
|
private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
|
||||||
@Mock
|
@Mock
|
||||||
private WindowManager mWindowManager;
|
private WindowManager mWindowManager;
|
||||||
|
|
||||||
@@ -58,76 +57,63 @@ public class CarHeadsUpNotificationSystemContainerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(/* testClass= */this);
|
||||||
|
|
||||||
when(mNotificationPanelViewController.isPanelExpanded()).thenReturn(false);
|
when(mOverlayViewGlobalStateController.shouldShowHUN()).thenReturn(true);
|
||||||
when(mCarDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
|
when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(true);
|
||||||
when(mCarDeviceProvisionedController.isCurrentUserSetupInProgress()).thenReturn(false);
|
|
||||||
|
|
||||||
TestableResources testableResources = mContext.getOrCreateTestableResources();
|
TestableResources testableResources = mContext.getOrCreateTestableResources();
|
||||||
|
|
||||||
testableResources.addOverride(
|
mCarHeadsUpNotificationSystemContainer = new CarHeadsUpNotificationSystemContainer(mContext,
|
||||||
R.bool.config_enableHeadsUpNotificationWhenNotificationShadeOpen, false);
|
|
||||||
|
|
||||||
mDefaultController = new CarHeadsUpNotificationSystemContainer(mContext,
|
|
||||||
testableResources.getResources(), mCarDeviceProvisionedController, mWindowManager,
|
testableResources.getResources(), mCarDeviceProvisionedController, mWindowManager,
|
||||||
() -> mNotificationPanelViewController);
|
mOverlayViewGlobalStateController);
|
||||||
|
|
||||||
testableResources.addOverride(
|
|
||||||
R.bool.config_enableHeadsUpNotificationWhenNotificationShadeOpen, true);
|
|
||||||
|
|
||||||
mOverrideEnabledController = new CarHeadsUpNotificationSystemContainer(mContext,
|
|
||||||
testableResources.getResources(), mCarDeviceProvisionedController, mWindowManager,
|
|
||||||
() -> mNotificationPanelViewController);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDisplayNotification_firstNotification_isVisible() {
|
public void testDisplayNotification_firstNotification_isVisible() {
|
||||||
mDefaultController.displayNotification(mNotificationView);
|
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
|
||||||
assertThat(mDefaultController.isVisible()).isTrue();
|
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRemoveNotification_lastNotification_isInvisible() {
|
public void testRemoveNotification_lastNotification_isInvisible() {
|
||||||
mDefaultController.displayNotification(mNotificationView);
|
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
|
||||||
mDefaultController.removeNotification(mNotificationView);
|
mCarHeadsUpNotificationSystemContainer.removeNotification(mNotificationView);
|
||||||
assertThat(mDefaultController.isVisible()).isFalse();
|
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRemoveNotification_nonLastNotification_isVisible() {
|
public void testRemoveNotification_nonLastNotification_isVisible() {
|
||||||
mDefaultController.displayNotification(mNotificationView);
|
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
|
||||||
mDefaultController.displayNotification(mNotificationView2);
|
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView2);
|
||||||
mDefaultController.removeNotification(mNotificationView);
|
mCarHeadsUpNotificationSystemContainer.removeNotification(mNotificationView);
|
||||||
assertThat(mDefaultController.isVisible()).isTrue();
|
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDisplayNotification_userSetupInProgress_isInvisible() {
|
public void testDisplayNotification_userFullySetupTrue_isInvisible() {
|
||||||
when(mCarDeviceProvisionedController.isCurrentUserSetupInProgress()).thenReturn(true);
|
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
|
||||||
mDefaultController.displayNotification(mNotificationView);
|
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
|
||||||
assertThat(mDefaultController.isVisible()).isFalse();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDisplayNotification_userSetupIncomplete_isInvisible() {
|
public void testDisplayNotification_userFullySetupFalse_isInvisible() {
|
||||||
when(mCarDeviceProvisionedController.isCurrentUserSetup()).thenReturn(false);
|
when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(false);
|
||||||
mDefaultController.displayNotification(mNotificationView);
|
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
|
||||||
assertThat(mDefaultController.isVisible()).isFalse();
|
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDisplayNotification_notificationPanelExpanded_isInvisible() {
|
public void testDisplayNotification_overlayWindowStateShouldShowHUNFalse_isInvisible() {
|
||||||
when(mNotificationPanelViewController.isPanelExpanded()).thenReturn(true);
|
when(mOverlayViewGlobalStateController.shouldShowHUN()).thenReturn(false);
|
||||||
mDefaultController.displayNotification(mNotificationView);
|
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
|
||||||
assertThat(mDefaultController.isVisible()).isFalse();
|
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDisplayNotification_notificationPanelExpandedEnabledHUNWhenOpen_isVisible() {
|
public void testDisplayNotification_overlayWindowStateShouldShowHUNTrue_isVisible() {
|
||||||
when(mNotificationPanelViewController.isPanelExpanded()).thenReturn(true);
|
mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
|
||||||
mOverrideEnabledController.displayNotification(mNotificationView);
|
assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
|
||||||
assertThat(mOverrideEnabledController.isVisible()).isTrue();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
mOverlayPanelViewController.setPanelVisible(true);
|
mOverlayPanelViewController.setPanelVisible(true);
|
||||||
|
|
||||||
verify(mOverlayViewGlobalStateController).setWindowVisible(true);
|
verify(mOverlayViewGlobalStateController).showView(mOverlayPanelViewController);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -349,7 +349,7 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
mOverlayPanelViewController.setPanelVisible(true);
|
mOverlayPanelViewController.setPanelVisible(true);
|
||||||
|
|
||||||
verify(mOverlayViewGlobalStateController, never()).setWindowVisible(true);
|
verify(mOverlayViewGlobalStateController, never()).showView(mOverlayPanelViewController);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -377,7 +377,7 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
mOverlayPanelViewController.setPanelVisible(false);
|
mOverlayPanelViewController.setPanelVisible(false);
|
||||||
|
|
||||||
verify(mOverlayViewGlobalStateController).setWindowVisible(false);
|
verify(mOverlayViewGlobalStateController).hideView(mOverlayPanelViewController);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -387,7 +387,7 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
mOverlayPanelViewController.setPanelVisible(false);
|
mOverlayPanelViewController.setPanelVisible(false);
|
||||||
|
|
||||||
verify(mOverlayViewGlobalStateController, never()).setWindowVisible(false);
|
verify(mOverlayViewGlobalStateController, never()).hideView(mOverlayPanelViewController);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -428,10 +428,6 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
private static class TestOverlayPanelViewController extends OverlayPanelViewController {
|
private static class TestOverlayPanelViewController extends OverlayPanelViewController {
|
||||||
|
|
||||||
private boolean mShouldAnimateCollapsePanel;
|
|
||||||
private boolean mShouldAnimateExpandPanel;
|
|
||||||
private boolean mShouldAllowClosingScroll;
|
|
||||||
|
|
||||||
boolean mOnAnimateCollapsePanelCalled;
|
boolean mOnAnimateCollapsePanelCalled;
|
||||||
boolean mAnimateCollapsePanelCalled;
|
boolean mAnimateCollapsePanelCalled;
|
||||||
boolean mOnAnimateExpandPanelCalled;
|
boolean mOnAnimateExpandPanelCalled;
|
||||||
@@ -440,6 +436,9 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase {
|
|||||||
boolean mOnExpandAnimationEndCalled;
|
boolean mOnExpandAnimationEndCalled;
|
||||||
boolean mOnOpenScrollStartEnd;
|
boolean mOnOpenScrollStartEnd;
|
||||||
List<Integer> mOnScrollHeights;
|
List<Integer> mOnScrollHeights;
|
||||||
|
private boolean mShouldAnimateCollapsePanel;
|
||||||
|
private boolean mShouldAnimateExpandPanel;
|
||||||
|
private boolean mShouldAllowClosingScroll;
|
||||||
|
|
||||||
TestOverlayPanelViewController(
|
TestOverlayPanelViewController(
|
||||||
Context context,
|
Context context,
|
||||||
|
|||||||
@@ -24,25 +24,33 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.FrameLayout;
|
import android.view.ViewStub;
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.car.navigationbar.CarNavigationBarController;
|
import com.android.systemui.car.navigationbar.CarNavigationBarController;
|
||||||
|
import com.android.systemui.tests.R;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
@RunWith(AndroidTestingRunner.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
@TestableLooper.RunWithLooper
|
@TestableLooper.RunWithLooper
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
|
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 OverlayViewGlobalStateController mOverlayViewGlobalStateController;
|
||||||
private ViewGroup mBaseLayout;
|
private ViewGroup mBaseLayout;
|
||||||
@@ -54,7 +62,11 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private OverlayViewMediator mOverlayViewMediator;
|
private OverlayViewMediator mOverlayViewMediator;
|
||||||
@Mock
|
@Mock
|
||||||
private OverlayViewController mOverlayViewController;
|
private OverlayViewController mOverlayViewController1;
|
||||||
|
@Mock
|
||||||
|
private OverlayViewController mOverlayViewController2;
|
||||||
|
@Mock
|
||||||
|
private OverlayPanelViewController mOverlayPanelViewController;
|
||||||
@Mock
|
@Mock
|
||||||
private Runnable mRunnable;
|
private Runnable mRunnable;
|
||||||
|
|
||||||
@@ -62,14 +74,15 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
|
|||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(/* testClass= */ this);
|
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(
|
mOverlayViewGlobalStateController = new OverlayViewGlobalStateController(
|
||||||
mCarNavigationBarController, mSystemUIOverlayWindowController);
|
mCarNavigationBarController, mSystemUIOverlayWindowController);
|
||||||
|
|
||||||
verify(mSystemUIOverlayWindowController).attach();
|
verify(mSystemUIOverlayWindowController).attach();
|
||||||
|
|
||||||
mBaseLayout = new FrameLayout(mContext);
|
|
||||||
|
|
||||||
when(mSystemUIOverlayWindowController.getBaseLayout()).thenReturn(mBaseLayout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -87,182 +100,445 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void showView_nothingAlreadyShown_navigationBarsHidden() {
|
public void showView_nothingAlreadyShown_shouldShowNavBarFalse_navigationBarsHidden() {
|
||||||
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
|
setupOverlayViewController1();
|
||||||
|
when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(false);
|
||||||
|
|
||||||
|
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
|
||||||
|
|
||||||
verify(mCarNavigationBarController).hideBars();
|
verify(mCarNavigationBarController).hideBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void showView_nothingAlreadyShown_windowIsExpanded() {
|
public void showView_nothingAlreadyShown_shouldShowNavBarTrue_navigationBarsShown() {
|
||||||
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
|
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);
|
verify(mSystemUIOverlayWindowController).setWindowVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void showView_somethingAlreadyShown_navigationBarsHidden() {
|
public void showView_nothingAlreadyShown_newHighestZOrder() {
|
||||||
mOverlayViewGlobalStateController.mShownSet.add(MOCK_OVERLAY_VIEW_CONTROLLER_NAME);
|
setupOverlayViewController1();
|
||||||
|
|
||||||
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
|
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
|
||||||
|
|
||||||
verify(mCarNavigationBarController, never()).hideBars();
|
assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
|
||||||
|
mOverlayViewController1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void showView_somethingAlreadyShown_windowIsExpanded() {
|
public void showView_nothingAlreadyShown_newHighestZOrder_isVisible() {
|
||||||
mOverlayViewGlobalStateController.mShownSet.add(MOCK_OVERLAY_VIEW_CONTROLLER_NAME);
|
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);
|
verify(mSystemUIOverlayWindowController, never()).setWindowVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void showView_viewControllerNotInflated_inflateViewController() {
|
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
|
@Test
|
||||||
public void showView_viewControllerInflated_inflateViewControllerNotCalled() {
|
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
|
@Test
|
||||||
public void showView_showRunnableCalled() {
|
public void showView_showRunnableCalled() {
|
||||||
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
|
setupOverlayViewController1();
|
||||||
|
|
||||||
|
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
|
||||||
|
|
||||||
verify(mRunnable).run();
|
verify(mRunnable).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void showView_overlayViewControllerAddedToShownSet() {
|
|
||||||
mOverlayViewGlobalStateController.showView(mOverlayViewController, mRunnable);
|
|
||||||
|
|
||||||
assertThat(mOverlayViewGlobalStateController.mShownSet.contains(
|
|
||||||
mOverlayViewController.getClass().getName())).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hideView_viewControllerNotInflated_hideRunnableNotCalled() {
|
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();
|
verify(mRunnable, never()).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hideView_nothingShown_hideRunnableNotCalled() {
|
public void hideView_nothingShown_hideRunnableNotCalled() {
|
||||||
when(mOverlayViewController.isInflated()).thenReturn(true);
|
when(mOverlayViewController2.isInflated()).thenReturn(true);
|
||||||
mOverlayViewGlobalStateController.mShownSet.clear();
|
mOverlayViewGlobalStateController.mZOrderMap.clear();
|
||||||
|
|
||||||
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
|
mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
|
||||||
|
|
||||||
verify(mRunnable, never()).run();
|
verify(mRunnable, never()).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hideView_viewControllerNotShown_hideRunnableNotCalled() {
|
public void hideView_viewControllerNotShown_hideRunnableNotCalled() {
|
||||||
when(mOverlayViewController.isInflated()).thenReturn(true);
|
setupOverlayViewController1();
|
||||||
mOverlayViewGlobalStateController.mShownSet.add(MOCK_OVERLAY_VIEW_CONTROLLER_NAME);
|
setOverlayViewControllerAsShowing(mOverlayViewController1);
|
||||||
|
when(mOverlayViewController2.isInflated()).thenReturn(true);
|
||||||
|
|
||||||
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
|
mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
|
||||||
|
|
||||||
verify(mRunnable, never()).run();
|
verify(mRunnable, never()).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hideView_viewControllerShown_hideRunnableCalled() {
|
public void hideView_viewControllerShown_hideRunnableCalled() {
|
||||||
when(mOverlayViewController.isInflated()).thenReturn(true);
|
setupOverlayViewController1();
|
||||||
mOverlayViewGlobalStateController.mShownSet.add(
|
setOverlayViewControllerAsShowing(mOverlayViewController1);
|
||||||
mOverlayViewController.getClass().getName());
|
|
||||||
|
|
||||||
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
|
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
|
||||||
|
|
||||||
verify(mRunnable).run();
|
verify(mRunnable).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hideView_viewControllerOnlyShown_nothingShown() {
|
public void hideView_viewControllerOnlyShown_noHighestZOrder() {
|
||||||
when(mOverlayViewController.isInflated()).thenReturn(true);
|
setupOverlayViewController1();
|
||||||
mOverlayViewGlobalStateController.mShownSet.add(
|
setOverlayViewControllerAsShowing(mOverlayViewController1);
|
||||||
mOverlayViewController.getClass().getName());
|
|
||||||
|
|
||||||
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
|
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
|
||||||
|
|
||||||
assertThat(mOverlayViewGlobalStateController.mShownSet.isEmpty()).isTrue();
|
assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hideView_viewControllerNotOnlyShown_navigationBarNotShown() {
|
public void hideView_viewControllerOnlyShown_nothingShown() {
|
||||||
when(mOverlayViewController.isInflated()).thenReturn(true);
|
setupOverlayViewController1();
|
||||||
mOverlayViewGlobalStateController.mShownSet.add(
|
setOverlayViewControllerAsShowing(mOverlayViewController1);
|
||||||
mOverlayViewController.getClass().getName());
|
|
||||||
mOverlayViewGlobalStateController.mShownSet.add(MOCK_OVERLAY_VIEW_CONTROLLER_NAME);
|
|
||||||
|
|
||||||
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
|
@Test
|
||||||
public void hideView_viewControllerNotOnlyShown_windowNotCollapsed() {
|
public void hideView_viewControllerNotOnlyShown_windowNotCollapsed() {
|
||||||
when(mOverlayViewController.isInflated()).thenReturn(true);
|
setupOverlayViewController1();
|
||||||
mOverlayViewGlobalStateController.mShownSet.add(
|
setOverlayViewControllerAsShowing(mOverlayViewController1);
|
||||||
mOverlayViewController.getClass().getName());
|
setupOverlayViewController2();
|
||||||
mOverlayViewGlobalStateController.mShownSet.add(MOCK_OVERLAY_VIEW_CONTROLLER_NAME);
|
setOverlayViewControllerAsShowing(mOverlayViewController2);
|
||||||
|
|
||||||
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
|
mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
|
||||||
|
|
||||||
verify(mSystemUIOverlayWindowController, never()).setWindowVisible(false);
|
verify(mSystemUIOverlayWindowController, never()).setWindowVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hideView_viewControllerOnlyShown_navigationBarShown() {
|
public void hideView_viewControllerOnlyShown_navigationBarShown() {
|
||||||
when(mOverlayViewController.isInflated()).thenReturn(true);
|
setupOverlayViewController1();
|
||||||
mOverlayViewGlobalStateController.mShownSet.add(
|
setOverlayViewControllerAsShowing(mOverlayViewController1);
|
||||||
mOverlayViewController.getClass().getName());
|
|
||||||
|
|
||||||
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
|
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
|
||||||
|
|
||||||
verify(mCarNavigationBarController).showBars();
|
verify(mCarNavigationBarController).showBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hideView_viewControllerOnlyShown_windowCollapsed() {
|
public void hideView_viewControllerOnlyShown_windowCollapsed() {
|
||||||
when(mOverlayViewController.isInflated()).thenReturn(true);
|
setupOverlayViewController1();
|
||||||
mOverlayViewGlobalStateController.mShownSet.add(
|
setOverlayViewControllerAsShowing(mOverlayViewController1);
|
||||||
mOverlayViewController.getClass().getName());
|
|
||||||
|
|
||||||
mOverlayViewGlobalStateController.hideView(mOverlayViewController, mRunnable);
|
mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
|
||||||
|
|
||||||
verify(mSystemUIOverlayWindowController).setWindowVisible(false);
|
verify(mSystemUIOverlayWindowController).setWindowVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void inflateView_notInflated_inflates() {
|
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
|
@Test
|
||||||
public void inflateView_alreadyInflated_doesNotInflate() {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user