Merge "Add Coordinators to the NewNotifPipeline"

This commit is contained in:
Beverly Tai
2019-12-04 18:24:30 +00:00
committed by Android (Google) Code Review
10 changed files with 621 additions and 6 deletions

View File

@@ -65,8 +65,18 @@ public interface NotificationLockscreenUserManager {
boolean needsRedaction(NotificationEntry entry);
/**
* Has the given user chosen to allow their private (full) notifications to be shown even
* when the lockscreen is in "public" (secure & locked) mode?
*/
boolean userAllowsPrivateNotificationsInPublic(int currentUserId);
/**
* Has the given user chosen to allow notifications to be shown even when the lockscreen is in
* "public" (secure & locked) mode?
*/
boolean userAllowsNotificationsInPublic(int userId);
/** Notified when the current user changes. */
interface UserChangedListener {
void onUserChanged(int userId);

View File

@@ -435,7 +435,7 @@ public class NotificationLockscreenUserManagerImpl implements
* Has the given user chosen to allow notifications to be shown even when the lockscreen is in
* "public" (secure & locked) mode?
*/
private boolean userAllowsNotificationsInPublic(int userHandle) {
public boolean userAllowsNotificationsInPublic(int userHandle) {
if (isCurrentProfile(userHandle) && userHandle != mCurrentUserId) {
return true;
}

View File

@@ -36,7 +36,10 @@ import com.android.systemui.statusbar.phone.StatusBar;
import javax.inject.Inject;
import javax.inject.Singleton;
/** Component which manages the various reasons a notification might be filtered out. */
/** Component which manages the various reasons a notification might be filtered out.*/
// TODO: delete NotificationFilter.java after migrating to new NotifPipeline b/145659174.
// Notification filtering is taken care of across the different Coordinators (mostly
// KeyguardCoordinator.java)
@Singleton
public class NotificationFilter {
@@ -109,7 +112,7 @@ public class NotificationFilter {
return true;
}
if (entry.isSuspended()) {
if (entry.getRanking().isSuspended()) {
return true;
}

View File

@@ -18,6 +18,8 @@ package com.android.systemui.statusbar.notification.collection;
import android.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -34,7 +36,8 @@ public class GroupEntry extends ListEntry {
private final List<NotificationEntry> mUnmodifiableChildren =
Collections.unmodifiableList(mChildren);
GroupEntry(String key) {
@VisibleForTesting
public GroupEntry(String key) {
super(key);
}
@@ -52,7 +55,8 @@ public class GroupEntry extends ListEntry {
return mUnmodifiableChildren;
}
void setSummary(@Nullable NotificationEntry summary) {
@VisibleForTesting
public void setSummary(@Nullable NotificationEntry summary) {
mSummary = summary;
}

View File

@@ -18,6 +18,8 @@ package com.android.systemui.statusbar.notification.collection;
import android.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
/**
* Abstract superclass for top-level entries, i.e. things that can appear in the final notification
* list shown to users. In practice, this means either GroupEntries or NotificationEntries.
@@ -49,7 +51,8 @@ public abstract class ListEntry {
return mParent;
}
void setParent(@Nullable GroupEntry parent) {
@VisibleForTesting
public void setParent(@Nullable GroupEntry parent) {
mParent = parent;
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2019 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 com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.NotifLifetimeExtender;
import com.android.systemui.statusbar.notification.collection.init.NewNotifPipeline;
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;
/**
* Interface for registering callbacks to the {@link NewNotifPipeline}.
*
* This includes registering:
* {@link Pluggable}s to the {@link NotifListBuilder}
* {@link NotifCollectionListener}s and {@link NotifLifetimeExtender}s to {@link NotifCollection}
*/
public interface Coordinator {
/**
* Called after the NewNotifPipeline is initialized.
* Coordinators should register their {@link Pluggable}s to the notifListBuilder
* and their {@link NotifCollectionListener}s and {@link NotifLifetimeExtender}s
* to the notifCollection in this method.
*/
void attach(NotifCollection notifCollection, NotifListBuilder notifListBuilder);
}

View File

@@ -0,0 +1,233 @@
/*
* Copyright (C) 2019 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 android.app.Notification.VISIBILITY_SECRET;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import androidx.annotation.MainThread;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* Filters low priority and privacy-sensitive notifications from the lockscreen.
*/
@Singleton
public class KeyguardCoordinator implements Coordinator {
private static final String TAG = "KeyguardNotificationCoordinator";
private final Context mContext;
private final Handler mMainHandler;
private final KeyguardStateController mKeyguardStateController;
private final NotificationLockscreenUserManager mLockscreenUserManager;
private final BroadcastDispatcher mBroadcastDispatcher;
private final StatusBarStateController mStatusBarStateController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Inject
public KeyguardCoordinator(
Context context,
@MainThread Handler mainThreadHandler,
KeyguardStateController keyguardStateController,
NotificationLockscreenUserManager lockscreenUserManager,
BroadcastDispatcher broadcastDispatcher,
StatusBarStateController statusBarStateController,
KeyguardUpdateMonitor keyguardUpdateMonitor) {
mContext = context;
mMainHandler = mainThreadHandler;
mKeyguardStateController = keyguardStateController;
mLockscreenUserManager = lockscreenUserManager;
mBroadcastDispatcher = broadcastDispatcher;
mStatusBarStateController = statusBarStateController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
}
@Override
public void attach(NotifCollection notifCollection, NotifListBuilder notifListBuilder) {
setupInvalidateNotifListCallbacks();
notifListBuilder.addFilter(mNotifFilter);
}
protected final NotifFilter mNotifFilter = new NotifFilter(TAG) {
@Override
public boolean shouldFilterOut(NotificationEntry entry, long now) {
final StatusBarNotification sbn = entry.getSbn();
// FILTER OUT the notification when the notification isn't for the current profile
if (!mLockscreenUserManager.isCurrentProfile(sbn.getUserId())) {
return true;
}
// FILTER OUT the notification when the keyguard is showing and...
if (mKeyguardStateController.isShowing()) {
// ... user settings or the device policy manager doesn't allow lockscreen
// notifications;
if (!mLockscreenUserManager.shouldShowLockscreenNotifications()) {
return true;
}
final int currUserId = mLockscreenUserManager.getCurrentUserId();
final int notifUserId = (sbn.getUser().getIdentifier() == UserHandle.USER_ALL)
? currUserId : sbn.getUser().getIdentifier();
// ... user is in lockdown
if (mKeyguardUpdateMonitor.isUserInLockdown(currUserId)
|| mKeyguardUpdateMonitor.isUserInLockdown(notifUserId)) {
return true;
}
// ... device is in public mode and the user's settings doesn't allow
// notifications to show in public mode
if (mLockscreenUserManager.isLockscreenPublicMode(currUserId)
|| mLockscreenUserManager.isLockscreenPublicMode(notifUserId)) {
if (entry.getRanking().getVisibilityOverride() == VISIBILITY_SECRET) {
return true;
}
if (!mLockscreenUserManager.userAllowsNotificationsInPublic(currUserId)
|| !mLockscreenUserManager.userAllowsNotificationsInPublic(
notifUserId)) {
return true;
}
}
// ... neither this notification nor its summary have high enough priority
// to be shown on the lockscreen
// TODO: grouping hasn't happened yet (b/145134683)
if (entry.getParent() != null) {
final NotificationEntry summary = entry.getParent().getRepresentativeEntry();
if (priorityExceedsLockscreenShowingThreshold(summary)) {
return false;
}
}
return !priorityExceedsLockscreenShowingThreshold(entry);
}
return false;
}
};
private boolean priorityExceedsLockscreenShowingThreshold(NotificationEntry entry) {
if (entry == null) {
return false;
}
if (NotificationUtils.useNewInterruptionModel(mContext)
&& hideSilentNotificationsOnLockscreen()) {
// TODO: make sure in the NewNotifPipeline that entry.isHighPriority() has been
// correctly updated before reaching this point (b/145134683)
return entry.isHighPriority();
} else {
return !entry.getRanking().isAmbient();
}
}
private boolean hideSilentNotificationsOnLockscreen() {
return Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 0;
}
private void setupInvalidateNotifListCallbacks() {
// register onKeyguardShowing callback
mKeyguardStateController.addCallback(mKeyguardCallback);
// register lockscreen settings changed callbacks:
final ContentObserver settingsObserver = new ContentObserver(mMainHandler) {
@Override
public void onChange(boolean selfChange, Uri uri) {
if (mKeyguardStateController.isShowing()) {
invalidateListFromFilter("Settings " + uri + " changed");
}
}
};
mContext.getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS),
false,
settingsObserver,
UserHandle.USER_ALL);
mContext.getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
true,
settingsObserver,
UserHandle.USER_ALL);
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ZEN_MODE),
false,
settingsObserver);
// register (maybe) public mode changed callbacks:
mStatusBarStateController.addCallback(mStatusBarStateListener);
mBroadcastDispatcher.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (mKeyguardStateController.isShowing()) {
// maybe public mode changed
invalidateListFromFilter(intent.getAction());
}
}}, new IntentFilter(Intent.ACTION_USER_SWITCHED));
}
private void invalidateListFromFilter(String reason) {
mNotifFilter.invalidateList();
}
private final KeyguardStateController.Callback mKeyguardCallback =
new KeyguardStateController.Callback() {
@Override
public void onUnlockedChanged() {
invalidateListFromFilter("onUnlockedChanged");
}
@Override
public void onKeyguardShowingChanged() {
invalidateListFromFilter("onKeyguardShowingChanged");
}
};
private final StatusBarStateController.StateListener mStatusBarStateListener =
new StatusBarStateController.StateListener() {
@Override
public void onStateChanged(int newState) {
// maybe public mode changed
invalidateListFromFilter("onStatusBarStateChanged");
}
};
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2019 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 com.android.systemui.Dumpable;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.NotifLifetimeExtender;
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* Handles the attachment of the {@link NotifListBuilder} and {@link NotifCollection} to the
* {@link Coordinator}s, so that the Coordinators can register their respective callbacks.
*/
@Singleton
public class NotifCoordinators implements Dumpable {
private static final String TAG = "NotifCoordinators";
private final List<Coordinator> mCoordinators = new ArrayList<>();
/**
* Creates all the coordinators.
*/
@Inject
public NotifCoordinators(KeyguardCoordinator keyguardNotificationCoordinator) {
mCoordinators.add(keyguardNotificationCoordinator);
// TODO: add new Coordinators here! (b/145134683, b/112656837)
}
/**
* Sends the initialized notifListBuilder and notifCollection to each
* coordinator to indicate the notifListBuilder is ready to accept {@link Pluggable}s
* and the notifCollection is ready to accept {@link NotifCollectionListener}s and
* {@link NotifLifetimeExtender}s.
*/
public void attach(NotifCollection notifCollection, NotifListBuilder notifListBuilder) {
for (Coordinator c : mCoordinators) {
c.attach(notifCollection, notifListBuilder);
}
}
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println(TAG + ":");
for (Coordinator c : mCoordinators) {
pw.println("\t" + c.getClass());
}
}
}

View File

@@ -23,6 +23,7 @@ import com.android.systemui.Dumpable;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifListBuilderImpl;
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -37,6 +38,7 @@ import javax.inject.Singleton;
public class NewNotifPipeline implements Dumpable {
private final NotifCollection mNotifCollection;
private final NotifListBuilderImpl mNotifPipeline;
private final NotifCoordinators mNotifPluggableCoordinators;
private final DumpController mDumpController;
private final FakePipelineConsumer mFakePipelineConsumer = new FakePipelineConsumer();
@@ -45,9 +47,11 @@ public class NewNotifPipeline implements Dumpable {
public NewNotifPipeline(
NotifCollection notifCollection,
NotifListBuilderImpl notifPipeline,
NotifCoordinators notifCoordinators,
DumpController dumpController) {
mNotifCollection = notifCollection;
mNotifPipeline = notifPipeline;
mNotifPluggableCoordinators = notifCoordinators;
mDumpController = dumpController;
}
@@ -57,6 +61,7 @@ public class NewNotifPipeline implements Dumpable {
mFakePipelineConsumer.attach(mNotifPipeline);
mNotifPipeline.attach(mNotifCollection);
mNotifCollection.attach(notificationService);
mNotifPluggableCoordinators.attach(mNotifCollection, mNotifPipeline);
Log.d(TAG, "Notif pipeline initialized");
@@ -66,6 +71,7 @@ public class NewNotifPipeline implements Dumpable {
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mFakePipelineConsumer.dump(fd, pw, args);
mNotifPluggableCoordinators.dump(fd, pw, args);
}
private static final String TAG = "NewNotifPipeline";

View File

@@ -0,0 +1,243 @@
/*
* Copyright (C) 2019 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 android.app.Notification.VISIBILITY_PUBLIC;
import static android.app.Notification.VISIBILITY_SECRET;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.when;
import android.os.Handler;
import android.os.UserHandle;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationEntryBuilder;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class KeyguardCoordinatorTest extends SysuiTestCase {
private static final int NOTIF_USER_ID = 0;
private static final int CURR_USER_ID = 1;
@Mock private Handler mMainHandler;
@Mock private KeyguardStateController mKeyguardStateController;
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
@Mock private BroadcastDispatcher mBroadcastDispatcher;
@Mock private StatusBarStateController mStatusBarStateController;
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private NotificationEntry mEntry;
private KeyguardCoordinator mKeyguardNotificationCoordinator;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mKeyguardNotificationCoordinator = new KeyguardCoordinator(
mContext, mMainHandler, mKeyguardStateController, mLockscreenUserManager,
mBroadcastDispatcher, mStatusBarStateController,
mKeyguardUpdateMonitor);
mEntry = new NotificationEntryBuilder()
.setUser(new UserHandle(NOTIF_USER_ID))
.build();
}
@Test
public void unfilteredState() {
// GIVEN an 'unfiltered-keyguard-showing' state
setupUnfilteredState();
// THEN don't filter out the entry
assertFalse(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0));
}
@Test
public void notificationNotForCurrentProfile() {
// GIVEN the notification isn't for the given user
setupUnfilteredState();
when(mLockscreenUserManager.isCurrentProfile(NOTIF_USER_ID)).thenReturn(false);
// THEN filter out the entry
assertTrue(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0));
}
@Test
public void keyguardNotShowing() {
// GIVEN the lockscreen isn't showing
setupUnfilteredState();
when(mKeyguardStateController.isShowing()).thenReturn(false);
// THEN don't filter out the entry
assertFalse(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0));
}
@Test
public void doNotShowLockscreenNotifications() {
// GIVEN an 'unfiltered-keyguard-showing' state
setupUnfilteredState();
// WHEN we shouldn't show any lockscreen notifications
when(mLockscreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false);
// THEN filter out the entry
assertTrue(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0));
}
@Test
public void lockdown() {
// GIVEN an 'unfiltered-keyguard-showing' state
setupUnfilteredState();
// WHEN the notification's user is in lockdown:
when(mKeyguardUpdateMonitor.isUserInLockdown(NOTIF_USER_ID)).thenReturn(true);
// THEN filter out the entry
assertTrue(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0));
}
@Test
public void publicMode_settingsDisallow() {
// GIVEN an 'unfiltered-keyguard-showing' state
setupUnfilteredState();
// WHEN the notification's user is in public mode and settings are configured to disallow
// notifications in public mode
when(mLockscreenUserManager.isLockscreenPublicMode(NOTIF_USER_ID)).thenReturn(true);
when(mLockscreenUserManager.userAllowsNotificationsInPublic(NOTIF_USER_ID))
.thenReturn(false);
// THEN filter out the entry
assertTrue(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0));
}
@Test
public void publicMode_notifDisallowed() {
// GIVEN an 'unfiltered-keyguard-showing' state
setupUnfilteredState();
// WHEN the notification's user is in public mode and settings are configured to disallow
// notifications in public mode
when(mLockscreenUserManager.isLockscreenPublicMode(CURR_USER_ID)).thenReturn(true);
mEntry.setRanking(new RankingBuilder()
.setKey(mEntry.getKey())
.setVisibilityOverride(VISIBILITY_SECRET).build());
// THEN filter out the entry
assertTrue(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0));
}
@Test
public void doesNotExceedThresholdToShow() {
// GIVEN an 'unfiltered-keyguard-showing' state
setupUnfilteredState();
// WHEN the notification doesn't exceed the threshold to show on the lockscreen
mEntry.setRanking(new RankingBuilder()
.setKey(mEntry.getKey())
.setImportance(IMPORTANCE_MIN)
.build());
// THEN filter out the entry
assertTrue(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0));
}
@Test
public void summaryExceedsThresholdToShow() {
// GIVEN an 'unfiltered-keyguard-showing' state
setupUnfilteredState();
// WHEN the notification doesn't exceed the threshold to show on the lockscreen
// but its summary does
mEntry.setRanking(new RankingBuilder()
.setKey(mEntry.getKey())
.setImportance(IMPORTANCE_MIN)
.build());
final NotificationEntry summary = new NotificationEntryBuilder().build();
summary.setRanking(new RankingBuilder()
.setKey(summary.getKey())
.setImportance(IMPORTANCE_HIGH)
.build());
final GroupEntry group = new GroupEntry(mEntry.getSbn().getGroupKey());
group.setSummary(summary);
mEntry.setParent(group);
// THEN don't filter out the entry
assertFalse(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0));
}
/**
* setup a state where the notification will not be filtered by the
* KeyguardNotificationCoordinator when the keyguard is showing.
*/
private void setupUnfilteredState() {
// notification is for current profile
when(mLockscreenUserManager.isCurrentProfile(NOTIF_USER_ID)).thenReturn(true);
// keyguard is showing
when(mKeyguardStateController.isShowing()).thenReturn(true);
// show notifications on the lockscreen
when(mLockscreenUserManager.shouldShowLockscreenNotifications()).thenReturn(true);
// neither the current user nor the notification's user is in lockdown
when(mLockscreenUserManager.getCurrentUserId()).thenReturn(CURR_USER_ID);
when(mKeyguardUpdateMonitor.isUserInLockdown(NOTIF_USER_ID)).thenReturn(false);
when(mKeyguardUpdateMonitor.isUserInLockdown(CURR_USER_ID)).thenReturn(false);
// not in public mode
when(mLockscreenUserManager.isLockscreenPublicMode(CURR_USER_ID)).thenReturn(false);
when(mLockscreenUserManager.isLockscreenPublicMode(NOTIF_USER_ID)).thenReturn(false);
// entry's ranking - should show on all lockscreens
// + priority of the notification exceeds the threshold to be shown on the lockscreen
mEntry.setRanking(new RankingBuilder()
.setKey(mEntry.getKey())
.setVisibilityOverride(VISIBILITY_PUBLIC)
.setImportance(IMPORTANCE_HIGH)
.build());
// settings allows notifications in public mode
when(mLockscreenUserManager.userAllowsNotificationsInPublic(CURR_USER_ID)).thenReturn(true);
when(mLockscreenUserManager.userAllowsNotificationsInPublic(NOTIF_USER_ID))
.thenReturn(true);
// notification doesn't have a summary
}
}