Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb2e9191 authored by Ned Burns's avatar Ned Burns Committed by android-build-merger
Browse files

Merge "Hide silent notifications section header on lockscreen" into qt-dev

am: 25443162

Change-Id: Iac6f4835468e63b36adfbc47a21f2ab0467a9822
parents 0cb1786b 25443162
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -1118,10 +1118,10 @@
    <string name="manage_notifications_text">Manage</string>
    <string name="manage_notifications_text">Manage</string>


    <!-- Section title for notifications that do not vibrate or make noise. [CHAR LIMIT=40] -->
    <!-- Section title for notifications that do not vibrate or make noise. [CHAR LIMIT=40] -->
    <string name="notification_section_header_gentle">Gentle notifications</string>
    <string name="notification_section_header_gentle">Silent notifications</string>


    <!-- Content description for accessibility: Tapping this button will dismiss all gentle notifications [CHAR LIMIT=NONE] -->
    <!-- Content description for accessibility: Tapping this button will dismiss all gentle notifications [CHAR LIMIT=NONE] -->
    <string name="accessibility_notification_section_header_gentle_clear_all">Clear all gentle notifications</string>
    <string name="accessibility_notification_section_header_gentle_clear_all">Clear all silent notifications</string>


    <!-- The text to show in the notifications shade when dnd is suppressing notifications. [CHAR LIMIT=100] -->
    <!-- The text to show in the notifications shade when dnd is suppressing notifications. [CHAR LIMIT=100] -->
    <string name="dnd_suppressing_shade_text">Notifications paused by Do Not Disturb</string>
    <string name="dnd_suppressing_shade_text">Notifications paused by Do Not Disturb</string>
+18 −3
Original line number Original line Diff line number Diff line
@@ -28,6 +28,8 @@ import android.view.View;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;


