Merge "Add Coordinators to the NewNotifPipeline"
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user