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

Commit 248e4315 authored by Bryce Lee's avatar Bryce Lee
Browse files

Do not show notifications on keyguard with communal.

This changelist suppressed notifications through a coordinator
when the communal view is present on keyguard.

Bug: 196867633
Test: atest CommunalCoordinatorTest
Change-Id: Ib76ec1ecd14cc46e4ef9a8d25b30ec843d793ff5
parent f8c928be
Loading
Loading
Loading
Loading
+70 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.notification.collection.coordinator;

import androidx.annotation.NonNull;

import com.android.systemui.communal.CommunalStateController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;

import javax.inject.Inject;

/**
 * {@link CommunalCoordinator} prevents notifications from showing on the keyguard when the communal
 * view is present.
 */
public class CommunalCoordinator implements Coordinator {
    final CommunalStateController mCommunalStateController;
    final NotificationEntryManager mNotificationEntryManager;
    final NotificationLockscreenUserManager mNotificationLockscreenUserManager;

    @Inject
    public CommunalCoordinator(NotificationEntryManager notificationEntryManager,
            NotificationLockscreenUserManager notificationLockscreenUserManager,
            CommunalStateController communalStateController) {
        mNotificationEntryManager = notificationEntryManager;
        mNotificationLockscreenUserManager = notificationLockscreenUserManager;
        mCommunalStateController = communalStateController;
    }

    final NotifFilter mFilter = new NotifFilter("CommunalCoordinator") {
        @Override
        public boolean shouldFilterOut(@NonNull NotificationEntry entry, long now) {
            return mCommunalStateController.getCommunalViewShowing();
        }
    };

    final CommunalStateController.Callback mStateCallback = new CommunalStateController.Callback() {
        @Override
        public void onCommunalViewShowingChanged() {
            mFilter.invalidateList();
            mNotificationEntryManager.updateNotifications("Communal mode state changed");
        }
    };

    @Override
    public void attach(@NonNull NotifPipeline pipeline) {
        pipeline.addPreGroupFilter(mFilter);
        mCommunalStateController.addCallback(mStateCallback);
        mNotificationLockscreenUserManager.addKeyguardNotificationSuppressor(
                entry -> mCommunalStateController.getCommunalViewShowing());
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -61,7 +61,8 @@ public class NotifCoordinators implements Dumpable {
            PreparationCoordinator preparationCoordinator,
            MediaCoordinator mediaCoordinator,
            SmartspaceDedupingCoordinator smartspaceDedupingCoordinator,
            VisualStabilityCoordinator visualStabilityCoordinator) {
            VisualStabilityCoordinator visualStabilityCoordinator,
            CommunalCoordinator communalCoordinator) {
        dumpManager.registerDumpable(TAG, this);

        mCoordinators.add(new HideLocallyDismissedNotifsCoordinator());
@@ -74,6 +75,7 @@ public class NotifCoordinators implements Dumpable {
        mCoordinators.add(conversationCoordinator);
        mCoordinators.add(mediaCoordinator);
        mCoordinators.add(visualStabilityCoordinator);
        mCoordinators.add(communalCoordinator);

        if (featureFlags.isSmartspaceDedupingEnabled()) {
            mCoordinators.add(smartspaceDedupingCoordinator);
+92 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.notification.collection.coordinator;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;

import android.test.suitebuilder.annotation.SmallTest;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.communal.CommunalStateController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;

import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;


@SmallTest
public class CommunalCoordinatorTest extends SysuiTestCase {
    @Mock
    CommunalStateController mCommunalStateController;
    @Mock
    NotificationEntryManager mNotificationEntryManager;
    @Mock
    NotificationLockscreenUserManager mNotificationLockscreenUserManager;
    @Mock
    NotifPipeline mNotifPipeline;
    @Mock
    NotificationEntry mNotificationEntry;
    @Mock
    Pluggable.PluggableListener mFilterListener;

    CommunalCoordinator mCoordinator;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mCoordinator = new CommunalCoordinator(mNotificationEntryManager,
                mNotificationLockscreenUserManager, mCommunalStateController);
    }

    @Test
    public void testNotificationSuppressionInCommunal() {
        mCoordinator.attach(mNotifPipeline);
        final ArgumentCaptor<CommunalStateController.Callback> stateCallbackCaptor =
                ArgumentCaptor.forClass(CommunalStateController.Callback.class);
        verify(mCommunalStateController).addCallback(stateCallbackCaptor.capture());

        final CommunalStateController.Callback stateCallback = stateCallbackCaptor.getValue();

        final ArgumentCaptor<NotifFilter> filterCaptor =
                ArgumentCaptor.forClass(NotifFilter.class);
        verify(mNotifPipeline).addPreGroupFilter(filterCaptor.capture());

        final NotifFilter filter = filterCaptor.getValue();

        // Verify that notifications are not filtered out by default.
        assert (!filter.shouldFilterOut(mNotificationEntry, 0));

        filter.setInvalidationListener(mFilterListener);

        // Verify that notifications are filtered out when communal is showing and that the filter
        // pipeline is notified.
        stateCallback.onCommunalViewShowingChanged();
        verify(mFilterListener).onPluggableInvalidated(any());
        verify(mNotificationEntryManager).updateNotifications(any());
        assert (filter.shouldFilterOut(mNotificationEntry, 0));

    }
}