diff options
| author | 2020-03-09 20:25:28 +0000 | |
|---|---|---|
| committer | 2020-03-09 20:25:28 +0000 | |
| commit | ab3f32b34659234292d007d61f37550a9391217a (patch) | |
| tree | d9abe8e11c9091b3f220aa9289f9394af2c4a8c9 | |
| parent | fb2441b80845a6e283860fc27411086d9ee442c7 (diff) | |
| parent | bcb499478af43fa6bd7626da45f5ba937e8abf2e (diff) | |
Merge "Revert "Create interface for NotifInterruptStateProvider"" into rvc-dev
30 files changed, 660 insertions, 730 deletions
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java index 22c3acf6f1eb..6f985a4e4ddb 100644 --- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java +++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java @@ -24,6 +24,7 @@ import android.content.Context; import com.android.keyguard.KeyguardViewController; import com.android.systemui.car.CarDeviceProvisionedController; 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; @@ -40,6 +41,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; @@ -63,6 +65,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) diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java new file mode 100644 index 000000000000..447e579ece42 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java @@ -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); + } +} diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index de768cbf0877..b2e21045f2a9 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -95,14 +95,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; @@ -250,9 +249,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, @@ -335,9 +335,10 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt remoteInputQuickSettingsDisabler, notificationGutsManager, notificationLogger, - notificationInterruptStateProvider, + notificationInterruptionStateProvider, notificationViewHierarchyManager, keyguardViewMediator, + notificationAlertingManager, displayMetrics, metricsLogger, uiBgExecutor, @@ -487,22 +488,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 diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java index 9a535844d9d8..4754118e7a64 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java @@ -62,12 +62,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; @@ -145,9 +146,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, @@ -232,6 +234,7 @@ public class CarStatusBarModule { notificationInterruptionStateProvider, notificationViewHierarchyManager, keyguardViewMediator, + notificationAlertingManager, displayMetrics, metricsLogger, uiBgExecutor, diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index b6152dae33d6..a868cf58cf7c 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -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, diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index f873f42dd918..48457f627e83 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java index 27c9e9895324..ac97d8aab326 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java @@ -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, diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java index 3a4b273e1c98..6c502d273a1c 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java @@ -90,7 +90,7 @@ public class DependencyProvider { /** */ @Provides - public AmbientDisplayConfiguration provideAmbientDisplayConfiguration(Context context) { + public AmbientDisplayConfiguration provideAmbientDispalyConfiguration(Context context) { return new AmbientDisplayConfiguration(context); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/BypassHeadsUpNotifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt index 88888d10e283..269a7a59f1b7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/BypassHeadsUpNotifier.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationAlertingManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java index b5725029450d..df21f0b21ec1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationAlertingManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java @@ -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) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java index 46d50441c06b..bbf2dde80040 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java @@ -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 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); + + } + } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt index 27476964b9af..8a23e3796e9b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt @@ -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) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java index 4beeedecfdf5..e8a62e48e75e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java index cd6affdaffac..3c0ac7ef53fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java @@ -31,8 +31,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; @@ -42,9 +44,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; @@ -57,7 +56,6 @@ import java.util.concurrent.Executor; import javax.inject.Singleton; -import dagger.Binds; import dagger.Lazy; import dagger.Module; import dagger.Provides; @@ -127,7 +125,7 @@ public interface NotificationsModule { NotificationRemoteInputManager remoteInputManager, VisualStabilityManager visualStabilityManager, StatusBarStateController statusBarStateController, - NotificationInterruptStateProvider notificationInterruptStateProvider, + NotificationInterruptionStateProvider notificationInterruptionStateProvider, NotificationListener notificationListener, HeadsUpManager headsUpManager) { return new NotificationAlertingManager( @@ -135,7 +133,7 @@ public interface NotificationsModule { remoteInputManager, visualStabilityManager, statusBarStateController, - notificationInterruptStateProvider, + notificationInterruptionStateProvider, notificationListener, headsUpManager); } @@ -201,9 +199,4 @@ public interface NotificationsModule { NotificationEntryManager entryManager) { return featureFlags.isNewNotifPipelineRenderingEnabled() ? pipeline.get() : entryManager; } - - /** */ - @Binds - NotificationInterruptStateProvider bindNotificationInterruptStateProvider( - NotificationInterruptStateProviderImpl notificationInterruptStateProviderImpl); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java deleted file mode 100644 index 3292a8fcdb50..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java +++ /dev/null @@ -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); -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptSuppressor.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptSuppressor.java deleted file mode 100644 index c19f8bd1994a..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptSuppressor.java +++ /dev/null @@ -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; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 8fcbab515759..b3a62d8a4753 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -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(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index 53fa2630a9c3..e1a20b6ac5d3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -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, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index 79cea91b8612..30d6b5079166 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -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(); - } - }; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java index 824e0f0d4295..eec8d50f00de 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java @@ -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, diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java index 977d0bbd0004..742e652a7189 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java @@ -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( diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java index 7fc83dac0280..22ef3f34cb4d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java @@ -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( diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java index d3d90c408468..de1fb41ddbbd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java @@ -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, diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableNotificationInterruptStateProviderImpl.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableNotificationInterruptStateProviderImpl.java deleted file mode 100644 index 17dc76b38a56..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableNotificationInterruptStateProviderImpl.java +++ /dev/null @@ -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; - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableNotificationInterruptionStateProvider.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableNotificationInterruptionStateProvider.java new file mode 100644 index 000000000000..5d192b2071b5 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableNotificationInterruptionStateProvider.java @@ -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; + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInterruptionStateProviderTest.java index f9c62e1ab604..1693e7f4df7f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInterruptionStateProviderTest.java @@ -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(); - NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT); + // Disable alerts + mNotifInterruptionStateProvider.setDisableNotificationAlerts(true); + assertThat(mNotifInterruptionStateProvider.areNotificationAlertsDisabled()).isTrue(); - // THEN this suppressor doesn't suppress anything by default - assertThat(defaultSuppressor.suppressAwakeHeadsUp(entry)).isFalse(); - assertThat(defaultSuppressor.suppressAwakeInterruptions(entry)).isFalse(); - assertThat(defaultSuppressor.suppressInterruptions(entry)).isFalse(); + // Enable alerts + mNotifInterruptionStateProvider.setDisableNotificationAlerts(false); + assertThat(mNotifInterruptionStateProvider.areNotificationAlertsDisabled()).isFalse(); } + /** + * Ensure that the disabled alert state effects whether HUNs are enabled. + */ @Test - public void testShouldHeadsUpAwake() throws RemoteException { - ensureStateForHeadsUpWhenAwake(); + public void testHunSettingsChange_enabled_butAlertsDisabled() { + // Set up but without a mock change observer + mNotifInterruptionStateProvider.setUpWithPresenter( + mPresenter, + mHeadsUpManager, + mHeadsUpSuppressor); - NotificationEntry entry = createNotification(IMPORTANCE_HIGH); - assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isTrue(); + // 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 testShouldNotHeadsUpAwake_flteredOut() throws RemoteException { - // GIVEN state for "heads up when awake" is true - ensureStateForHeadsUpWhenAwake(); + public void testCanAlertCommon_true() { + ensureStateForAlertCommon(); - // WHEN this entry should be filtered out - NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT); - when(mNotificationFilter.shouldFilterOut(entry)).thenReturn(true); + NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT); + assertThat(mNotifInterruptionStateProvider.canAlertCommon(entry)).isTrue(); + } - // THEN we shouldn't heads up this entry - assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse(); + /** + * Filtered out notifications don't alert. + */ + @Test + public void testCanAlertCommon_false_filteredOut() { + ensureStateForAlertCommon(); + when(mNotificationFilter.shouldFilterOut(any())).thenReturn(true); + + 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 testShouldNotHeadsUp_suppressedForGroups() throws RemoteException { - // GIVEN state for "heads up when awake" is true - ensureStateForHeadsUpWhenAwake(); + public void testCanAlertCommon_false_suppressedForGroups() { + ensureStateForAlertCommon(); - // 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,18 +301,23 @@ 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); @@ -292,11 +325,38 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { } /** + * 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(); - - // If a suppressor is suppressing heads up, then it shouldn't be shown as a heads up. - mNotifInterruptionStateProvider.addSuppressor(mSuppressAwakeInterruptions); + public void testCanAlertAwakeCommon__false_vrMode() { + ensureStateForAlertAwakeCommon(); + when(mPresenter.isDeviceInVrMode()).thenReturn(true); - 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"; - } - - @Override - public boolean suppressAwakeHeadsUp(NotificationEntry entry) { - return true; - } - }; - - 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; + /** + * Testable class overriding constructor. + */ + public static class TestableNotificationInterruptionStateProvider extends + NotificationInterruptionStateProvider { + + TestableNotificationInterruptionStateProvider(Context context, + PowerManager powerManager, IDreamManager dreamManager, + AmbientDisplayConfiguration ambientDisplayConfiguration, + NotificationFilter notificationFilter, + StatusBarStateController statusBarStateController, + BatteryController batteryController) { + super(context, powerManager, dreamManager, ambientDisplayConfiguration, + notificationFilter, batteryController, statusBarStateController); } - }; + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java index a21a047d9a70..5d0349dbbb60 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java @@ -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; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java index b9c5b7c02b1c..1e4df272b02b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java @@ -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) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java index 318e9b87fa70..b9d2d229cd69 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java @@ -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 { } } } + diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index d9f4d4b8f758..0d7734e13621 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -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; } } |