Merge changes from topic "jr-onboard" into pi-dev
am: fd7d5779c3

Change-Id: I3313558f4438ec2ebb2c68e8490c7b287efe3faa
diff --git a/packages/SystemUI/res/layout/status_bar_dnd_suppressing_notifications.xml b/packages/SystemUI/res/layout/status_bar_dnd_suppressing_notifications.xml
new file mode 100644
index 0000000..eff9b36
--- /dev/null
+++ b/packages/SystemUI/res/layout/status_bar_dnd_suppressing_notifications.xml
@@ -0,0 +1,34 @@
+<!--
+    Copyright 2018, 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.
+-->
+
+<!-- Extends Framelayout -->
+<com.android.systemui.statusbar.DndSuppressingNotificationsView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/hidden_container"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:visibility="gone">
+    <TextView
+        android:id="@+id/hidden_notifications"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:minHeight="64dp"
+        android:paddingTop="28dp"
+        android:gravity="top|center_horizontal"
+        android:textColor="?attr/wallpaperTextColor"
+        android:textSize="16sp"
+        android:text="@string/dnd_suppressing_shade_text"/>
+</com.android.systemui.statusbar.DndSuppressingNotificationsView>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 697ab06..9d72184 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1062,7 +1062,7 @@
     <string name="manage_notifications_text">Manage notifications</string>
 
     <!-- The text to show in the notifications shade when dnd is suppressing notifications. [CHAR LIMIT=100] -->
-    <string name="dnd_suppressing_shade_text">Do Not Disturb is hiding notifications</string>
+    <string name="dnd_suppressing_shade_text">Notifications hidden by Do Not Disturb</string>
 
     <!-- Media projection permission dialog action text. [CHAR LIMIT=60] -->
     <string name="media_projection_action_text">Start now</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DndSuppressingNotificationsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DndSuppressingNotificationsView.java