@@ -40,18 +42,22 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvider {
class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvider {
    private final NotificationStackScrollLayout mParent;
    private final NotificationStackScrollLayout mParent;
    private final ActivityStarter mActivityStarter;
    private final ActivityStarter mActivityStarter;
    private final StatusBarStateController mStatusBarStateController;
    private final boolean mUseMultipleSections;
    private final boolean mUseMultipleSections;


    private SectionHeaderView mGentleHeader;
    private SectionHeaderView mGentleHeader;
    private boolean mGentleHeaderVisible = false;
    private boolean mGentleHeaderVisible = false;
    @Nullable private ExpandableNotificationRow mFirstGentleNotif;
    @Nullable private View.OnClickListener mOnClearGentleNotifsClickListener;
    @Nullable private View.OnClickListener mOnClearGentleNotifsClickListener;


    NotificationSectionsManager(
    NotificationSectionsManager(
            NotificationStackScrollLayout parent,
            NotificationStackScrollLayout parent,
            ActivityStarter activityStarter,
            ActivityStarter activityStarter,
            StatusBarStateController statusBarStateController,
            boolean useMultipleSections) {
            boolean useMultipleSections) {
        mParent = parent;
        mParent = parent;
        mActivityStarter = activityStarter;
        mActivityStarter = activityStarter;
        mStatusBarStateController = statusBarStateController;
        mUseMultipleSections = useMultipleSections;
        mUseMultipleSections = useMultipleSections;
    }
    }


@@ -92,7 +98,7 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide


    @Override
    @Override
    public boolean beginsSection(View view) {
    public boolean beginsSection(View view) {
        return view == mGentleHeader;
        return view == getFirstLowPriorityChild();
    }
    }


    /**
    /**
@@ -104,6 +110,7 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide
            return;
            return;
        }
        }


        mFirstGentleNotif = null;
        int firstGentleNotifIndex = -1;
        int firstGentleNotifIndex = -1;


        final int n = mParent.getChildCount();
        final int n = mParent.getChildCount();
@@ -114,6 +121,7 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide
                ExpandableNotificationRow row = (ExpandableNotificationRow) child;
                ExpandableNotificationRow row = (ExpandableNotificationRow) child;
                if (!row.getEntry().isHighPriority()) {
                if (!row.getEntry().isHighPriority()) {
                    firstGentleNotifIndex = i;
                    firstGentleNotifIndex = i;
                    mFirstGentleNotif = row;
                    break;
                    break;
                }
                }
            }
            }
@@ -126,9 +134,12 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide
    }
    }


    private void adjustGentleHeaderVisibilityAndPosition(int firstGentleNotifIndex) {
    private void adjustGentleHeaderVisibilityAndPosition(int firstGentleNotifIndex) {
        final boolean showGentleHeader =
                firstGentleNotifIndex != -1
                        && mStatusBarStateController.getState() != StatusBarState.KEYGUARD;
        final int currentHeaderIndex = mParent.indexOfChild(mGentleHeader);
        final int currentHeaderIndex = mParent.indexOfChild(mGentleHeader);


        if (firstGentleNotifIndex == -1) {
        if (!showGentleHeader) {
            if (mGentleHeaderVisible) {
            if (mGentleHeaderVisible) {
                mGentleHeaderVisible = false;
                mGentleHeaderVisible = false;
                mParent.removeView(mGentleHeader);
                mParent.removeView(mGentleHeader);
@@ -208,7 +219,11 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide


    @Nullable
    @Nullable
    private ActivatableNotificationView getFirstLowPriorityChild() {
    private ActivatableNotificationView getFirstLowPriorityChild() {
        return mGentleHeaderVisible ? mGentleHeader : null;
        if (mGentleHeaderVisible) {
            return mGentleHeader;
        } else {
            return mFirstGentleNotif;
        }
    }
    }


    @Nullable
    @Nullable
+3 −1
Original line number Original line Diff line number Diff line
@@ -518,7 +518,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
            NotificationRoundnessManager notificationRoundnessManager,
            NotificationRoundnessManager notificationRoundnessManager,
            AmbientPulseManager ambientPulseManager,
            AmbientPulseManager ambientPulseManager,
            DynamicPrivacyController dynamicPrivacyController,
            DynamicPrivacyController dynamicPrivacyController,
            ActivityStarter activityStarter) {
            ActivityStarter activityStarter,
            StatusBarStateController statusBarStateController) {
        super(context, attrs, 0, 0);
        super(context, attrs, 0, 0);
        Resources res = getResources();
        Resources res = getResources();


@@ -534,6 +535,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
                new NotificationSectionsManager(
                new NotificationSectionsManager(
                        this,
                        this,
                        activityStarter,
                        activityStarter,
                        statusBarStateController,
                        NotificationUtils.useNewInterruptionModel(context));
                        NotificationUtils.useNewInterruptionModel(context));
        mSectionsManager.inflateViews(context);
        mSectionsManager.inflateViews(context);
        mSectionsManager.setOnClearGentleNotifsClickListener(v -> {
        mSectionsManager.setOnClearGentleNotifsClickListener(v -> {
+53 −1
Original line number Original line Diff line number Diff line
@@ -38,6 +38,8 @@ import androidx.test.filters.SmallTest;


import com.android.systemui.ActivityStarterDelegate;
import com.android.systemui.ActivityStarterDelegate;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;


import org.junit.Before;
import org.junit.Before;
@@ -57,17 +59,24 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {


    @Mock private NotificationStackScrollLayout mNssl;
    @Mock private NotificationStackScrollLayout mNssl;
    @Mock private ActivityStarterDelegate mActivityStarterDelegate;
    @Mock private ActivityStarterDelegate mActivityStarterDelegate;
    @Mock private StatusBarStateController mStatusBarStateController;


    private NotificationSectionsManager mSectionsManager;
    private NotificationSectionsManager mSectionsManager;


    @Before
    @Before
    public void setUp() {
    public void setUp() {
        mSectionsManager = new NotificationSectionsManager(mNssl, mActivityStarterDelegate, true);
        mSectionsManager =
                new NotificationSectionsManager(
                        mNssl,
                        mActivityStarterDelegate,
                        mStatusBarStateController,
                        true);
        // Required in order for the header inflation to work properly
        // Required in order for the header inflation to work properly
        when(mNssl.generateLayoutParams(any(AttributeSet.class)))
        when(mNssl.generateLayoutParams(any(AttributeSet.class)))
                .thenReturn(new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
                .thenReturn(new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
        mSectionsManager.inflateViews(mContext);
        mSectionsManager.inflateViews(mContext);
        when(mNssl.indexOfChild(any(View.class))).thenReturn(-1);
        when(mNssl.indexOfChild(any(View.class))).thenReturn(-1);
        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
    }
    }


    @Test
    @Test
@@ -185,6 +194,49 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
        verify(mNssl).addView(mSectionsManager.getGentleHeaderView(), 1);
        verify(mNssl).addView(mSectionsManager.getGentleHeaderView(), 1);
    }
    }


    @Test
    public void testHeaderNotShownOnLockscreen() {
        // GIVEN a stack of HI and LO notifs on the lockscreen
        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
        setStackState(ChildType.HIPRI, ChildType.HIPRI, ChildType.HIPRI, ChildType.LOPRI);

        // WHEN we update the section headers
        mSectionsManager.updateSectionBoundaries();

        // Then the section header is not added
        verify(mNssl, never()).addView(eq(mSectionsManager.getGentleHeaderView()), anyInt());
    }

    @Test
    public void testHeaderShownWhenEnterLockscreen() {
        // GIVEN a stack of HI and LO notifs on the lockscreen
        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
        setStackState(ChildType.HIPRI, ChildType.HIPRI, ChildType.HIPRI, ChildType.LOPRI);
        mSectionsManager.updateSectionBoundaries();

        // WHEN we unlock
        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
        mSectionsManager.updateSectionBoundaries();

        // Then the section header is added
        verify(mNssl).addView(mSectionsManager.getGentleHeaderView(), 3);
    }

    @Test
    public void testHeaderHiddenWhenEnterLockscreen() {
        // GIVEN a stack of HI and LO notifs on the shade
        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED);
        setStackState(ChildType.HIPRI, ChildType.HIPRI, ChildType.HIPRI, ChildType.LOPRI);
        mSectionsManager.updateSectionBoundaries();

        // WHEN we go back to the keyguard
        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
        mSectionsManager.updateSectionBoundaries();

        // Then the section header is removed
        verify(mNssl).removeView(eq(mSectionsManager.getGentleHeaderView()));
    }

    private enum ChildType { HEADER, HIPRI, LOPRI }
    private enum ChildType { HEADER, HIPRI, LOPRI }


    private void setStackState(ChildType... children) {
    private void setStackState(ChildType... children) {
+2 −1
Original line number Original line Diff line number Diff line
@@ -153,7 +153,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
                true /* allowLongPress */, mNotificationRoundnessManager,
                true /* allowLongPress */, mNotificationRoundnessManager,
                new AmbientPulseManager(mContext),
                new AmbientPulseManager(mContext),
                mock(DynamicPrivacyController.class),
                mock(DynamicPrivacyController.class),
                mock(ActivityStarterDelegate.class));
                mock(ActivityStarterDelegate.class),
                mock(StatusBarStateController.class));
        mStackScroller = spy(mStackScrollerInternal);
        mStackScroller = spy(mStackScrollerInternal);
        mStackScroller.setShelf(notificationShelf);
        mStackScroller.setShelf(notificationShelf);
        mStackScroller.setStatusBar(mBar);
        mStackScroller.setStatusBar(mBar);