Revert "Create interface for NotifInterruptStateProvider"

Revert "Move HUNs and pulsing to interrupt package"

Revert submission 10548462-hun_interrupt_package
Fixes: b/151050224

Reason for revert: broke HUNs
Reverted Changes:
I5ad5546d6:Move HUNs and pulsing to interrupt package
I13be75809:Create interface for NotifInterruptStateProvider

Change-Id: I421a7906a87236fb18fc3d434d654fb18c35e6a2
This commit is contained in:
Beverly Tai
2020-03-09 16:17:53 +00:00
parent e73aea2e48
commit bcb499478a
30 changed files with 665 additions and 735 deletions

View File

@@ -22,6 +22,7 @@ import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
import android.content.Context;
import com.android.systemui.car.CarDeviceProvisionedControllerImpl;
import com.android.systemui.car.CarNotificationInterruptionStateProvider;
import com.android.systemui.dagger.SystemUIRootComponent;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerImpl;
@@ -38,6 +39,7 @@ import com.android.systemui.statusbar.car.CarShadeControllerImpl;
import com.android.systemui.statusbar.car.CarStatusBar;
import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
@@ -61,6 +63,10 @@ import dagger.Provides;
@Module(includes = {DividerModule.class})
abstract class CarSystemUIModule {
@Binds
abstract NotificationInterruptionStateProvider bindNotificationInterruptionStateProvider(
CarNotificationInterruptionStateProvider notificationInterruptionStateProvider);
@Singleton
@Provides
@Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME)

View File

@@ -0,0 +1,54 @@
/*
* 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.car;
import android.content.Context;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.policy.BatteryController;
import javax.inject.Inject;
import javax.inject.Singleton;
/** Auto-specific implementation of {@link NotificationInterruptionStateProvider}. */
@Singleton
public class CarNotificationInterruptionStateProvider extends
NotificationInterruptionStateProvider {
@Inject
public CarNotificationInterruptionStateProvider(Context context,
NotificationFilter filter,
StatusBarStateController stateController,
BatteryController batteryController) {
super(context, filter, stateController, batteryController);
}
@Override
public boolean shouldHeadsUp(NotificationEntry entry) {
// Because space is usually constrained in the auto use-case, there should not be a
// pinned notification when the shade has been expanded. Ensure this by not pinning any
// notification if the shade is already opened.
if (!getPresenter().isPresenterFullyCollapsed()) {
return false;
}
return super.shouldHeadsUp(entry);
}
}

View File

@@ -97,14 +97,13 @@ import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.phone.AutoHideController;
@@ -268,9 +267,10 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
NotificationGutsManager notificationGutsManager,
NotificationLogger notificationLogger,
NotificationInterruptStateProvider notificationInterruptStateProvider,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
NotificationViewHierarchyManager notificationViewHierarchyManager,
KeyguardViewMediator keyguardViewMediator,
NotificationAlertingManager notificationAlertingManager,
DisplayMetrics displayMetrics,
MetricsLogger metricsLogger,
@UiBackground Executor uiBgExecutor,
@@ -350,9 +350,10 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
remoteInputQuickSettingsDisabler,
notificationGutsManager,
notificationLogger,
notificationInterruptStateProvider,
notificationInterruptionStateProvider,
notificationViewHierarchyManager,
keyguardViewMediator,
notificationAlertingManager,
displayMetrics,
metricsLogger,
uiBgExecutor,
@@ -490,22 +491,6 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
.isCurrentUserSetupInProgress();
}
});
mNotificationInterruptStateProvider.addSuppressor(new NotificationInterruptSuppressor() {
@Override
public String getName() {
return TAG;
}
@Override
public boolean suppressInterruptions(NotificationEntry entry) {
// Because space is usually constrained in the auto use-case, there should not be a
// pinned notification when the shade has been expanded.
// Ensure this by not allowing any interruptions (ie: pinning any notifications) if
// the shade is already opened.
return !getPresenter().isPresenterFullyCollapsed();
}
});
}
@Override

View File