new file mode 100644
index 0000000..db3a02d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DndSuppressingNotificationsView.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 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
+ */
+
+package com.android.systemui.statusbar;
+
+import android.annotation.ColorInt;
+import android.annotation.DrawableRes;
+import android.annotation.IntegerRes;
+import android.annotation.StringRes;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Configuration;
+import android.graphics.drawable.Icon;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.stack.ExpandableViewState;
+import com.android.systemui.statusbar.stack.StackScrollState;
+
+public class DndSuppressingNotificationsView extends StackScrollerDecorView {
+
+    private TextView mText;
+    private @StringRes int mTextId = R.string.dnd_suppressing_shade_text;
+
+    public DndSuppressingNotificationsView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mText.setText(mTextId);
+    }
+
+    @Override
+    protected View findContentView() {
+        return findViewById(R.id.hidden_container);
+    }
+
+    @Override
+    protected View findSecondaryView() {
+        return null;
+    }
+
+    public void setColor(@ColorInt int color) {
+        mText.setTextColor(color);
+    }
+
+    public void setOnContentClickListener(OnClickListener listener) {
+        mText.setOnClickListener(listener);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mText = findViewById(R.id.hidden_notifications);
+    }
+
+    @Override
+    public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
+        return new DndSuppressingViewState();
+    }
+
+    public class DndSuppressingViewState extends ExpandableViewState {
+        @Override
+        public void applyToView(View view) {
+            super.applyToView(view);
+            if (view instanceof DndSuppressingNotificationsView) {
+                DndSuppressingNotificationsView dndView = (DndSuppressingNotificationsView) view;
+                boolean visible = this.clipTopAmount <= mText.getPaddingTop() * 0.6f;
+                dndView.performVisibilityAnimation(visible && !dndView.willBeGone());
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index b650944..8bb73da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -199,6 +199,7 @@
     private ValueAnimator mQsSizeChangeAnimator;
 
     private boolean mShowEmptyShadeView;
+    private boolean mShowDndView;
 
     private boolean mQsScrimEnabled = true;
     private boolean mLastAnnouncementWasQuickSettings;
@@ -1599,8 +1600,8 @@
         // When only empty shade view is visible in QS collapsed state, simulate that we would have
         // it in expanded QS state as well so we don't run into troubles when fading the view in/out
         // and expanding/collapsing the whole panel from/to quick settings.
-        if (mNotificationStackScroller.getNotGoneChildCount() == 0
-                && mShowEmptyShadeView) {
+        if ((mNotificationStackScroller.getNotGoneChildCount() == 0
+                && mShowEmptyShadeView) || mShowDndView) {
             notificationHeight = mNotificationStackScroller.getEmptyShadeViewHeight();
         }
         int maxQsHeight = mQsMaxExpansionHeight;
@@ -2243,13 +2244,17 @@
         return mDozing;
     }
 
+    public void showDndView(boolean dndViewVisible) {
+        mShowDndView = dndViewVisible;
+        mNotificationStackScroller.updateDndView(mShowDndView && !mQsExpanded);
+    }
+
     public void showEmptyShadeView(boolean emptyShadeViewVisible) {
         mShowEmptyShadeView = emptyShadeViewVisible;
         updateEmptyShadeView();
     }
 
     private void updateEmptyShadeView() {
-
         // Hide "No notifications" in QS.
         mNotificationStackScroller.updateEmptyShadeView(mShowEmptyShadeView && !mQsExpanded);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index ff0adb6..57a3556 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -20,6 +20,7 @@
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.StatusBarManager.windowStateToString;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
+import static android.provider.Settings.Global.ZEN_MODE_OFF;
 
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
@@ -168,6 +169,7 @@
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 import com.android.systemui.qs.QSFragment;
@@ -188,6 +190,7 @@
 import com.android.systemui.statusbar.BackDropView;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CrossFadeHelper;
+import com.android.systemui.statusbar.DndSuppressingNotificationsView;
 import com.android.systemui.statusbar.DragDownHelper;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -413,7 +416,7 @@
     protected NotificationViewHierarchyManager mViewHierarchyManager;
     protected AppOpsListener mAppOpsListener;
     protected KeyguardViewMediator mKeyguardViewMediator;
-    private ZenModeController mZenController;
+    protected ZenModeController mZenController;
 
     /**
      * Helper that is responsible for showing the right toast when a disallowed activity operation
@@ -878,6 +881,7 @@
         mVisualStabilityManager.setVisibilityLocationProvider(mStackScroller);
 
         inflateEmptyShadeView();
+        inflateDndView();
         inflateFooterView();
 
         mBackdrop = mStatusBarWindow.findViewById(R.id.backdrop);
@@ -1145,6 +1149,7 @@
     protected void reevaluateStyles() {
         inflateFooterView();
         updateFooter();
+        inflateDndView();
         inflateEmptyShadeView();
         updateEmptyShadeView();
     }
@@ -1166,6 +1171,19 @@
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
     }
 
+    private void inflateDndView() {
+        if (mStackScroller == null) {
+            return;
+        }
+        mDndView = (DndSuppressingNotificationsView) LayoutInflater.from(mContext).inflate(
+                R.layout.status_bar_dnd_suppressing_notifications, mStackScroller, false);
+        mDndView.setOnContentClickListener(v -> {
+            Intent intent = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
+            startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP);
+        });
+        mStackScroller.setDndView(mDndView);
+    }
+
     private void inflateFooterView() {
         if (mStackScroller == null) {
             return;
@@ -1460,9 +1478,11 @@
     @VisibleForTesting
     protected void updateFooter() {
         boolean showFooterView = mState != StatusBarState.KEYGUARD
+                && !areNotificationsHidden()
                 && mEntryManager.getNotificationData().getActiveNotifications().size() != 0
                 && !mRemoteInputManager.getController().isRemoteInputActive();
         boolean showDismissView = mClearAllEnabled && mState != StatusBarState.KEYGUARD
+                && !areNotificationsHidden()
                 && hasActiveClearableNotifications();
 
         mStackScroller.updateFooterView(showFooterView, showDismissView);
@@ -1485,10 +1505,13 @@
         return false;
     }
 
-    private void updateEmptyShadeView() {
-        boolean showEmptyShadeView =
-                mState != StatusBarState.KEYGUARD &&
-                        mEntryManager.getNotificationData().getActiveNotifications().size() == 0;
+    @VisibleForTesting
+    protected void updateEmptyShadeView() {
+        boolean showDndView = mState != StatusBarState.KEYGUARD && areNotificationsHidden();
+        boolean showEmptyShadeView = !showDndView
+                && mState != StatusBarState.KEYGUARD
+                && mEntryManager.getNotificationData().getActiveNotifications().size() == 0;
+        mNotificationPanel.showDndView(showDndView);
         mNotificationPanel.showEmptyShadeView(showEmptyShadeView);
     }
 
@@ -4988,6 +5011,7 @@
     protected NotificationShelf mNotificationShelf;
     protected FooterView mFooterView;
     protected EmptyShadeView mEmptyShadeView;
+    protected DndSuppressingNotificationsView mDndView;
 
     protected AssistManager mAssistManager;
 
@@ -5472,6 +5496,11 @@
                     mStackScroller.getChildCount() - offsetFromEnd++);
         }
 
+        if (mDndView != null) {
+            mStackScroller.changeViewPosition(mDndView,
+                    mStackScroller.getChildCount() - offsetFromEnd++);
+        }
+
         mStackScroller.changeViewPosition(mEmptyShadeView,
                 mStackScroller.getChildCount() - offsetFromEnd++);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 5275e27..eeaa6cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -81,6 +81,7 @@
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.DndSuppressingNotificationsView;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
@@ -236,6 +237,7 @@
     protected boolean mScrollingEnabled;
     protected FooterView mFooterView;
     protected EmptyShadeView mEmptyShadeView;
+    protected DndSuppressingNotificationsView mDndView;
     private boolean mDismissAllInProgress;
     private boolean mFadeNotificationsOnDismiss;
 
@@ -1006,7 +1008,8 @@
     private float getAppearEndPosition() {
         int appearPosition;
         int notGoneChildCount = getNotGoneChildCount();
-        if (mEmptyShadeView.getVisibility() == GONE && notGoneChildCount != 0) {
+        if ((mEmptyShadeView.getVisibility() == GONE && mDndView.getVisibility() == GONE)
+                && notGoneChildCount != 0) {
             if (isHeadsUpTransition()
                     || (mHeadsUpManager.hasPinnedHeadsUp() && !mAmbientState.isDark())) {
                 appearPosition = getTopHeadsUpPinnedHeight();
@@ -1016,6 +1019,8 @@
                     appearPosition += mShelf.getIntrinsicHeight();
                 }
             }
+        } else if (mEmptyShadeView.getVisibility() == GONE) {
+            appearPosition = mDndView.getHeight();
         } else {
             appearPosition = mEmptyShadeView.getHeight();
         }
@@ -2608,19 +2613,6 @@
         return mShelf.getVisibility() == GONE ? 0 : mShelf.getIntrinsicHeight();
     }
 
-    public int getFirstChildIntrinsicHeight() {
-        final ExpandableView firstChild = getFirstChildNotGone();
-        int firstChildMinHeight = firstChild != null
-                ? firstChild.getIntrinsicHeight()
-                : mEmptyShadeView != null
-                        ? mEmptyShadeView.getIntrinsicHeight()
-                        : mCollapsedSize;
-        if (mOwnScrollY > 0) {
-            firstChildMinHeight = Math.max(firstChildMinHeight - mOwnScrollY, mCollapsedSize);
-        }
-        return firstChildMinHeight;
-    }
-
     public float getTopPaddingOverflow() {
         return mTopPaddingOverflow;
     }
@@ -3918,6 +3910,7 @@
         final int textColor = Utils.getColorAttr(context, R.attr.wallpaperTextColor);
         mFooterView.setTextColor(textColor);
         mEmptyShadeView.setTextColor(textColor);
+        mDndView.setColor(textColor);
     }
 
     public void goToFullShade(long delay) {
@@ -3925,6 +3918,7 @@
             mFooterView.setInvisible();
         }
         mEmptyShadeView.setInvisible();
+        mDndView.setInvisible();
         mGoToFullShadeNeedsAnimation = true;
         mGoToFullShadeDelay = delay;
         mNeedsAnimation = true;
@@ -4076,25 +4070,39 @@
         int newVisibility = visible ? VISIBLE : GONE;
 
         boolean changedVisibility = oldVisibility != newVisibility;
-        if (changedVisibility || newVisibility != GONE) {
+        if (changedVisibility) {
             if (newVisibility != GONE) {
-                int oldText = mEmptyShadeView.getTextResource();
-                int newText;
-                if (mStatusBar.areNotificationsHidden()) {
-                    newText = R.string.dnd_suppressing_shade_text;
-                } else {
-                    newText = R.string.empty_shade_text;
-                }
-                if (changedVisibility || !Objects.equals(oldText, newText)) {
-                    mEmptyShadeView.setText(newText);
-                    showFooterView(mEmptyShadeView);
-                }
+                showFooterView(mEmptyShadeView);
             } else {
                 hideFooterView(mEmptyShadeView, true);
             }
         }
     }
 
+    public void setDndView(DndSuppressingNotificationsView dndView) {
+        int index = -1;
+        if (mDndView != null) {
+            index = indexOfChild(mDndView);
+            removeView(mDndView);
+        }
+        mDndView = dndView;
+        addView(mDndView, index);
+    }
+
+    public void updateDndView(boolean visible) {
+        int oldVisibility = mDndView.willBeGone() ? GONE : mDndView.getVisibility();
+        int newVisibility = visible ? VISIBLE : GONE;
+
+        boolean changedVisibility = oldVisibility != newVisibility;
+        if (changedVisibility) {
+            if (newVisibility != GONE) {
+                showFooterView(mDndView);
+            } else {
+                hideFooterView(mDndView, true);
+            }
+        }
+    }
+
     public void updateFooterView(boolean visible, boolean showDismissView) {
         if (mFooterView == null) {
             return;
@@ -4119,10 +4127,16 @@
         } else {
             footerView.setInvisible();
         }
-        footerView.setVisibility(VISIBLE);
-        footerView.setWillBeGone(false);
-        updateContentHeight();
-        notifyHeightChangeListener(footerView);
+        Runnable onShowFinishRunnable = new Runnable() {
+            @Override
+            public void run() {
+                footerView.setVisibility(VISIBLE);
+                footerView.setWillBeGone(false);
+                updateContentHeight();
+                notifyHeightChangeListener(footerView);
+            }
+        };
+        footerView.performVisibilityAnimation(true, onShowFinishRunnable);
     }
 
     private void hideFooterView(StackScrollerDecorView footerView, boolean isButtonVisible) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 37e0005..41cf869 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -78,6 +78,7 @@
 import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.AppOpsListener;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.DndSuppressingNotificationsView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.FooterView;
 import com.android.systemui.statusbar.FooterViewButton;
@@ -103,6 +104,7 @@
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.KeyguardMonitorImpl;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 import org.junit.Before;
@@ -132,6 +134,7 @@
     @Mock private ScrimController mScrimController;
     @Mock private ArrayList<Entry> mNotificationList;
     @Mock private FingerprintUnlockController mFingerprintUnlockController;
+    @Mock private ZenModeController mZenController;
     @Mock private NotificationData mNotificationData;
 
     // Mock dependencies:
@@ -163,6 +166,7 @@
         mDependency.injectTestDependency(NotificationListener.class, mNotificationListener);
         mDependency.injectTestDependency(KeyguardMonitor.class, mock(KeyguardMonitorImpl.class));
         mDependency.injectTestDependency(AppOpsListener.class, mock(AppOpsListener.class));
+        mDependency.injectTestDependency(ZenModeController.class, mZenController);
 
         mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
         mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
@@ -213,7 +217,7 @@
                 mRemoteInputManager, mock(NotificationGroupManager.class),
                 mock(FalsingManager.class), mock(StatusBarWindowManager.class),
                 mock(NotificationIconAreaController.class), mock(DozeScrimController.class),
-                mock(NotificationShelf.class), mLockscreenUserManager,
+                mock(NotificationShelf.class), mLockscreenUserManager, mZenController,
                 mock(CommandQueue.class));
         mStatusBar.mContext = mContext;
         mStatusBar.mComponents = mContext.getComponents();
@@ -676,6 +680,60 @@
     }
 
     @Test
+    public void testDNDView_atEnd() {
+        // add footer
+        mStatusBar.reevaluateStyles();
+
+        // add notification
+        ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
+        mStackScroller.addContainerView(row);
+
+        mStatusBar.onUpdateRowStates();
+
+        // move dnd view to end
+        verify(mStackScroller).changeViewPosition(any(FooterView.class), eq(-1 /* end */));
+        verify(mStackScroller).changeViewPosition(any(DndSuppressingNotificationsView.class),
+                eq(-2 /* end */));
+    }
+
+    @Test
+    public void updateEmptyShade_nonNotificationsDndOff() {
+        mStatusBar.setBarStateForTest(StatusBarState.SHADE);
+        when(mNotificationData.getActiveNotifications()).thenReturn(new ArrayList<>());
+        assertEquals(0, mEntryManager.getNotificationData().getActiveNotifications().size());
+
+        mStatusBar.updateEmptyShadeView();
+        verify(mNotificationPanelView).showDndView(false);
+        verify(mNotificationPanelView).showEmptyShadeView(true);
+    }
+
+    @Test
+    public void updateEmptyShade_noNotificationsDndOn() {
+        mStatusBar.setBarStateForTest(StatusBarState.SHADE);
+        when(mNotificationData.getActiveNotifications()).thenReturn(new ArrayList<>());
+        assertEquals(0, mEntryManager.getNotificationData().getActiveNotifications().size());
+        when(mZenController.areNotificationsHiddenInShade()).thenReturn(true);
+
+        mStatusBar.updateEmptyShadeView();
+        verify(mNotificationPanelView).showDndView(true);
+        verify(mNotificationPanelView).showEmptyShadeView(false);
+    }
+
+    @Test
+    public void updateEmptyShade_yesNotificationsDndOff() {
+        mStatusBar.setBarStateForTest(StatusBarState.SHADE);
+        ArrayList<Entry> entries = new ArrayList<>();
+        entries.add(mock(Entry.class));
+        when(mNotificationData.getActiveNotifications()).thenReturn(entries);
+        assertEquals(1, mEntryManager.getNotificationData().getActiveNotifications().size());
+        when(mZenController.areNotificationsHiddenInShade()).thenReturn(false);
+
+        mStatusBar.updateEmptyShadeView();
+        verify(mNotificationPanelView).showDndView(false);
+        verify(mNotificationPanelView).showEmptyShadeView(false);
+    }
+
+    @Test
     public void testSetState_changesIsFullScreenUserSwitcherState() {
         mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
         assertFalse(mStatusBar.isFullScreenUserSwitcherState());
@@ -721,6 +779,7 @@
                 DozeScrimController dozeScrimController,
                 NotificationShelf notificationShelf,
                 NotificationLockscreenUserManager notificationLockscreenUserManager,
+                ZenModeController zenController,
                 CommandQueue commandQueue) {
             mStatusBarKeyguardViewManager = man;
             mUnlockMethodCache = unlock;
@@ -749,6 +808,7 @@
             mDozeScrimController = dozeScrimController;
             mNotificationShelf = notificationShelf;
             mLockscreenUserManager = notificationLockscreenUserManager;
+            mZenController = zenController;
             mCommandQueue = commandQueue;
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
index eeb4209..3d17ec4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
@@ -18,6 +18,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
@@ -34,6 +35,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.TestableDependency;
+import com.android.systemui.statusbar.DndSuppressingNotificationsView;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.FooterView;
 import com.android.systemui.statusbar.NotificationBlockingHelperManager;
@@ -69,6 +71,7 @@
     @Mock private NotificationGroupManager mGroupManager;
     @Mock private ExpandHelper mExpandHelper;
     @Mock private EmptyShadeView mEmptyShadeView;
+    @Mock private DndSuppressingNotificationsView mDndView;
 
     @Before
     @UiThreadTest
@@ -86,6 +89,7 @@
         mStackScroller.setHeadsUpManager(mHeadsUpManager);
         mStackScroller.setGroupManager(mGroupManager);
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
+        mStackScroller.setDndView(mDndView);
 
         // Stub out functionality that isn't necessary to test.
         doNothing().when(mBar)
@@ -120,40 +124,6 @@
     }
 
     @Test
-    public void updateEmptyView_dndSuppressing() {
-        when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        when(mBar.areNotificationsHidden()).thenReturn(true);
-
-        mStackScroller.updateEmptyShadeView(true);
-
-        verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
-    }
-
-    @Test
-    public void updateEmptyView_dndNotSuppressing() {
-        mStackScroller.setEmptyShadeView(mEmptyShadeView);
-        when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        when(mBar.areNotificationsHidden()).thenReturn(false);
-
-        mStackScroller.updateEmptyShadeView(true);
-
-        verify(mEmptyShadeView).setText(R.string.empty_shade_text);
-    }
-
-    @Test
-    public void updateEmptyView_noNotificationsToDndSuppressing() {
-        mStackScroller.setEmptyShadeView(mEmptyShadeView);
-        when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        when(mBar.areNotificationsHidden()).thenReturn(false);
-        mStackScroller.updateEmptyShadeView(true);
-        verify(mEmptyShadeView).setText(R.string.empty_shade_text);
-
-        when(mBar.areNotificationsHidden()).thenReturn(true);
-        mStackScroller.updateEmptyShadeView(true);
-        verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
-    }
-
-    @Test
     @UiThreadTest
     public void testSetExpandedHeight_blockingHelperManagerReceivedCallbacks() {
         mStackScroller.setExpandedHeight(0f);
@@ -173,7 +143,7 @@
 
         mStackScroller.updateFooterView(true, false);
 
-        verify(view).setVisibility(View.VISIBLE);
+        verify(view).performVisibilityAnimation(eq(true), any());
         verify(view).performSecondaryVisibilityAnimation(false);
     }
 
@@ -186,7 +156,7 @@
 
         mStackScroller.updateFooterView(true, true);
 
-        verify(view).setVisibility(View.VISIBLE);
+        verify(view).performVisibilityAnimation(eq(true), any());
         verify(view).performSecondaryVisibilityAnimation(true);
     }
 }