@@ -58,12 +58,13 @@ import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.dagger.StatusBarDependenciesModule;
import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.NotificationRowModule;
@@ -142,9 +143,10 @@ public class CarStatusBarModule {
RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
NotificationGutsManager notificationGutsManager,
NotificationLogger notificationLogger,
NotificationInterruptStateProvider notificationInterruptionStateProvider,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
NotificationViewHierarchyManager notificationViewHierarchyManager,
KeyguardViewMediator keyguardViewMediator,
NotificationAlertingManager notificationAlertingManager,
DisplayMetrics displayMetrics,
MetricsLogger metricsLogger,
@UiBackground Executor uiBgExecutor,
@@ -226,6 +228,7 @@ public class CarStatusBarModule {
notificationInterruptionStateProvider,
notificationViewHierarchyManager,
keyguardViewMediator,
notificationAlertingManager,
displayMetrics,
metricsLogger,
uiBgExecutor,

View File

@@ -71,11 +71,12 @@ import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager.KeyguardEnvironment;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.interruption.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ChannelEditorDialogController;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
@@ -288,6 +289,7 @@ public class Dependency {
@Inject Lazy<NotificationLogger> mNotificationLogger;
@Inject Lazy<NotificationViewHierarchyManager> mNotificationViewHierarchyManager;
@Inject Lazy<NotificationFilter> mNotificationFilter;
@Inject Lazy<NotificationInterruptionStateProvider> mNotificationInterruptionStateProvider;
@Inject Lazy<KeyguardDismissUtil> mKeyguardDismissUtil;
@Inject Lazy<SmartReplyController> mSmartReplyController;
@Inject Lazy<RemoteInputQuickSettingsDisabler> mRemoteInputQuickSettingsDisabler;
@@ -487,6 +489,8 @@ public class Dependency {
mProviders.put(NotificationViewHierarchyManager.class,
mNotificationViewHierarchyManager::get);
mProviders.put(NotificationFilter.class, mNotificationFilter::get);
mProviders.put(NotificationInterruptionStateProvider.class,
mNotificationInterruptionStateProvider::get);
mProviders.put(KeyguardDismissUtil.class, mKeyguardDismissUtil::get);
mProviders.put(SmartReplyController.class, mSmartReplyController::get);
mProviders.put(RemoteInputQuickSettingsDisabler.class,

View File

@@ -83,11 +83,11 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationRemoveInterceptor;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -169,7 +169,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
// Callback that updates BubbleOverflowActivity on data change.
@Nullable private Runnable mOverflowCallback = null;
private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
private IStatusBarService mBarService;
// Used for determining view rect for touch interaction
@@ -279,7 +279,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
ShadeController shadeController,
BubbleData data,
ConfigurationController configurationController,
NotificationInterruptStateProvider interruptionStateProvider,
NotificationInterruptionStateProvider interruptionStateProvider,
ZenModeController zenModeController,
NotificationLockscreenUserManager notifUserManager,
NotificationGroupManager groupManager,
@@ -304,7 +304,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
BubbleData data,
@Nullable BubbleStackView.SurfaceSynchronizer synchronizer,
ConfigurationController configurationController,
NotificationInterruptStateProvider interruptionStateProvider,
NotificationInterruptionStateProvider interruptionStateProvider,
ZenModeController zenModeController,
NotificationLockscreenUserManager notifUserManager,
NotificationGroupManager groupManager,
@@ -316,7 +316,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
dumpManager.registerDumpable(TAG, this);
mContext = context;
mShadeController = shadeController;
mNotificationInterruptStateProvider = interruptionStateProvider;
mNotificationInterruptionStateProvider = interruptionStateProvider;
mNotifUserManager = notifUserManager;
mZenModeController = zenModeController;
mFloatingContentCoordinator = floatingContentCoordinator;
@@ -632,7 +632,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
for (NotificationEntry e :
mNotificationEntryManager.getActiveNotificationsForCurrentUser()) {
if (savedBubbleKeys.contains(e.getKey())
&& mNotificationInterruptStateProvider.shouldBubbleUp(e)
&& mNotificationInterruptionStateProvider.shouldBubbleUp(e)
&& canLaunchInActivityView(mContext, e)) {
updateBubble(e, /* suppressFlyout= */ true);
}
@@ -894,7 +894,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
boolean wasAdjusted = BubbleExperimentConfig.adjustForExperiments(
mContext, entry, previouslyUserCreated, userBlocked);
if (mNotificationInterruptStateProvider.shouldBubbleUp(entry)
if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
&& (canLaunchInActivityView(mContext, entry) || wasAdjusted)) {
if (wasAdjusted && !previouslyUserCreated) {
// Gotta treat the auto-bubbled / whitelisted packaged bubbles as usercreated
@@ -910,7 +910,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
boolean wasAdjusted = BubbleExperimentConfig.adjustForExperiments(
mContext, entry, previouslyUserCreated, userBlocked);
boolean shouldBubble = mNotificationInterruptStateProvider.shouldBubbleUp(entry)
boolean shouldBubble = mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
&& (canLaunchInActivityView(mContext, entry) || wasAdjusted);
if (!shouldBubble && mBubbleData.hasBubbleWithKey(entry.getKey())) {
// It was previously a bubble but no longer a bubble -- lets remove it

View File

@@ -25,8 +25,8 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -54,7 +54,7 @@ public interface BubbleModule {
ShadeController shadeController,
BubbleData data,
ConfigurationController configurationController,
NotificationInterruptStateProvider interruptionStateProvider,
NotificationInterruptionStateProvider interruptionStateProvider,
ZenModeController zenModeController,
NotificationLockscreenUserManager notifUserManager,
NotificationGroupManager groupManager,

View File

@@ -90,7 +90,7 @@ public class DependencyProvider {
/** */
@Provides
public AmbientDisplayConfiguration provideAmbientDisplayConfiguration(Context context) {
public AmbientDisplayConfiguration provideAmbientDispalyConfiguration(Context context) {
return new AmbientDisplayConfiguration(context);
}

View File

@@ -14,7 +14,7 @@
* limitations under the License
*/
package com.android.systemui.statusbar.notification.interruption
package com.android.systemui.statusbar.notification
import android.content.Context
import android.media.MediaMetadata
@@ -24,7 +24,6 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.NotificationMediaManager
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.notification.NotificationEntryManager
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
import com.android.systemui.statusbar.phone.KeyguardBypassController

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.systemui.statusbar.notification.interruption;
package com.android.systemui.statusbar.notification;
import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP;
@@ -27,9 +27,6 @@ import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -42,7 +39,7 @@ public class NotificationAlertingManager {
private final NotificationRemoteInputManager mRemoteInputManager;
private final VisualStabilityManager mVisualStabilityManager;
private final StatusBarStateController mStatusBarStateController;
private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
private final NotificationListener mNotificationListener;
private HeadsUpManager mHeadsUpManager;
@@ -55,13 +52,13 @@ public class NotificationAlertingManager {
NotificationRemoteInputManager remoteInputManager,
VisualStabilityManager visualStabilityManager,
StatusBarStateController statusBarStateController,
NotificationInterruptStateProvider notificationInterruptionStateProvider,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
NotificationListener notificationListener,
HeadsUpManager headsUpManager) {
mRemoteInputManager = remoteInputManager;
mVisualStabilityManager = visualStabilityManager;
mStatusBarStateController = statusBarStateController;
mNotificationInterruptStateProvider = notificationInterruptionStateProvider;
mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
mNotificationListener = notificationListener;
mHeadsUpManager = headsUpManager;
@@ -97,7 +94,7 @@ public class NotificationAlertingManager {
if (entry.getRow().getPrivateLayout().getHeadsUpChild() != null) {
// Possible for shouldHeadsUp to change between the inflation starting and ending.
// If it does and we no longer need to heads up, we should free the view.
if (mNotificationInterruptStateProvider.shouldHeadsUp(entry)) {
if (mNotificationInterruptionStateProvider.shouldHeadsUp(entry)) {
mHeadsUpManager.showNotification(entry);
if (!mStatusBarStateController.isDozing()) {
// Mark as seen immediately
@@ -112,7 +109,7 @@ public class NotificationAlertingManager {
private void updateAlertState(NotificationEntry entry) {
boolean alertAgain = alertAgain(entry, entry.getSbn().getNotification());
// includes check for whether this notification should be filtered:
boolean shouldAlert = mNotificationInterruptStateProvider.shouldHeadsUp(entry);
boolean shouldAlert = mNotificationInterruptionStateProvider.shouldHeadsUp(entry);
final boolean wasAlerting = mHeadsUpManager.isAlerting(entry.getKey());
if (wasAlerting) {
if (shouldAlert) {

View File

@@ -14,35 +14,33 @@
* limitations under the License.
*/
package com.android.systemui.statusbar.notification.interruption;
package com.android.systemui.statusbar.notification;
import static com.android.systemui.statusbar.StatusBarState.SHADE;
import android.app.NotificationManager;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -50,84 +48,120 @@ import javax.inject.Singleton;
* Provides heads-up and pulsing state for notification entries.
*/
@Singleton
public class NotificationInterruptStateProviderImpl implements NotificationInterruptStateProvider {
public class NotificationInterruptionStateProvider {
private static final String TAG = "InterruptionStateProvider";
private static final boolean DEBUG = true; //false;
private static final boolean DEBUG = false;
private static final boolean DEBUG_HEADS_UP = true;
private static final boolean ENABLE_HEADS_UP = true;
private static final String SETTING_HEADS_UP_TICKER = "ticker_gets_heads_up";
private final List<NotificationInterruptSuppressor> mSuppressors = new ArrayList<>();
private final StatusBarStateController mStatusBarStateController;
private final NotificationFilter mNotificationFilter;
private final ContentResolver mContentResolver;
private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
private final Context mContext;
private final PowerManager mPowerManager;
private final IDreamManager mDreamManager;
private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
private final BatteryController mBatteryController;
private final ContentObserver mHeadsUpObserver;
private HeadsUpManager mHeadsUpManager;
private NotificationPresenter mPresenter;
private HeadsUpManager mHeadsUpManager;
private HeadsUpSuppressor mHeadsUpSuppressor;
private ContentObserver mHeadsUpObserver;
@VisibleForTesting
protected boolean mUseHeadsUp = false;
private boolean mDisableNotificationAlerts;
@Inject
public NotificationInterruptStateProviderImpl(
ContentResolver contentResolver,
public NotificationInterruptionStateProvider(Context context, NotificationFilter filter,
StatusBarStateController stateController, BatteryController batteryController) {
this(context,
(PowerManager) context.getSystemService(Context.POWER_SERVICE),
IDreamManager.Stub.asInterface(
ServiceManager.checkService(DreamService.DREAM_SERVICE)),
new AmbientDisplayConfiguration(context),
filter,
batteryController,
stateController);
}
@VisibleForTesting
protected NotificationInterruptionStateProvider(
Context context,
PowerManager powerManager,
IDreamManager dreamManager,
AmbientDisplayConfiguration ambientDisplayConfiguration,
NotificationFilter notificationFilter,
BatteryController batteryController,
StatusBarStateController statusBarStateController,
HeadsUpManager headsUpManager,
@Main Handler mainHandler) {
mContentResolver = contentResolver;
StatusBarStateController statusBarStateController) {
mContext = context;
mPowerManager = powerManager;
mDreamManager = dreamManager;
mBatteryController = batteryController;
mAmbientDisplayConfiguration = ambientDisplayConfiguration;
mNotificationFilter = notificationFilter;
mStatusBarStateController = statusBarStateController;
mHeadsUpManager = headsUpManager;
mHeadsUpObserver = new ContentObserver(mainHandler) {
@Override
public void onChange(boolean selfChange) {
boolean wasUsing = mUseHeadsUp;
mUseHeadsUp = ENABLE_HEADS_UP
&& Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
mContentResolver,
Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Settings.Global.HEADS_UP_OFF);
Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
if (wasUsing != mUseHeadsUp) {
if (!mUseHeadsUp) {
Log.d(TAG, "dismissing any existing heads up notification on "
+ "disable event");
mHeadsUpManager.releaseAllImmediately();
}
/** Sets up late-binding dependencies for this component. */
public void setUpWithPresenter(
NotificationPresenter notificationPresenter,
HeadsUpManager headsUpManager,
HeadsUpSuppressor headsUpSuppressor) {
setUpWithPresenter(notificationPresenter, headsUpManager, headsUpSuppressor,
new ContentObserver(Dependency.get(Dependency.MAIN_HANDLER)) {
@Override
public void onChange(boolean selfChange) {
boolean wasUsing = mUseHeadsUp;
mUseHeadsUp = ENABLE_HEADS_UP && !mDisableNotificationAlerts
&& Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
mContext.getContentResolver(),
Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Settings.Global.HEADS_UP_OFF);
Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
if (wasUsing != mUseHeadsUp) {
if (!mUseHeadsUp) {
Log.d(TAG,
"dismissing any existing heads up notification on disable"
+ " event");
mHeadsUpManager.releaseAllImmediately();
}
}
}
}
}
};
});
}
/** Sets up late-binding dependencies for this component. */
public void setUpWithPresenter(
NotificationPresenter notificationPresenter,
HeadsUpManager headsUpManager,
HeadsUpSuppressor headsUpSuppressor,
ContentObserver observer) {
mPresenter = notificationPresenter;
mHeadsUpManager = headsUpManager;
mHeadsUpSuppressor = headsUpSuppressor;
mHeadsUpObserver = observer;
if (ENABLE_HEADS_UP) {
mContentResolver.registerContentObserver(
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED),
true,
mHeadsUpObserver);
mContentResolver.registerContentObserver(
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
mHeadsUpObserver);
}
mHeadsUpObserver.onChange(true); // set up
}
@Override
public void addSuppressor(NotificationInterruptSuppressor suppressor) {
mSuppressors.add(suppressor);
}
@Override
/**
* Whether the notification should appear as a bubble with a fly-out on top of the screen.
*
* @param entry the entry to check
* @return true if the entry should bubble up, false otherwise
*/
public boolean shouldBubbleUp(NotificationEntry entry) {
final StatusBarNotification sbn = entry.getSbn();
@@ -167,8 +201,12 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
return true;
}
@Override
/**
* Whether the notification should peek in from the top and alert the user.
*
* @param entry the entry to check
* @return true if the entry should heads up, false otherwise
*/
public boolean shouldHeadsUp(NotificationEntry entry) {
if (mStatusBarStateController.isDozing()) {
return shouldHeadsUpWhenDozing(entry);
@@ -177,17 +215,6 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
}
}
/**
* When an entry was added, should we launch its fullscreen intent? Examples are Alarms or
* incoming calls.
*/
@Override
public boolean shouldLaunchFullScreenIntentWhenAdded(NotificationEntry entry) {
return entry.getSbn().getNotification().fullScreenIntent != null
&& (!shouldHeadsUp(entry)
|| mStatusBarStateController.getState() == StatusBarState.KEYGUARD);
}
private boolean shouldHeadsUpWhenAwake(NotificationEntry entry) {
StatusBarNotification sbn = entry.getSbn();
@@ -244,15 +271,13 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
return false;
}
for (int i = 0; i < mSuppressors.size(); i++) {
if (mSuppressors.get(i).suppressAwakeHeadsUp(entry)) {
if (DEBUG_HEADS_UP) {
Log.d(TAG, "No heads up: aborted by suppressor: "
+ mSuppressors.get(i).getName() + " sbnKey=" + sbn.getKey());
}
return false;
if (!mHeadsUpSuppressor.canHeadsUp(entry, sbn)) {
if (DEBUG_HEADS_UP) {
Log.d(TAG, "No heads up: aborted by suppressor: " + sbn.getKey());
}
return false;
}
return true;
}
@@ -300,7 +325,7 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
}
return false;
}
return true;
return true;
}
/**
@@ -309,7 +334,8 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
* @param entry the entry to check
* @return true if these checks pass, false if the notification should not alert
*/
private boolean canAlertCommon(NotificationEntry entry) {
@VisibleForTesting
public boolean canAlertCommon(NotificationEntry entry) {
StatusBarNotification sbn = entry.getSbn();
if (mNotificationFilter.shouldFilterOut(entry)) {
@@ -326,16 +352,6 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
}
return false;
}
for (int i = 0; i < mSuppressors.size(); i++) {
if (mSuppressors.get(i).suppressInterruptions(entry)) {
if (DEBUG_HEADS_UP) {
Log.d(TAG, "No alerting: aborted by suppressor: "
+ mSuppressors.get(i).getName() + " sbnKey=" + sbn.getKey());
}
return false;
}
}
return true;
}
@@ -345,17 +361,15 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
* @param entry the entry to check
* @return true if these checks pass, false if the notification should not alert
*/
private boolean canAlertAwakeCommon(NotificationEntry entry) {
@VisibleForTesting
public boolean canAlertAwakeCommon(NotificationEntry entry) {
StatusBarNotification sbn = entry.getSbn();
for (int i = 0; i < mSuppressors.size(); i++) {
if (mSuppressors.get(i).suppressAwakeInterruptions(entry)) {
if (DEBUG_HEADS_UP) {
Log.d(TAG, "No alerting: aborted by suppressor: "
+ mSuppressors.get(i).getName() + " sbnKey=" + sbn.getKey());
}
return false;
if (mPresenter.isDeviceInVrMode()) {
if (DEBUG_HEADS_UP) {
Log.d(TAG, "No alerting: no huns or vr mode");
}
return false;
}
if (isSnoozedPackage(sbn)) {
@@ -378,4 +392,54 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
private boolean isSnoozedPackage(StatusBarNotification sbn) {
return mHeadsUpManager.isSnoozed(sbn.getPackageName());
}
/** Sets whether to disable all alerts. */
public void setDisableNotificationAlerts(boolean disableNotificationAlerts) {
mDisableNotificationAlerts = disableNotificationAlerts;
mHeadsUpObserver.onChange(true);
}
/** Whether all alerts are disabled. */
@VisibleForTesting
public boolean areNotificationAlertsDisabled() {
return mDisableNotificationAlerts;
}
/** Whether HUNs should be used. */
@VisibleForTesting
public boolean getUseHeadsUp() {
return mUseHeadsUp;
}
protected NotificationPresenter getPresenter() {
return mPresenter;
}
/**
* When an entry was added, should we launch its fullscreen intent? Examples are Alarms or
* incoming calls.
*
* @param entry the entry that was added
* @return {@code true} if we should launch the full screen intent
*/
public boolean shouldLaunchFullScreenIntentWhenAdded(NotificationEntry entry) {
return entry.getSbn().getNotification().fullScreenIntent != null
&& (!shouldHeadsUp(entry)
|| mStatusBarStateController.getState() == StatusBarState.KEYGUARD);
}
/** A component which can suppress heads-up notifications due to the overall state of the UI. */
public interface HeadsUpSuppressor {
/**
* Returns false if the provided notification is ineligible for heads-up according to this
* component.
*
* @param entry entry of the notification that might be heads upped
* @param sbn notification that might be heads upped
* @return false if the notification can not be heads upped
*/
boolean canHeadsUp(NotificationEntry entry, StatusBarNotification sbn);
}
}

View File

@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification
import android.animation.ObjectAnimator
import android.content.Context
import android.util.FloatProperty
import com.android.systemui.Interpolators
import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -25,10 +26,10 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
import com.android.systemui.statusbar.notification.stack.StackStateAnimator
import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.NotificationIconAreaController
import com.android.systemui.statusbar.phone.PanelExpansionListener
import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
import javax.inject.Inject
@@ -36,14 +37,15 @@ import javax.inject.Singleton
@Singleton
class NotificationWakeUpCoordinator @Inject constructor(
private val mHeadsUpManager: HeadsUpManager,
private val statusBarStateController: StatusBarStateController,
private val bypassController: KeyguardBypassController,
private val dozeParameters: DozeParameters
) : OnHeadsUpChangedListener, StatusBarStateController.StateListener, PanelExpansionListener {
private val mHeadsUpManagerPhone: HeadsUpManagerPhone,
private val statusBarStateController: StatusBarStateController,
private val bypassController: KeyguardBypassController,
private val dozeParameters: DozeParameters)
: OnHeadsUpChangedListener, StatusBarStateController.StateListener,
PanelExpansionListener {
private val mNotificationVisibility = object : FloatProperty<NotificationWakeUpCoordinator>(
"notificationVisibility") {
private val mNotificationVisibility
= object : FloatProperty<NotificationWakeUpCoordinator>("notificationVisibility") {
override fun setValue(coordinator: NotificationWakeUpCoordinator, value: Float) {
coordinator.setVisibilityAmount(value)
@@ -76,10 +78,10 @@ class NotificationWakeUpCoordinator @Inject constructor(
field = value
willWakeUp = false
if (value) {
if (mNotificationsVisible && !mNotificationsVisibleForExpansion &&
!bypassController.bypassEnabled) {
if (mNotificationsVisible && !mNotificationsVisibleForExpansion
&& !bypassController.bypassEnabled) {
// We're waking up while pulsing, let's make sure the animation looks nice
mStackScroller.wakeUpFromPulse()
mStackScroller.wakeUpFromPulse();
}
if (bypassController.bypassEnabled && !mNotificationsVisible) {
// Let's make sure our huns become visible once we are waking up in case
@@ -98,7 +100,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
private var collapsedEnoughToHide: Boolean = false
lateinit var iconAreaController: NotificationIconAreaController
lateinit var iconAreaController : NotificationIconAreaController
var pulsing: Boolean = false
set(value) {
@@ -130,8 +132,8 @@ class NotificationWakeUpCoordinator @Inject constructor(
var canShow = pulsing
if (bypassController.bypassEnabled) {
// We also allow pulsing on the lock screen!
canShow = canShow || (wakingUp || willWakeUp || fullyAwake) &&
statusBarStateController.state == StatusBarState.KEYGUARD
canShow = canShow || (wakingUp || willWakeUp || fullyAwake)
&& statusBarStateController.state == StatusBarState.KEYGUARD
// We want to hide the notifications when collapsed too much
if (collapsedEnoughToHide) {
canShow = false
@@ -141,7 +143,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
init {
mHeadsUpManager.addListener(this)
mHeadsUpManagerPhone.addListener(this)
statusBarStateController.addCallback(this)
addListener(object : WakeUpListener {
override fun onFullyHiddenChanged(isFullyHidden: Boolean) {
@@ -153,7 +155,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
increaseSpeed = false)
}
}
})
});
}
fun setStackScroller(stackScroller: NotificationStackScrollLayout) {
@@ -176,55 +178,46 @@ class NotificationWakeUpCoordinator @Inject constructor(
* @param animate should this change be animated
* @param increaseSpeed should the speed be increased of the animation
*/
fun setNotificationsVisibleForExpansion(
visible: Boolean,
animate: Boolean,
increaseSpeed: Boolean
) {
fun setNotificationsVisibleForExpansion(visible: Boolean, animate: Boolean,
increaseSpeed: Boolean) {
mNotificationsVisibleForExpansion = visible
updateNotificationVisibility(animate, increaseSpeed)
if (!visible && mNotificationsVisible) {
// If we stopped expanding and we're still visible because we had a pulse that hasn't
// times out, let's release them all to make sure were not stuck in a state where
// notifications are visible
mHeadsUpManager.releaseAllImmediately()
mHeadsUpManagerPhone.releaseAllImmediately()
}
}
fun addListener(listener: WakeUpListener) {
wakeUpListeners.add(listener)
wakeUpListeners.add(listener);
}
fun removeListener(listener: WakeUpListener) {
wakeUpListeners.remove(listener)
wakeUpListeners.remove(listener);
}
private fun updateNotificationVisibility(
animate: Boolean,
increaseSpeed: Boolean
) {
private fun updateNotificationVisibility(animate: Boolean, increaseSpeed: Boolean) {
// TODO: handle Lockscreen wakeup for bypass when we're not pulsing anymore
var visible = mNotificationsVisibleForExpansion || mHeadsUpManager.hasNotifications()
var visible = mNotificationsVisibleForExpansion || mHeadsUpManagerPhone.hasNotifications()
visible = visible && canShowPulsingHuns
if (!visible && mNotificationsVisible && (wakingUp || willWakeUp) && mDozeAmount != 0.0f) {
// let's not make notifications invisible while waking up, otherwise the animation
// is strange
return
return;
}
setNotificationsVisible(visible, animate, increaseSpeed)
}
private fun setNotificationsVisible(
visible: Boolean,
animate: Boolean,
increaseSpeed: Boolean
) {
private fun setNotificationsVisible(visible: Boolean, animate: Boolean,
increaseSpeed: Boolean) {
if (mNotificationsVisible == visible) {
return
}
mNotificationsVisible = visible
mVisibilityAnimator?.cancel()
mVisibilityAnimator?.cancel();
if (animate) {
notifyAnimationStart(visible)
startVisibilityAnimation(increaseSpeed)
@@ -237,8 +230,8 @@ class NotificationWakeUpCoordinator @Inject constructor(
if (updateDozeAmountIfBypass()) {
return
}
if (linear != 1.0f && linear != 0.0f &&
(mLinearDozeAmount == 0.0f || mLinearDozeAmount == 1.0f)) {
if (linear != 1.0f && linear != 0.0f
&& (mLinearDozeAmount == 0.0f || mLinearDozeAmount == 1.0f)) {
// Let's notify the scroller that an animation started
notifyAnimationStart(mLinearDozeAmount == 1.0f)
}
@@ -252,17 +245,17 @@ class NotificationWakeUpCoordinator @Inject constructor(
mStackScroller.setDozeAmount(mDozeAmount)
updateHideAmount()
if (changed && linear == 0.0f) {
setNotificationsVisible(visible = false, animate = false, increaseSpeed = false)
setNotificationsVisible(visible = false, animate = false, increaseSpeed = false);
setNotificationsVisibleForExpansion(visible = false, animate = false,
increaseSpeed = false)
}
}
override fun onStateChanged(newState: Int) {
updateDozeAmountIfBypass()
updateDozeAmountIfBypass();
if (bypassController.bypassEnabled &&
newState == StatusBarState.KEYGUARD && state == StatusBarState.SHADE_LOCKED &&
(!statusBarStateController.isDozing || shouldAnimateVisibility())) {
newState == StatusBarState.KEYGUARD && state == StatusBarState.SHADE_LOCKED
&& (!statusBarStateController.isDozing || shouldAnimateVisibility())) {
// We're leaving shade locked. Let's animate the notifications away
setNotificationsVisible(visible = true, increaseSpeed = false, animate = false)
setNotificationsVisible(visible = false, increaseSpeed = false, animate = true)
@@ -273,23 +266,23 @@ class NotificationWakeUpCoordinator @Inject constructor(
override fun onPanelExpansionChanged(expansion: Float, tracking: Boolean) {
val collapsedEnough = expansion <= 0.9f
if (collapsedEnough != this.collapsedEnoughToHide) {
val couldShowPulsingHuns = canShowPulsingHuns
val couldShowPulsingHuns = canShowPulsingHuns;
this.collapsedEnoughToHide = collapsedEnough
if (couldShowPulsingHuns && !canShowPulsingHuns) {
updateNotificationVisibility(animate = true, increaseSpeed = true)
mHeadsUpManager.releaseAllImmediately()
mHeadsUpManagerPhone.releaseAllImmediately()
}
}
}
private fun updateDozeAmountIfBypass(): Boolean {
if (bypassController.bypassEnabled) {
var amount = 1.0f
if (statusBarStateController.state == StatusBarState.SHADE ||
statusBarStateController.state == StatusBarState.SHADE_LOCKED) {
amount = 0.0f
var amount = 1.0f;
if (statusBarStateController.state == StatusBarState.SHADE
|| statusBarStateController.state == StatusBarState.SHADE_LOCKED) {
amount = 0.0f;
}
setDozeAmount(amount, amount)
setDozeAmount(amount, amount)
return true
}
return false
@@ -307,7 +300,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
visibilityAnimator.setInterpolator(Interpolators.LINEAR)
var duration = StackStateAnimator.ANIMATION_DURATION_WAKEUP.toLong()
if (increaseSpeed) {
duration = (duration.toFloat() / 1.5F).toLong()
duration = (duration.toFloat() / 1.5F).toLong();
}
visibilityAnimator.setDuration(duration)
visibilityAnimator.start()
@@ -318,7 +311,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
mLinearVisibilityAmount = visibilityAmount
mVisibilityAmount = mVisibilityInterpolator.getInterpolation(
visibilityAmount)
handleAnimationFinished()
handleAnimationFinished();
updateHideAmount()
}
@@ -329,7 +322,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
}
fun getWakeUpHeight(): Float {
fun getWakeUpHeight() : Float {
return mStackScroller.wakeUpHeight
}
@@ -337,7 +330,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
val linearAmount = Math.min(1.0f - mLinearVisibilityAmount, mLinearDozeAmount)
val amount = Math.min(1.0f - mVisibilityAmount, mDozeAmount)
mStackScroller.setHideAmount(linearAmount, amount)
notificationsFullyHidden = linearAmount == 1.0f
notificationsFullyHidden = linearAmount == 1.0f;
}
private fun notifyAnimationStart(awake: Boolean) {
@@ -368,7 +361,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
// if we animate, we see the shelf briefly visible. Instead we fully animate
// the notification and its background out
animate = false
} else if (!wakingUp && !willWakeUp) {
} else if (!wakingUp && !willWakeUp){
// TODO: look that this is done properly and not by anyone else
entry.setHeadsUpAnimatingAway(true)
mEntrySetToClearWhenFinished.add(entry)

View File

@@ -37,8 +37,8 @@ import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationUiAdjustment;
import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.NotificationClicker;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
import com.android.systemui.statusbar.notification.row.NotifBindPipeline;
@@ -66,7 +66,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
private static final String TAG = "NotificationViewManager";
private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
private final Context mContext;
private final NotifBindPipeline mNotifBindPipeline;
@@ -97,7 +97,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
StatusBarStateController statusBarStateController,
NotificationGroupManager notificationGroupManager,
NotificationGutsManager notificationGutsManager,
NotificationInterruptStateProvider notificationInterruptionStateProvider,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
Provider<RowInflaterTask> rowInflaterTaskProvider,
ExpandableNotificationRowComponent.Builder expandableNotificationRowComponentBuilder) {
mContext = context;
@@ -106,7 +106,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
mMessagingUtil = notificationMessagingUtil;
mNotificationRemoteInputManager = notificationRemoteInputManager;
mNotificationLockscreenUserManager = notificationLockscreenUserManager;
mNotificationInterruptStateProvider = notificationInterruptionStateProvider;
mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
mRowInflaterTaskProvider = rowInflaterTaskProvider;
mExpandableNotificationRowComponentBuilder = expandableNotificationRowComponentBuilder;
}
@@ -243,7 +243,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
params.setUseIncreasedHeadsUpHeight(useIncreasedHeadsUp);
params.setUseLowPriority(entry.isAmbient());
if (mNotificationInterruptStateProvider.shouldHeadsUp(entry)) {
if (mNotificationInterruptionStateProvider.shouldHeadsUp(entry)) {
params.requireContentViews(FLAG_CONTENT_VIEW_HEADS_UP);
}
//TODO: Replace this API with RowContentBindParams directly

View File

@@ -29,8 +29,10 @@ import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFeatureController;
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
@@ -40,9 +42,6 @@ import com.android.systemui.statusbar.notification.collection.provider.HighPrior
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.init.NotificationsControllerImpl;
import com.android.systemui.statusbar.notification.init.NotificationsControllerStub;
import com.android.systemui.statusbar.notification.interruption.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
@@ -55,7 +54,6 @@ import java.util.concurrent.Executor;
import javax.inject.Singleton;
import dagger.Binds;
import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
@@ -125,7 +123,7 @@ public interface NotificationsModule {
NotificationRemoteInputManager remoteInputManager,
VisualStabilityManager visualStabilityManager,
StatusBarStateController statusBarStateController,
NotificationInterruptStateProvider notificationInterruptStateProvider,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
NotificationListener notificationListener,
HeadsUpManager headsUpManager) {
return new NotificationAlertingManager(
@@ -133,7 +131,7 @@ public interface NotificationsModule {
remoteInputManager,
visualStabilityManager,
statusBarStateController,
notificationInterruptStateProvider,
notificationInterruptionStateProvider,
notificationListener,
headsUpManager);
}
@@ -192,9 +190,4 @@ public interface NotificationsModule {
NotificationEntryManager entryManager) {
return featureFlags.isNewNotifPipelineRenderingEnabled() ? pipeline.get() : entryManager;
}
/** */
@Binds
NotificationInterruptStateProvider bindNotificationInterruptStateProvider(
NotificationInterruptStateProviderImpl notificationInterruptStateProviderImpl);
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright (C) 2020 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.interruption;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
/**
* Provides bubble-up and heads-up state for notification entries.
*
* When a notification is heads-up when dozing, this is also called "pulsing."
*/
public interface NotificationInterruptStateProvider {
/**
* If the device is awake (not dozing):
* Whether the notification should peek in from the top and alert the user.
*
* If the device is dozing:
* Whether the notification should show the ambient view of the notification ("pulse").
*
* @param entry the entry to check
* @return true if the entry should heads up, false otherwise
*/
boolean shouldHeadsUp(NotificationEntry entry);
/**
* Whether the notification should appear as a bubble with a fly-out on top of the screen.
*
* @param entry the entry to check
* @return true if the entry should bubble up, false otherwise
*/
boolean shouldBubbleUp(NotificationEntry entry);
/**
* Whether to launch the entry's full screen intent when the entry is added.
*
* @param entry the entry that was added
* @return {@code true} if we should launch the full screen intent
*/
boolean shouldLaunchFullScreenIntentWhenAdded(NotificationEntry entry);
/**
* Add a component that can suppress visual interruptions.
*/
void addSuppressor(NotificationInterruptSuppressor suppressor);
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (C) 2020 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.interruption;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
/** A component which can suppress visual interruptions of notifications such as heads-up and
* bubble-up.
*/
public interface NotificationInterruptSuppressor {
/**
* A unique name to identify this suppressor.
*/
default String getName() {
return this.getClass().getName();
}
/**
* Returns true if the provided notification is, when the device is awake, ineligible for
* heads-up according to this component.
*
* @param entry entry of the notification that might heads-up
* @return true if the heads up interruption should be suppressed when the device is awake
*/
default boolean suppressAwakeHeadsUp(NotificationEntry entry) {
return false;
}
/**
* Returns true if the provided notification is, when the device is awake, ineligible for
* heads-up or bubble-up according to this component.
*
* @param entry entry of the notification that might heads-up or bubble-up
* @return true if interruptions should be suppressed when the device is awake
*/
default boolean suppressAwakeInterruptions(NotificationEntry entry) {
return false;
}
/**
* Returns true if the provided notification is, regardless of awake/dozing state,
* ineligible for heads-up or bubble-up according to this component.
*
* @param entry entry of the notification that might heads-up or bubble-up
* @return true if interruptions should be suppressed
*/
default boolean suppressInterruptions(NotificationEntry entry) {
return false;
}
}

View File

@@ -185,14 +185,15 @@ import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
@@ -403,9 +404,10 @@ public class StatusBar extends SystemUI implements DemoMode,
private final NotificationGutsManager mGutsManager;
private final NotificationLogger mNotificationLogger;
private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
private final NotificationViewHierarchyManager mViewHierarchyManager;
private final KeyguardViewMediator mKeyguardViewMediator;
protected final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
private final NotificationAlertingManager mNotificationAlertingManager;
// for disabling the status bar
private int mDisabled1 = 0;
@@ -619,9 +621,10 @@ public class StatusBar extends SystemUI implements DemoMode,
RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
NotificationGutsManager notificationGutsManager,
NotificationLogger notificationLogger,
NotificationInterruptStateProvider notificationInterruptStateProvider,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
NotificationViewHierarchyManager notificationViewHierarchyManager,
KeyguardViewMediator keyguardViewMediator,
NotificationAlertingManager notificationAlertingManager,
DisplayMetrics displayMetrics,
MetricsLogger metricsLogger,
@UiBackground Executor uiBgExecutor,
@@ -698,9 +701,10 @@ public class StatusBar extends SystemUI implements DemoMode,
mRemoteInputQuickSettingsDisabler = remoteInputQuickSettingsDisabler;
mGutsManager = notificationGutsManager;
mNotificationLogger = notificationLogger;
mNotificationInterruptStateProvider = notificationInterruptStateProvider;
mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
mViewHierarchyManager = notificationViewHierarchyManager;
mKeyguardViewMediator = keyguardViewMediator;
mNotificationAlertingManager = notificationAlertingManager;
mDisplayMetrics = displayMetrics;
mMetricsLogger = metricsLogger;
mUiBgExecutor = uiBgExecutor;
@@ -1234,9 +1238,9 @@ public class StatusBar extends SystemUI implements DemoMode,
mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanelViewController,
mHeadsUpManager, mNotificationShadeWindowView, mStackScroller, mDozeScrimController,
mScrimController, mActivityLaunchAnimator, mDynamicPrivacyController,
mKeyguardStateController, mKeyguardIndicationController,
this /* statusBar */, mShadeController, mCommandQueue, mInitController,
mNotificationInterruptStateProvider);
mNotificationAlertingManager, mKeyguardStateController,
mKeyguardIndicationController,
this /* statusBar */, mShadeController, mCommandQueue, mInitController);
mNotificationShelf.setOnActivatedListener(mPresenter);
mRemoteInputManager.getController().addCallback(mNotificationShadeWindowController);
@@ -1585,9 +1589,8 @@ public class StatusBar extends SystemUI implements DemoMode,
}
if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
if (areNotificationAlertsDisabled()) {
mHeadsUpManager.releaseAllImmediately();
}
mNotificationInterruptionStateProvider.setDisableNotificationAlerts(
(state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0);
}
if ((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) {
@@ -1602,10 +1605,6 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
boolean areNotificationAlertsDisabled() {
return (mDisabled1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
}
protected H createHandler() {
return new StatusBar.H();
}

View File

@@ -68,12 +68,12 @@ import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.policy.HeadsUpUtil;
@@ -108,7 +108,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
private final NotifCollection mNotifCollection;
private final FeatureFlags mFeatureFlags;
private final StatusBarStateController mStatusBarStateController;
private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
private final MetricsLogger mMetricsLogger;
private final Context mContext;
private final NotificationPanelViewController mNotificationPanel;
@@ -142,7 +142,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
NotificationLockscreenUserManager lockscreenUserManager,
ShadeController shadeController, StatusBar statusBar,
KeyguardStateController keyguardStateController,
NotificationInterruptStateProvider notificationInterruptStateProvider,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
MetricsLogger metricsLogger, LockPatternUtils lockPatternUtils,
Handler mainThreadHandler, Handler backgroundHandler, Executor uiBgExecutor,
ActivityIntentHelper activityIntentHelper, BubbleController bubbleController,
@@ -167,7 +167,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mActivityStarter = activityStarter;
mEntryManager = entryManager;
mStatusBarStateController = statusBarStateController;
mNotificationInterruptStateProvider = notificationInterruptStateProvider;
mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
mMetricsLogger = metricsLogger;
mAssistManagerLazy = assistManagerLazy;
mGroupManager = groupManager;
@@ -436,7 +436,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
}
private void handleFullScreenIntent(NotificationEntry entry) {
if (mNotificationInterruptStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) {
if (mNotificationInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) {
if (shouldSuppressFullScreenIntent(entry)) {
if (DEBUG) {
Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + entry.getKey());
@@ -603,7 +603,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
private final ActivityIntentHelper mActivityIntentHelper;
private final BubbleController mBubbleController;
private NotificationPanelViewController mNotificationPanelViewController;
private NotificationInterruptStateProvider mNotificationInterruptStateProvider;
private NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
private final ShadeController mShadeController;
private NotificationPresenter mNotificationPresenter;
private ActivityLaunchAnimator mActivityLaunchAnimator;
@@ -626,7 +626,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
NotificationGroupManager groupManager,
NotificationLockscreenUserManager lockscreenUserManager,
KeyguardStateController keyguardStateController,
NotificationInterruptStateProvider notificationInterruptStateProvider,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
MetricsLogger metricsLogger,
LockPatternUtils lockPatternUtils,
@Main Handler mainThreadHandler,
@@ -654,7 +654,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mGroupManager = groupManager;
mLockscreenUserManager = lockscreenUserManager;
mKeyguardStateController = keyguardStateController;
mNotificationInterruptStateProvider = notificationInterruptStateProvider;
mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
mMetricsLogger = metricsLogger;
mLockPatternUtils = lockPatternUtils;
mMainThreadHandler = mainThreadHandler;
@@ -712,7 +712,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mShadeController,
mStatusBar,
mKeyguardStateController,
mNotificationInterruptStateProvider,
mNotificationInterruptionStateProvider,
mMetricsLogger,
mLockPatternUtils,
mMainThreadHandler,

View File

@@ -60,13 +60,13 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.AboveShelfObserver;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
@@ -98,6 +98,8 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
(SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class);
private final NotificationEntryManager mEntryManager =
Dependency.get(NotificationEntryManager.class);
private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider =
Dependency.get(NotificationInterruptionStateProvider.class);
private final NotificationMediaManager mMediaManager =
Dependency.get(NotificationMediaManager.class);
private final VisualStabilityManager mVisualStabilityManager =
@@ -138,13 +140,13 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
ScrimController scrimController,
ActivityLaunchAnimator activityLaunchAnimator,
DynamicPrivacyController dynamicPrivacyController,
NotificationAlertingManager notificationAlertingManager,
KeyguardStateController keyguardStateController,
KeyguardIndicationController keyguardIndicationController,
StatusBar statusBar,
ShadeController shadeController,
CommandQueue commandQueue,
InitController initController,
NotificationInterruptStateProvider notificationInterruptStateProvider) {
InitController initController) {
mContext = context;
mKeyguardStateController = keyguardStateController;
mNotificationPanel = panel;
@@ -214,7 +216,8 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
mEntryManager.addNotificationLifetimeExtender(mGutsManager);
mEntryManager.addNotificationLifetimeExtenders(
remoteInputManager.getLifetimeExtenders());
notificationInterruptStateProvider.addSuppressor(mInterruptSuppressor);
mNotificationInterruptionStateProvider.setUpWithPresenter(
this, mHeadsUpManager, this::canHeadsUp);
mLockscreenUserManager.setUpWithPresenter(this);
mMediaManager.setUpWithPresenter(this);
mVisualStabilityManager.setUpWithPresenter(this);
@@ -333,6 +336,39 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
return mEntryManager.hasActiveNotifications();
}
public boolean canHeadsUp(NotificationEntry entry, StatusBarNotification sbn) {
if (mStatusBar.isOccluded()) {
boolean devicePublic = mLockscreenUserManager.
isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
boolean userPublic = devicePublic
|| mLockscreenUserManager.isLockscreenPublicMode(sbn.getUserId());
boolean needsRedaction = mLockscreenUserManager.needsRedaction(entry);
if (userPublic && needsRedaction) {
// TODO(b/135046837): we can probably relax this with dynamic privacy
return false;
}
}
if (!mCommandQueue.panelsEnabled()) {
if (DEBUG) {
Log.d(TAG, "No heads up: disabled panel : " + sbn.getKey());
}
return false;
}
if (sbn.getNotification().fullScreenIntent != null) {
if (mAccessibilityManager.isTouchExplorationEnabled()) {
if (DEBUG) Log.d(TAG, "No heads up: accessible fullscreen: " + sbn.getKey());
return false;
} else {
// we only allow head-up on the lockscreen if it doesn't have a fullscreen intent
return !mKeyguardStateController.isShowing()
|| mStatusBar.isOccluded();
}
}
return true;
}
@Override
public void onUserSwitched(int newUserId) {
// Begin old BaseStatusBar.userSwitched
@@ -471,66 +507,4 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
}
}
};
private final NotificationInterruptSuppressor mInterruptSuppressor =
new NotificationInterruptSuppressor() {
@Override
public String getName() {
return TAG;
}
@Override
public boolean suppressAwakeHeadsUp(NotificationEntry entry) {
final StatusBarNotification sbn = entry.getSbn();
if (mStatusBar.isOccluded()) {
boolean devicePublic = mLockscreenUserManager
.isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
boolean userPublic = devicePublic
|| mLockscreenUserManager.isLockscreenPublicMode(sbn.getUserId());
boolean needsRedaction = mLockscreenUserManager.needsRedaction(entry);
if (userPublic && needsRedaction) {
// TODO(b/135046837): we can probably relax this with dynamic privacy
return true;
}
}
if (!mCommandQueue.panelsEnabled()) {
if (DEBUG) {
Log.d(TAG, "No heads up: disabled panel : " + sbn.getKey());
}
return true;
}
if (sbn.getNotification().fullScreenIntent != null) {
// we don't allow head-up on the lockscreen (unless there's a
// "showWhenLocked" activity currently showing) if
// the potential HUN has a fullscreen intent
if (mKeyguardStateController.isShowing() && !mStatusBar.isOccluded()) {
if (DEBUG) {
Log.d(TAG, "No heads up: entry has fullscreen intent on lockscreen "
+ sbn.getKey());
}
return true;
}
if (mAccessibilityManager.isTouchExplorationEnabled()) {
if (DEBUG) {
Log.d(TAG, "No heads up: accessible fullscreen: " + sbn.getKey());
}
return true;
}
}
return false;
}
@Override
public boolean suppressAwakeInterruptions(NotificationEntry entry) {
return isDeviceInVrMode();
}
@Override
public boolean suppressInterruptions(NotificationEntry entry) {
return mStatusBar.areNotificationAlertsDisabled();
}
};
}

View File

@@ -56,12 +56,13 @@ import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.phone.AutoHideController;
@@ -138,9 +139,10 @@ public interface StatusBarPhoneModule {
RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
NotificationGutsManager notificationGutsManager,
NotificationLogger notificationLogger,
NotificationInterruptStateProvider notificationInterruptStateProvider,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
NotificationViewHierarchyManager notificationViewHierarchyManager,
KeyguardViewMediator keyguardViewMediator,
NotificationAlertingManager notificationAlertingManager,
DisplayMetrics displayMetrics,
MetricsLogger metricsLogger,
@UiBackground Executor uiBgExecutor,
@@ -216,9 +218,10 @@ public interface StatusBarPhoneModule {
remoteInputQuickSettingsDisabler,
notificationGutsManager,
notificationLogger,
notificationInterruptStateProvider,
notificationInterruptionStateProvider,
notificationViewHierarchyManager,
keyguardViewMediator,
notificationAlertingManager,
displayMetrics,
metricsLogger,
uiBgExecutor,

View File

@@ -45,11 +45,7 @@ import android.app.IActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.res.Resources;
import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.face.FaceManager;
import android.os.Handler;
import android.os.PowerManager;
import android.service.dreams.IDreamManager;
import android.service.notification.ZenModeConfig;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -65,12 +61,14 @@ import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoveInterceptor;
import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
@@ -229,17 +227,15 @@ public class BubbleControllerTest extends SysuiTestCase {
mZenModeConfig.suppressedVisualEffects = 0;
when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
TestableNotificationInterruptStateProviderImpl interruptionStateProvider =
new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
mock(PowerManager.class),
mock(IDreamManager.class),
mock(AmbientDisplayConfiguration.class),
TestableNotificationInterruptionStateProvider interruptionStateProvider =
new TestableNotificationInterruptionStateProvider(mContext,
mock(NotificationFilter.class),
mock(StatusBarStateController.class),
mock(BatteryController.class),
mock(HeadsUpManager.class),
mock(Handler.class)
);
mock(BatteryController.class));
interruptionStateProvider.setUpWithPresenter(
mock(NotificationPresenter.class),
mock(HeadsUpManager.class),
mock(NotificationInterruptionStateProvider.HeadsUpSuppressor.class));
mBubbleData = new BubbleData(mContext);
when(mFeatureFlagsOldPipeline.isNewNotifPipelineRenderingEnabled()).thenReturn(false);
mBubbleController = new TestableBubbleController(

View File

@@ -41,11 +41,7 @@ import android.app.IActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.res.Resources;
import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.face.FaceManager;
import android.os.Handler;
import android.os.PowerManager;
import android.service.dreams.IDreamManager;
import android.service.notification.ZenModeConfig;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -61,10 +57,12 @@ import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
@@ -218,17 +216,15 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
mZenModeConfig.suppressedVisualEffects = 0;
when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
TestableNotificationInterruptStateProviderImpl interruptionStateProvider =
new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
mock(PowerManager.class),
mock(IDreamManager.class),
mock(AmbientDisplayConfiguration.class),
TestableNotificationInterruptionStateProvider interruptionStateProvider =
new TestableNotificationInterruptionStateProvider(mContext,
mock(NotificationFilter.class),
mock(StatusBarStateController.class),
mock(BatteryController.class),
mock(HeadsUpManager.class),
mock(Handler.class)
);
mock(BatteryController.class));
interruptionStateProvider.setUpWithPresenter(
mock(NotificationPresenter.class),
mock(HeadsUpManager.class),
mock(NotificationInterruptionStateProvider.HeadsUpSuppressor.class));
mBubbleData = new BubbleData(mContext);
when(mFeatureFlagsNewPipeline.isNewNotifPipelineRenderingEnabled()).thenReturn(true);
mBubbleController = new TestableBubbleController(

View File

@@ -23,8 +23,8 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -44,7 +44,7 @@ public class TestableBubbleController extends BubbleController {
ShadeController shadeController,
BubbleData data,
ConfigurationController configurationController,
NotificationInterruptStateProvider interruptionStateProvider,
NotificationInterruptionStateProvider interruptionStateProvider,
ZenModeController zenModeController,
NotificationLockscreenUserManager lockscreenUserManager,
NotificationGroupManager groupManager,

View File

@@ -1,55 +0,0 @@
/*
* Copyright (C) 2020 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.bubbles;
import android.content.ContentResolver;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
import android.os.PowerManager;
import android.service.dreams.IDreamManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
public class TestableNotificationInterruptStateProviderImpl
extends NotificationInterruptStateProviderImpl {
TestableNotificationInterruptStateProviderImpl(
ContentResolver contentResolver,
PowerManager powerManager,
IDreamManager dreamManager,
AmbientDisplayConfiguration ambientDisplayConfiguration,
NotificationFilter filter,
StatusBarStateController statusBarStateController,
BatteryController batteryController,
HeadsUpManager headsUpManager,
Handler mainHandler) {
super(contentResolver,
powerManager,
dreamManager,
ambientDisplayConfiguration,
filter,
batteryController,
statusBarStateController,
headsUpManager,
mainHandler);
mUseHeadsUp = true;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2020 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.bubbles;
import android.content.Context;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.policy.BatteryController;
public class TestableNotificationInterruptionStateProvider
extends NotificationInterruptionStateProvider {
TestableNotificationInterruptionStateProvider(Context context,
NotificationFilter filter, StatusBarStateController controller,
BatteryController batteryController) {
super(context, filter, controller, batteryController);
mUseHeadsUp = true;
}
}

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.notification.interruption;
package com.android.systemui.statusbar;
import static android.app.Notification.FLAG_BUBBLE;
@@ -30,14 +30,15 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
import android.os.PowerManager;
import android.os.RemoteException;
import android.service.dreams.IDreamManager;
@@ -49,6 +50,7 @@ import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -66,7 +68,7 @@ import org.mockito.MockitoAnnotations;
*/
@RunWith(AndroidTestingRunner.class)
@SmallTest
public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
public class NotificationInterruptionStateProviderTest extends SysuiTestCase {
@Mock
PowerManager mPowerManager;
@@ -79,36 +81,38 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
@Mock
StatusBarStateController mStatusBarStateController;
@Mock
NotificationPresenter mPresenter;
@Mock
HeadsUpManager mHeadsUpManager;
@Mock
BatteryController mBatteryController;
NotificationInterruptionStateProvider.HeadsUpSuppressor mHeadsUpSuppressor;
@Mock
Handler mMockHandler;
BatteryController mBatteryController;
private NotificationInterruptStateProviderImpl mNotifInterruptionStateProvider;
private NotificationInterruptionStateProvider mNotifInterruptionStateProvider;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mNotifInterruptionStateProvider =
new NotificationInterruptStateProviderImpl(
mContext.getContentResolver(),
new TestableNotificationInterruptionStateProvider(mContext,
mPowerManager,
mDreamManager,
mAmbientDisplayConfiguration,
mNotificationFilter,
mBatteryController,
mStatusBarStateController,
mHeadsUpManager,
mMockHandler);
mBatteryController);
mNotifInterruptionStateProvider.mUseHeadsUp = true;
mNotifInterruptionStateProvider.setUpWithPresenter(
mPresenter,
mHeadsUpManager,
mHeadsUpSuppressor);
}
/**
* Sets up the state such that any requests to
* {@link NotificationInterruptStateProviderImpl#canAlertCommon(NotificationEntry)} will
* {@link NotificationInterruptionStateProvider#canAlertCommon(NotificationEntry)} will
* pass as long its provided NotificationEntry fulfills group suppression check.
*/
private void ensureStateForAlertCommon() {
@@ -117,16 +121,17 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
/**
* Sets up the state such that any requests to
* {@link NotificationInterruptStateProviderImpl#canAlertAwakeCommon(NotificationEntry)} will
* {@link NotificationInterruptionStateProvider#canAlertAwakeCommon(NotificationEntry)} will
* pass as long its provided NotificationEntry fulfills launch fullscreen check.
*/
private void ensureStateForAlertAwakeCommon() {
when(mPresenter.isDeviceInVrMode()).thenReturn(false);
when(mHeadsUpManager.isSnoozed(any())).thenReturn(false);
}
/**
* Sets up the state such that any requests to
* {@link NotificationInterruptStateProviderImpl#shouldHeadsUp(NotificationEntry)} will
* {@link NotificationInterruptionStateProvider#shouldHeadsUp(NotificationEntry)} will
* pass as long its provided NotificationEntry fulfills importance & DND checks.
*/
private void ensureStateForHeadsUpWhenAwake() throws RemoteException {
@@ -136,11 +141,12 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
when(mStatusBarStateController.isDozing()).thenReturn(false);
when(mDreamManager.isDreaming()).thenReturn(false);
when(mPowerManager.isScreenOn()).thenReturn(true);
when(mHeadsUpSuppressor.canHeadsUp(any(), any())).thenReturn(true);
}
/**
* Sets up the state such that any requests to
* {@link NotificationInterruptStateProviderImpl#shouldHeadsUp(NotificationEntry)} will
* {@link NotificationInterruptionStateProvider#shouldHeadsUp(NotificationEntry)} will
* pass as long its provided NotificationEntry fulfills importance & DND checks.
*/
private void ensureStateForHeadsUpWhenDozing() {
@@ -152,7 +158,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
/**
* Sets up the state such that any requests to
* {@link NotificationInterruptStateProviderImpl#shouldBubbleUp(NotificationEntry)} will
* {@link NotificationInterruptionStateProvider#shouldBubbleUp(NotificationEntry)} will
* pass as long its provided NotificationEntry fulfills importance & bubble checks.
*/
private void ensureStateForBubbleUp() {
@@ -160,53 +166,75 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
ensureStateForAlertAwakeCommon();
}
/**
* Ensure that the disabled state is set correctly.
*/
@Test
public void testDefaultSuppressorDoesNotSuppress() {
// GIVEN a suppressor without any overrides
final NotificationInterruptSuppressor defaultSuppressor =
new NotificationInterruptSuppressor() {
@Override
public String getName() {
return "defaultSuppressor";
}
};
public void testDisableNotificationAlerts() {
// Enabled by default
assertThat(mNotifInterruptionStateProvider.areNotificationAlertsDisabled()).isFalse();
// Disable alerts
mNotifInterruptionStateProvider.setDisableNotificationAlerts(true);
assertThat(mNotifInterruptionStateProvider.areNotificationAlertsDisabled()).isTrue();
// Enable alerts
mNotifInterruptionStateProvider.setDisableNotificationAlerts(false);
assertThat(mNotifInterruptionStateProvider.areNotificationAlertsDisabled()).isFalse();
}
/**
* Ensure that the disabled alert state effects whether HUNs are enabled.
*/
@Test
public void testHunSettingsChange_enabled_butAlertsDisabled() {
// Set up but without a mock change observer
mNotifInterruptionStateProvider.setUpWithPresenter(
mPresenter,
mHeadsUpManager,
mHeadsUpSuppressor);
// HUNs enabled by default
assertThat(mNotifInterruptionStateProvider.getUseHeadsUp()).isTrue();
// Set alerts disabled
mNotifInterruptionStateProvider.setDisableNotificationAlerts(true);
// No more HUNs
assertThat(mNotifInterruptionStateProvider.getUseHeadsUp()).isFalse();
}
/**
* Alerts can happen.
*/
@Test
public void testCanAlertCommon_true() {
ensureStateForAlertCommon();
NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
// THEN this suppressor doesn't suppress anything by default
assertThat(defaultSuppressor.suppressAwakeHeadsUp(entry)).isFalse();
assertThat(defaultSuppressor.suppressAwakeInterruptions(entry)).isFalse();
assertThat(defaultSuppressor.suppressInterruptions(entry)).isFalse();
assertThat(mNotifInterruptionStateProvider.canAlertCommon(entry)).isTrue();
}
/**
* Filtered out notifications don't alert.
*/
@Test
public void testShouldHeadsUpAwake() throws RemoteException {
ensureStateForHeadsUpWhenAwake();
public void testCanAlertCommon_false_filteredOut() {
ensureStateForAlertCommon();
when(mNotificationFilter.shouldFilterOut(any())).thenReturn(true);
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isTrue();
NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
assertThat(mNotifInterruptionStateProvider.canAlertCommon(entry)).isFalse();
}
/**
* Grouped notifications have different alerting behaviours, sometimes the alert for a
* grouped notification may be suppressed {@link android.app.Notification#GROUP_ALERT_CHILDREN}.
*/
@Test
public void testShouldNotHeadsUpAwake_flteredOut() throws RemoteException {
// GIVEN state for "heads up when awake" is true
ensureStateForHeadsUpWhenAwake();
public void testCanAlertCommon_false_suppressedForGroups() {
ensureStateForAlertCommon();
// WHEN this entry should be filtered out
NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
when(mNotificationFilter.shouldFilterOut(entry)).thenReturn(true);
// THEN we shouldn't heads up this entry
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
}
@Test
public void testShouldNotHeadsUp_suppressedForGroups() throws RemoteException {
// GIVEN state for "heads up when awake" is true
ensureStateForHeadsUpWhenAwake();
// WHEN the alert for a grouped notification is suppressed
// see {@link android.app.Notification#GROUP_ALERT_CHILDREN}
NotificationEntry entry = new NotificationEntryBuilder()
.setPkg("a")
.setOpPkg("a")
@@ -219,40 +247,40 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
.setImportance(IMPORTANCE_DEFAULT)
.build();
// THEN this entry shouldn't HUN
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
assertThat(mNotifInterruptionStateProvider.canAlertCommon(entry)).isFalse();
}
/**
* HUNs while dozing can happen.
*/
@Test
public void testShouldHeadsUpWhenDozing() {
public void testShouldHeadsUpWhenDozing_true() {
ensureStateForHeadsUpWhenDozing();
NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isTrue();
}
/**
* Ambient display can show HUNs for new notifications, this may be disabled.
*/
@Test
public void testShouldNotHeadsUpWhenDozing_pulseDisabled() {
// GIVEN state for "heads up when dozing" is true
public void testShouldHeadsUpWhenDozing_false_pulseDisabled() {
ensureStateForHeadsUpWhenDozing();
// WHEN pulsing (HUNs when dozing) is disabled
when(mAmbientDisplayConfiguration.pulseOnNotificationEnabled(anyInt())).thenReturn(false);
// THEN this entry shouldn't HUN
NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
}
/**
* If the device is not in ambient display or sleeping then we don't HUN.
*/
@Test
public void testShouldNotHeadsUpWhenDozing_notDozing() {
// GIVEN state for "heads up when dozing" is true
public void testShouldHeadsUpWhenDozing_false_notDozing() {
ensureStateForHeadsUpWhenDozing();
// WHEN we're not dozing (in ambient display or sleeping)
when(mStatusBarStateController.isDozing()).thenReturn(false);
// THEN this entry shouldn't HUN
NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
}
@@ -262,7 +290,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
* {@link android.app.NotificationManager.Policy#SUPPRESSED_EFFECT_AMBIENT}.
*/
@Test
public void testShouldNotHeadsUpWhenDozing_suppressingAmbient() {
public void testShouldHeadsUpWhenDozing_false_suppressingAmbient() {
ensureStateForHeadsUpWhenDozing();
NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
@@ -273,30 +301,62 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
}
/**
* Notifications that are < {@link android.app.NotificationManager#IMPORTANCE_DEFAULT} don't
* get to pulse.
*/
@Test
public void testShouldNotHeadsUpWhenDozing_lessImportant() {
public void testShouldHeadsUpWhenDozing_false_lessImportant() {
ensureStateForHeadsUpWhenDozing();
// Notifications that are < {@link android.app.NotificationManager#IMPORTANCE_DEFAULT} don't
// get to pulse
NotificationEntry entry = createNotification(IMPORTANCE_LOW);
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
}
/**
* Heads up can happen.
*/
@Test
public void testShouldHeadsUp() throws RemoteException {
public void testShouldHeadsUp_true() throws RemoteException {
ensureStateForHeadsUpWhenAwake();
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isTrue();
}
/**
* Heads up notifications can be disabled in general.
*/
@Test
public void testShouldHeadsUp_false_noHunsAllowed() throws RemoteException {
ensureStateForHeadsUpWhenAwake();
// Set alerts disabled, this should cause heads up to be false
mNotifInterruptionStateProvider.setDisableNotificationAlerts(true);
assertThat(mNotifInterruptionStateProvider.getUseHeadsUp()).isFalse();
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
}
/**
* If the device is dozing, we don't show as heads up.
*/
@Test
public void testShouldHeadsUp_false_dozing() throws RemoteException {
ensureStateForHeadsUpWhenAwake();
when(mStatusBarStateController.isDozing()).thenReturn(true);
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
}
/**
* If the notification is a bubble, and the user is not on AOD / lockscreen, then
* the bubble is shown rather than the heads up.
*/
@Test
public void testShouldNotHeadsUp_bubble() throws RemoteException {
public void testShouldHeadsUp_false_bubble() throws RemoteException {
ensureStateForHeadsUpWhenAwake();
// Bubble bit only applies to interruption when we're in the shade
@@ -309,7 +369,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
* If we're not allowed to alert in general, we shouldn't be shown as heads up.
*/
@Test
public void testShouldNotHeadsUp_filtered() throws RemoteException {
public void testShouldHeadsUp_false_alertCommonFalse() throws RemoteException {
ensureStateForHeadsUpWhenAwake();
// Make canAlertCommon false by saying it's filtered out
when(mNotificationFilter.shouldFilterOut(any())).thenReturn(true);
@@ -323,7 +383,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
* {@link android.app.NotificationManager.Policy#SUPPRESSED_EFFECT_PEEK}.
*/
@Test
public void testShouldNotHeadsUp_suppressPeek() throws RemoteException {
public void testShouldHeadsUp_false_suppressPeek() throws RemoteException {
ensureStateForHeadsUpWhenAwake();
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
@@ -339,7 +399,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
* to show as a heads up.
*/
@Test
public void testShouldNotHeadsUp_lessImportant() throws RemoteException {
public void testShouldHeadsUp_false_lessImportant() throws RemoteException {
ensureStateForHeadsUpWhenAwake();
NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
@@ -350,7 +410,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
* If the device is not in use then we shouldn't be shown as heads up.
*/
@Test
public void testShouldNotHeadsUp_deviceNotInUse() throws RemoteException {
public void testShouldHeadsUp_false_deviceNotInUse() throws RemoteException {
ensureStateForHeadsUpWhenAwake();
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
@@ -364,58 +424,61 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
}
/**
* If something wants to suppress this heads up, then it shouldn't be shown as a heads up.
*/
@Test
public void testShouldNotHeadsUp_headsUpSuppressed() throws RemoteException {
public void testShouldHeadsUp_false_suppressed() throws RemoteException {
ensureStateForHeadsUpWhenAwake();
// If a suppressor is suppressing heads up, then it shouldn't be shown as a heads up.
mNotifInterruptionStateProvider.addSuppressor(mSuppressAwakeHeadsUp);
when(mHeadsUpSuppressor.canHeadsUp(any(), any())).thenReturn(false);
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
verify(mHeadsUpSuppressor).canHeadsUp(any(), any());
}
/**
* On screen alerts don't happen when the device is in VR Mode.
*/
@Test
public void testShouldNotHeadsUpAwake_awakeInterruptsSuppressed() throws RemoteException {
ensureStateForHeadsUpWhenAwake();
public void testCanAlertAwakeCommon__false_vrMode() {
ensureStateForAlertAwakeCommon();
when(mPresenter.isDeviceInVrMode()).thenReturn(true);
// If a suppressor is suppressing heads up, then it shouldn't be shown as a heads up.
mNotifInterruptionStateProvider.addSuppressor(mSuppressAwakeInterruptions);
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
assertThat(mNotifInterruptionStateProvider.canAlertAwakeCommon(entry)).isFalse();
}
/**
* On screen alerts don't happen when the notification is snoozed.
*/
@Test
public void testShouldNotHeadsUp_snoozedPackage() {
NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
public void testCanAlertAwakeCommon_false_snoozedPackage() {
ensureStateForAlertAwakeCommon();
when(mHeadsUpManager.isSnoozed(any())).thenReturn(true);
when(mHeadsUpManager.isSnoozed(entry.getSbn().getPackageName())).thenReturn(true);
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
assertThat(mNotifInterruptionStateProvider.canAlertAwakeCommon(entry)).isFalse();
}
/**
* On screen alerts don't happen when that package has just launched fullscreen.
*/
@Test
public void testShouldNotHeadsUp_justLaunchedFullscreen() {
public void testCanAlertAwakeCommon_false_justLaunchedFullscreen() {
ensureStateForAlertAwakeCommon();
// On screen alerts don't happen when that package has just launched fullscreen.
NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
entry.notifyFullScreenIntentLaunched();
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
assertThat(mNotifInterruptionStateProvider.canAlertAwakeCommon(entry)).isFalse();
}
/**
* Bubbles can happen.
*/
@Test
public void testShouldBubbleUp() {
public void testShouldBubbleUp_true() {
ensureStateForBubbleUp();
assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(createBubble())).isTrue();
}
@@ -424,7 +487,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
* If the notification doesn't have permission to bubble, it shouldn't bubble.
*/
@Test
public void shouldNotBubbleUp_notAllowedToBubble() {
public void shouldBubbleUp_false_notAllowedToBubble() {
ensureStateForBubbleUp();
NotificationEntry entry = createBubble();
@@ -439,7 +502,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
* If the notification isn't a bubble, it should definitely not show as a bubble.
*/
@Test
public void shouldNotBubbleUp_notABubble() {
public void shouldBubbleUp_false_notABubble() {
ensureStateForBubbleUp();
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
@@ -454,7 +517,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
* If the notification doesn't have bubble metadata, it shouldn't bubble.
*/
@Test
public void shouldNotBubbleUp_invalidMetadata() {
public void shouldBubbleUp_false_invalidMetadata() {
ensureStateForBubbleUp();
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
@@ -466,18 +529,24 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(entry)).isFalse();
}
/**
* If the notification can't heads up in general, it shouldn't bubble.
*/
@Test
public void shouldNotBubbleUp_suppressedInterruptions() {
public void shouldBubbleUp_false_alertAwakeCommonFalse() {
ensureStateForBubbleUp();
// If the notification can't heads up in general, it shouldn't bubble.
mNotifInterruptionStateProvider.addSuppressor(mSuppressInterruptions);
// Make alert common return false by pretending we're in VR mode
when(mPresenter.isDeviceInVrMode()).thenReturn(true);
assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(createBubble())).isFalse();
}
/**
* If the notification can't heads up in general, it shouldn't bubble.
*/
@Test
public void shouldNotBubbleUp_filteredOut() {
public void shouldBubbleUp_false_alertCommonFalse() {
ensureStateForBubbleUp();
// Make canAlertCommon false by saying it's filtered out
@@ -523,45 +592,20 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
.build();
}
private final NotificationInterruptSuppressor
mSuppressAwakeHeadsUp =
new NotificationInterruptSuppressor() {
@Override
public String getName() {
return "suppressAwakeHeadsUp";
}
/**
* Testable class overriding constructor.
*/
public static class TestableNotificationInterruptionStateProvider extends
NotificationInterruptionStateProvider {
@Override
public boolean suppressAwakeHeadsUp(NotificationEntry entry) {
return true;
TestableNotificationInterruptionStateProvider(Context context,
PowerManager powerManager, IDreamManager dreamManager,
AmbientDisplayConfiguration ambientDisplayConfiguration,
NotificationFilter notificationFilter,
StatusBarStateController statusBarStateController,
BatteryController batteryController) {
super(context, powerManager, dreamManager, ambientDisplayConfiguration,
notificationFilter, batteryController, statusBarStateController);
}
};
private final NotificationInterruptSuppressor
mSuppressAwakeInterruptions =
new NotificationInterruptSuppressor() {
@Override
public String getName() {
return "suppressAwakeInterruptions";
}
@Override
public boolean suppressAwakeInterruptions(NotificationEntry entry) {
return true;
}
};
private final NotificationInterruptSuppressor
mSuppressInterruptions =
new NotificationInterruptSuppressor() {
@Override
public String getName() {
return "suppressInterruptions";
}
@Override
public boolean suppressInterruptions(NotificationEntry entry) {
return true;
}
};
}
}

View File

@@ -56,12 +56,12 @@ import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
@@ -108,7 +108,7 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
@Mock private NotificationEntryListener mEntryListener;
@Mock private NotificationRowBinderImpl.BindRowCallback mBindCallback;
@Mock private HeadsUpManager mHeadsUpManager;
@Mock private NotificationInterruptStateProvider mNotificationInterruptionStateProvider;
@Mock private NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
@Mock private NotificationGutsManager mGutsManager;
@Mock private NotificationRemoteInputManager mRemoteInputManager;

View File

@@ -67,10 +67,10 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -183,7 +183,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
mock(StatusBarRemoteInputCallback.class), mock(NotificationGroupManager.class),
mock(NotificationLockscreenUserManager.class),
mKeyguardStateController,
mock(NotificationInterruptStateProvider.class), mock(MetricsLogger.class),
mock(NotificationInterruptionStateProvider.class), mock(MetricsLogger.class),
mock(LockPatternUtils.class), mHandler, mHandler, mUiBgExecutor,
mActivityIntentHelper, mBubbleController, mShadeController, mFeatureFlags,
mNotifPipeline, mNotifCollection)

View File

@@ -16,9 +16,8 @@ package com.android.systemui.statusbar.phone;
import static android.view.Display.DEFAULT_DISPLAY;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Notification;
@@ -36,7 +35,6 @@ import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.logging.testing.FakeMetricsLogger;
import com.android.systemui.ForegroundServiceNotificationListener;
import com.android.systemui.InitController;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -50,12 +48,12 @@ import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
@@ -64,7 +62,6 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import java.util.ArrayList;
@@ -75,9 +72,6 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
private StatusBarNotificationPresenter mStatusBarNotificationPresenter;
private NotificationInterruptStateProvider mNotificationInterruptStateProvider =
mock(NotificationInterruptStateProvider.class);
private NotificationInterruptSuppressor mInterruptSuppressor;
private CommandQueue mCommandQueue;
private FakeMetricsLogger mMetricsLogger;
private ShadeController mShadeController = mock(ShadeController.class);
@@ -101,11 +95,11 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
mDependency.injectMockDependency(NotificationViewHierarchyManager.class);
mDependency.injectMockDependency(NotificationRemoteInputManager.Callback.class);
mDependency.injectMockDependency(NotificationLockscreenUserManager.class);
mDependency.injectMockDependency(NotificationInterruptionStateProvider.class);
mDependency.injectMockDependency(NotificationMediaManager.class);
mDependency.injectMockDependency(VisualStabilityManager.class);
mDependency.injectMockDependency(NotificationGutsManager.class);
mDependency.injectMockDependency(NotificationShadeWindowController.class);
mDependency.injectMockDependency(ForegroundServiceNotificationListener.class);
NotificationEntryManager entryManager =
mDependency.injectMockDependency(NotificationEntryManager.class);
when(entryManager.getActiveNotificationsForCurrentUser()).thenReturn(new ArrayList<>());
@@ -113,25 +107,18 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
NotificationShadeWindowView notificationShadeWindowView =
mock(NotificationShadeWindowView.class);
when(notificationShadeWindowView.getResources()).thenReturn(mContext.getResources());
mStatusBarNotificationPresenter = new StatusBarNotificationPresenter(mContext,
mock(NotificationPanelViewController.class), mock(HeadsUpManagerPhone.class),
notificationShadeWindowView, mock(NotificationListContainerViewGroup.class),
mock(DozeScrimController.class), mock(ScrimController.class),
mock(ActivityLaunchAnimator.class), mock(DynamicPrivacyController.class),
mock(KeyguardStateController.class),
mock(NotificationAlertingManager.class), mock(KeyguardStateController.class),
mock(KeyguardIndicationController.class), mStatusBar,
mock(ShadeControllerImpl.class), mCommandQueue, mInitController,
mNotificationInterruptStateProvider);
mInitController.executePostInitTasks();
ArgumentCaptor<NotificationInterruptSuppressor> suppressorCaptor =
ArgumentCaptor.forClass(NotificationInterruptSuppressor.class);
verify(mNotificationInterruptStateProvider).addSuppressor(suppressorCaptor.capture());
mInterruptSuppressor = suppressorCaptor.getValue();
mock(ShadeControllerImpl.class), mCommandQueue, mInitController);
}
@Test
public void testSuppressHeadsUp_disabledStatusBar() {
public void testHeadsUp_disabledStatusBar() {
Notification n = new Notification.Builder(getContext(), "a").build();
NotificationEntry entry = new NotificationEntryBuilder()
.setPkg("a")
@@ -143,12 +130,12 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
false /* animate */);
TestableLooper.get(this).processAllMessages();
assertTrue("The panel should suppress heads up while disabled",
mInterruptSuppressor.suppressAwakeHeadsUp(entry));
assertFalse("The panel shouldn't allow heads up while disabled",
mStatusBarNotificationPresenter.canHeadsUp(entry, entry.getSbn()));
}
@Test
public void testSuppressHeadsUp_disabledNotificationShade() {
public void testHeadsUp_disabledNotificationShade() {
Notification n = new Notification.Builder(getContext(), "a").build();
NotificationEntry entry = new NotificationEntryBuilder()
.setPkg("a")
@@ -160,39 +147,8 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
false /* animate */);
TestableLooper.get(this).processAllMessages();
assertTrue("The panel should suppress interruptions while notification shade "
+ "disabled",
mInterruptSuppressor.suppressAwakeHeadsUp(entry));
}
@Test
public void testSuppressInterruptions_vrMode() {
Notification n = new Notification.Builder(getContext(), "a").build();
NotificationEntry entry = new NotificationEntryBuilder()
.setPkg("a")
.setOpPkg("a")
.setTag("a")
.setNotification(n)
.build();
mStatusBarNotificationPresenter.mVrMode = true;
assertTrue("Vr mode should suppress interruptions",
mInterruptSuppressor.suppressAwakeInterruptions(entry));
}
@Test
public void testSuppressInterruptions_statusBarAlertsDisabled() {
Notification n = new Notification.Builder(getContext(), "a").build();
NotificationEntry entry = new NotificationEntryBuilder()
.setPkg("a")
.setOpPkg("a")
.setTag("a")
.setNotification(n)
.build();
when(mStatusBar.areNotificationAlertsDisabled()).thenReturn(true);
assertTrue("StatusBar alerts disabled shouldn't allow interruptions",
mInterruptSuppressor.suppressInterruptions(entry));
assertFalse("The panel shouldn't allow heads up while notitifcation shade disabled",
mStatusBarNotificationPresenter.canHeadsUp(entry, entry.getSbn()));
}
@Test
@@ -216,3 +172,4 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
}
}
}

View File

@@ -42,7 +42,7 @@ import android.app.Notification;
import android.app.StatusBarManager;
import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IntentFilter;
import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.fingerprint.FingerprintManager;
@@ -109,17 +109,18 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
@@ -128,7 +129,6 @@ import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
@@ -160,7 +160,7 @@ public class StatusBarTest extends SysuiTestCase {
private StatusBar mStatusBar;
private FakeMetricsLogger mMetricsLogger;
private PowerManager mPowerManager;
private TestableNotificationInterruptStateProviderImpl mNotificationInterruptStateProvider;
private TestableNotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
@Mock private NotificationsController mNotificationsController;
@Mock private LightBarController mLightBarController;
@@ -178,6 +178,7 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private DozeScrimController mDozeScrimController;
@Mock private Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
@Mock private BiometricUnlockController mBiometricUnlockController;
@Mock private NotificationInterruptionStateProvider.HeadsUpSuppressor mHeadsUpSuppressor;
@Mock private VisualStabilityManager mVisualStabilityManager;
@Mock private NotificationListener mNotificationListener;
@Mock private KeyguardViewMediator mKeyguardViewMediator;
@@ -190,9 +191,10 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private StatusBarNotificationPresenter mNotificationPresenter;
@Mock private NotificationEntryListener mEntryListener;
@Mock private NotificationFilter mNotificationFilter;
@Mock private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
@Mock private NotificationAlertingManager mNotificationAlertingManager;
@Mock private NotificationLogger.ExpansionStateLogger mExpansionStateLogger;
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
@Mock private NotificationShadeWindowView mNotificationShadeWindowView;
@Mock private BroadcastDispatcher mBroadcastDispatcher;
@Mock private AssistManager mAssistManager;
@@ -260,12 +262,10 @@ public class StatusBarTest extends SysuiTestCase {
mPowerManager = new PowerManager(mContext, powerManagerService, thermalService,
Handler.createAsync(Looper.myLooper()));
mNotificationInterruptStateProvider =
new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
mPowerManager,
mNotificationInterruptionStateProvider =
new TestableNotificationInterruptionStateProvider(mContext, mPowerManager,
mDreamManager, mAmbientDisplayConfiguration, mNotificationFilter,
mStatusBarStateController, mBatteryController, mHeadsUpManager,
new Handler(TestableLooper.get(this).getLooper()));
mStatusBarStateController, mBatteryController);
mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
@@ -298,6 +298,9 @@ public class StatusBarTest extends SysuiTestCase {
return null;
}).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any());
mNotificationInterruptionStateProvider.setUpWithPresenter(mNotificationPresenter,
mHeadsUpManager, mHeadsUpSuppressor);
when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
WakefulnessLifecycle wakefulnessLifecycle = new WakefulnessLifecycle();
@@ -344,9 +347,10 @@ public class StatusBarTest extends SysuiTestCase {
),
mNotificationGutsManager,
notificationLogger,
mNotificationInterruptStateProvider,
mNotificationInterruptionStateProvider,
mNotificationViewHierarchyManager,
mKeyguardViewMediator,
mNotificationAlertingManager,
new DisplayMetrics(),
mMetricsLogger,
mUiBgExecutor,
@@ -557,6 +561,7 @@ public class StatusBarTest extends SysuiTestCase {
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
when(mNotificationFilter.shouldFilterOut(any())).thenReturn(false);
when(mDreamManager.isDreaming()).thenReturn(false);
when(mHeadsUpSuppressor.canHeadsUp(any(), any())).thenReturn(true);
Notification n = new Notification.Builder(getContext(), "a")
.setGroup("a")
@@ -572,7 +577,7 @@ public class StatusBarTest extends SysuiTestCase {
.setImportance(IMPORTANCE_HIGH)
.build();
assertTrue(mNotificationInterruptStateProvider.shouldHeadsUp(entry));
assertTrue(mNotificationInterruptionStateProvider.shouldHeadsUp(entry));
}
@Test
@@ -581,6 +586,7 @@ public class StatusBarTest extends SysuiTestCase {
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
when(mNotificationFilter.shouldFilterOut(any())).thenReturn(false);
when(mDreamManager.isDreaming()).thenReturn(false);
when(mHeadsUpSuppressor.canHeadsUp(any(), any())).thenReturn(true);
Notification n = new Notification.Builder(getContext(), "a")
.setGroup("a")
@@ -596,7 +602,7 @@ public class StatusBarTest extends SysuiTestCase {
.setImportance(IMPORTANCE_HIGH)
.build();
assertFalse(mNotificationInterruptStateProvider.shouldHeadsUp(entry));
assertFalse(mNotificationInterruptionStateProvider.shouldHeadsUp(entry));
}
@Test
@@ -605,6 +611,7 @@ public class StatusBarTest extends SysuiTestCase {
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
when(mNotificationFilter.shouldFilterOut(any())).thenReturn(false);
when(mDreamManager.isDreaming()).thenReturn(false);
when(mHeadsUpSuppressor.canHeadsUp(any(), any())).thenReturn(true);
Notification n = new Notification.Builder(getContext(), "a").build();
@@ -617,7 +624,7 @@ public class StatusBarTest extends SysuiTestCase {
.setSuppressedVisualEffects(SUPPRESSED_EFFECT_PEEK)
.build();
assertFalse(mNotificationInterruptStateProvider.shouldHeadsUp(entry));
assertFalse(mNotificationInterruptionStateProvider.shouldHeadsUp(entry));
}
@Test
@@ -626,6 +633,7 @@ public class StatusBarTest extends SysuiTestCase {
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
when(mNotificationFilter.shouldFilterOut(any())).thenReturn(false);
when(mDreamManager.isDreaming()).thenReturn(false);
when(mHeadsUpSuppressor.canHeadsUp(any(), any())).thenReturn(true);
Notification n = new Notification.Builder(getContext(), "a").build();
@@ -637,7 +645,7 @@ public class StatusBarTest extends SysuiTestCase {
.setImportance(IMPORTANCE_HIGH)
.build();
assertTrue(mNotificationInterruptStateProvider.shouldHeadsUp(entry));
assertTrue(mNotificationInterruptionStateProvider.shouldHeadsUp(entry));
}
@Test
@@ -863,21 +871,19 @@ public class StatusBarTest extends SysuiTestCase {
verify(mDozeServiceHost).setDozeSuppressed(false);
}
public static class TestableNotificationInterruptStateProviderImpl extends
NotificationInterruptStateProviderImpl {
public static class TestableNotificationInterruptionStateProvider extends
NotificationInterruptionStateProvider {
TestableNotificationInterruptStateProviderImpl(
ContentResolver contentResolver,
TestableNotificationInterruptionStateProvider(
Context context,
PowerManager powerManager,
IDreamManager dreamManager,
AmbientDisplayConfiguration ambientDisplayConfiguration,
NotificationFilter filter,
StatusBarStateController controller,
BatteryController batteryController,
HeadsUpManager headsUpManager,
Handler mainHandler) {
super(contentResolver, powerManager, dreamManager, ambientDisplayConfiguration, filter,
batteryController, controller, headsUpManager, mainHandler);
BatteryController batteryController) {
super(context, powerManager, dreamManager, ambientDisplayConfiguration, filter,
batteryController, controller);
mUseHeadsUp = true;
}
}