New pipeline: Fix notification re-inflation on dark mode change.

Fixes: 201329618
Fixes: 201413798
Test: tap dark mode QS tile
Test: atest PreparationCoordinatorTest ShadeEventCoordinatorTest
Change-Id: I05931f89596b4145f2c5d31cb32b2d451fc280b6
This commit is contained in:
Jeff DeCew
2021-09-28 16:27:26 +00:00
parent d5b52e01d1
commit fc40850f0e
15 changed files with 548 additions and 46 deletions

View File

@@ -15,7 +15,7 @@ class GutsCoordinatorLogger @Inject constructor(
fun logGutsOpened(key: String, guts: NotificationGuts) { fun logGutsOpened(key: String, guts: NotificationGuts) {
buffer.log(TAG, LogLevel.DEBUG, { buffer.log(TAG, LogLevel.DEBUG, {
str1 = key str1 = key
str2 = guts::class.simpleName str2 = guts.gutsContent::class.simpleName
bool1 = guts.isLeavebehind bool1 = guts.isLeavebehind
}, { }, {
"Guts of type $str2 (leave behind: $bool1) opened for class $str1" "Guts of type $str2 (leave behind: $bool1) opened for class $str1"

View File

@@ -61,7 +61,9 @@ public class NotifCoordinators implements Dumpable {
ConversationCoordinator conversationCoordinator, ConversationCoordinator conversationCoordinator,
PreparationCoordinator preparationCoordinator, PreparationCoordinator preparationCoordinator,
MediaCoordinator mediaCoordinator, MediaCoordinator mediaCoordinator,
ShadeEventCoordinator shadeEventCoordinator,
SmartspaceDedupingCoordinator smartspaceDedupingCoordinator, SmartspaceDedupingCoordinator smartspaceDedupingCoordinator,
ViewConfigCoordinator viewConfigCoordinator,
VisualStabilityCoordinator visualStabilityCoordinator, VisualStabilityCoordinator visualStabilityCoordinator,
CommunalCoordinator communalCoordinator) { CommunalCoordinator communalCoordinator) {
dumpManager.registerDumpable(TAG, this); dumpManager.registerDumpable(TAG, this);
@@ -75,6 +77,8 @@ public class NotifCoordinators implements Dumpable {
mCoordinators.add(bubbleCoordinator); mCoordinators.add(bubbleCoordinator);
mCoordinators.add(conversationCoordinator); mCoordinators.add(conversationCoordinator);
mCoordinators.add(mediaCoordinator); mCoordinators.add(mediaCoordinator);
mCoordinators.add(shadeEventCoordinator);
mCoordinators.add(viewConfigCoordinator);
mCoordinators.add(visualStabilityCoordinator); mCoordinators.add(visualStabilityCoordinator);
mCoordinators.add(communalCoordinator); mCoordinators.add(communalCoordinator);

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.notification.collection.coordinator
import android.service.notification.NotificationListenerService
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.notification.collection.ListEntry
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.collection.render.NotifShadeEventSource
import javax.inject.Inject
/**
* A coordinator which provides callbacks to a view surfaces for various events relevant to the
* shade, such as when the user removes a notification, or when the shade is emptied.
*/
@SysUISingleton
class ShadeEventCoordinator @Inject internal constructor(
private val mLogger: ShadeEventCoordinatorLogger
) : Coordinator, NotifShadeEventSource {
private var mNotifRemovedByUserCallback: Runnable? = null
private var mShadeEmptiedCallback: Runnable? = null
private var mEntryRemoved = false
private var mEntryRemovedByUser = false
override fun attach(pipeline: NotifPipeline) {
pipeline.addCollectionListener(mNotifCollectionListener)
pipeline.addOnBeforeRenderListListener(this::onBeforeRenderList)
}
private val mNotifCollectionListener = object : NotifCollectionListener {
override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
mEntryRemoved = true
mEntryRemovedByUser =
reason == NotificationListenerService.REASON_CLICK ||
reason == NotificationListenerService.REASON_CANCEL_ALL ||
reason == NotificationListenerService.REASON_CANCEL
}
}
override fun setNotifRemovedByUserCallback(callback: Runnable) {
check(mNotifRemovedByUserCallback == null) { "mNotifRemovedByUserCallback already set" }
mNotifRemovedByUserCallback = callback
}
override fun setShadeEmptiedCallback(callback: Runnable) {
check(mShadeEmptiedCallback == null) { "mShadeEmptiedCallback already set" }
mShadeEmptiedCallback = callback
}
private fun onBeforeRenderList(entries: List<ListEntry>) {
if (mEntryRemoved && entries.isEmpty()) {
mLogger.logShadeEmptied()
mShadeEmptiedCallback?.run()
}
if (mEntryRemoved && mEntryRemovedByUser) {
mLogger.logNotifRemovedByUser()
mNotifRemovedByUserCallback?.run()
}
mEntryRemoved = false
mEntryRemovedByUser = false
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.notification.collection.coordinator
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel
import com.android.systemui.log.dagger.NotificationLog
import javax.inject.Inject
private const val TAG = "ShadeEventCoordinator"
/** Logger for the [ShadeEventCoordinator] */
class ShadeEventCoordinatorLogger @Inject constructor(
@NotificationLog private val buffer: LogBuffer
) {
fun logShadeEmptied() {
buffer.log(TAG, LogLevel.DEBUG, { }, { "Shade emptied" })
}
fun logNotifRemovedByUser() {
buffer.log(TAG, LogLevel.DEBUG, { }, { "Notification removed by user" })
}
}

View File

@@ -0,0 +1,109 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.notification.collection.coordinator
import com.android.internal.widget.MessagingGroup
import com.android.internal.widget.MessagingMessage
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener
import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl
import com.android.systemui.statusbar.notification.collection.NotifPipeline
import com.android.systemui.statusbar.notification.row.NotificationGutsManager
import com.android.systemui.statusbar.policy.ConfigurationController
import javax.inject.Inject
/**
* A coordinator which ensures that notifications within the new pipeline are correctly inflated
* for the current uiMode and screen properties; additionally deferring those changes when a user
* change is in progress until that process has completed.
*/
@SysUISingleton
class ViewConfigCoordinator @Inject internal constructor(
configurationController: ConfigurationController,
lockscreenUserManager: NotificationLockscreenUserManagerImpl,
featureFlags: FeatureFlags,
private val mGutsManager: NotificationGutsManager,
private val mKeyguardUpdateMonitor: KeyguardUpdateMonitor
) : Coordinator, UserChangedListener, ConfigurationController.ConfigurationListener {
private var mReinflateNotificationsOnUserSwitched = false
private var mDispatchUiModeChangeOnUserSwitched = false
private var mPipeline: NotifPipeline? = null
init {
if (featureFlags.isNewNotifPipelineRenderingEnabled) {
lockscreenUserManager.addUserChangedListener(this)
configurationController.addCallback(this)
}
}
override fun attach(pipeline: NotifPipeline) {
mPipeline = pipeline
}
override fun onDensityOrFontScaleChanged() {
MessagingMessage.dropCache()
MessagingGroup.dropCache()
if (!mKeyguardUpdateMonitor.isSwitchingUser) {
updateNotificationsOnDensityOrFontScaleChanged()
} else {
mReinflateNotificationsOnUserSwitched = true
}
}
override fun onUiModeChanged() {
if (!mKeyguardUpdateMonitor.isSwitchingUser) {
updateNotificationsOnUiModeChanged()
} else {
mDispatchUiModeChangeOnUserSwitched = true
}
}
override fun onThemeChanged() {
onDensityOrFontScaleChanged()
}
override fun onUserChanged(userId: Int) {
if (mReinflateNotificationsOnUserSwitched) {
updateNotificationsOnDensityOrFontScaleChanged()
mReinflateNotificationsOnUserSwitched = false
}
if (mDispatchUiModeChangeOnUserSwitched) {
updateNotificationsOnUiModeChanged()
mDispatchUiModeChangeOnUserSwitched = false
}
}
private fun updateNotificationsOnUiModeChanged() {
mPipeline?.allNotifs?.forEach { entry ->
val row = entry.row
row?.onUiModeChanged()
}
}
private fun updateNotificationsOnDensityOrFontScaleChanged() {
mPipeline?.allNotifs?.forEach { entry ->
entry.onDensityOrFontScaleChanged()
val exposedGuts = entry.areGutsExposed()
if (exposedGuts) {
mGutsManager.onDensityOrFontScaleChanged(entry)
}
}
}
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.notification.collection.legacy;
import static com.android.systemui.statusbar.phone.StatusBar.SPEW;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import androidx.annotation.NonNull;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
/**
* This is some logic extracted from the
* {@link com.android.systemui.statusbar.phone.StatusBarNotificationPresenter}
* into a class that implements a new-pipeline interface so that the new pipeline can implement it
* correctly.
*
* Specifically, this is the logic which updates notifications when uiMode and screen properties
* change, and which closes the shade when the last notification disappears.
*/
public class LegacyNotificationPresenterExtensions implements NotifShadeEventSource {
private static final String TAG = "LegacyNotifPresenter";
private final NotificationEntryManager mEntryManager;
private boolean mEntryListenerAdded;
private Runnable mShadeEmptiedCallback;
private Runnable mNotifRemovedByUserCallback;
@Inject
public LegacyNotificationPresenterExtensions(NotificationEntryManager entryManager) {
mEntryManager = entryManager;
}
private void ensureEntryListenerAdded() {
if (mEntryListenerAdded) return;
mEntryListenerAdded = true;
mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
@Override
public void onEntryRemoved(
@NotNull NotificationEntry entry,
NotificationVisibility visibility,
boolean removedByUser,
int reason) {
StatusBarNotification old = entry.getSbn();
if (SPEW) {
Log.d(TAG, "removeNotification key=" + entry.getKey()
+ " old=" + old + " reason=" + reason);
}
if (old != null && !mEntryManager.hasActiveNotifications()) {
if (mShadeEmptiedCallback != null) mShadeEmptiedCallback.run();
}
if (removedByUser) {
if (mNotifRemovedByUserCallback != null) mNotifRemovedByUserCallback.run();
}
}
});
}
@Override
public void setNotifRemovedByUserCallback(@NonNull Runnable callback) {
if (mNotifRemovedByUserCallback != null) {
throw new IllegalStateException("mNotifRemovedByUserCallback already set");
}
mNotifRemovedByUserCallback = callback;
ensureEntryListenerAdded();
}
@Override
public void setShadeEmptiedCallback(@NonNull Runnable callback) {
if (mShadeEmptiedCallback != null) {
throw new IllegalStateException("mShadeEmptiedCallback already set");
}
mShadeEmptiedCallback = callback;
ensureEntryListenerAdded();
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.notification.collection.render
/**
* This is an object which provides callbacks for certain important events related to the
* notification shade, such as notifications being removed by the user, or the shade becoming empty.
*/
interface NotifShadeEventSource {
/**
* Registers a callback to be invoked when the last notification has been removed from
* the shade for any reason
*/
fun setShadeEmptiedCallback(callback: Runnable)
/**
* Registers a callback to be invoked when a notification has been removed from
* the shade by a user action
*/
fun setNotifRemovedByUserCallback(callback: Runnable)
}

View File

@@ -45,10 +45,12 @@ import com.android.systemui.statusbar.notification.NotificationEntryManagerLogge
import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl; import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.coordinator.ShadeEventCoordinator;
import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator; import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater; import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
import com.android.systemui.statusbar.notification.collection.inflation.OnUserInteractionCallbackImpl; import com.android.systemui.statusbar.notification.collection.inflation.OnUserInteractionCallbackImpl;
import com.android.systemui.statusbar.notification.collection.legacy.LegacyNotificationPresenterExtensions;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.legacy.OnUserInteractionCallbackImplLegacy; import com.android.systemui.statusbar.notification.collection.legacy.OnUserInteractionCallbackImplLegacy;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
@@ -59,6 +61,7 @@ import com.android.systemui.statusbar.notification.collection.render.GroupExpans
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl;
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager; import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import com.android.systemui.statusbar.notification.init.NotificationsController; import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.init.NotificationsControllerImpl; import com.android.systemui.statusbar.notification.init.NotificationsControllerImpl;
import com.android.systemui.statusbar.notification.init.NotificationsControllerStub; import com.android.systemui.statusbar.notification.init.NotificationsControllerStub;
@@ -270,6 +273,20 @@ public interface NotificationsModule {
return featureFlags.isNewNotifPipelineRenderingEnabled() ? pipeline.get() : entryManager; return featureFlags.isNewNotifPipelineRenderingEnabled() ? pipeline.get() : entryManager;
} }
/**
* Provide the active implementation for presenting notifications.
*/
@Provides
@SysUISingleton
static NotifShadeEventSource provideNotifShadeEventSource(
FeatureFlags featureFlags,
Lazy<ShadeEventCoordinator> shadeEventCoordinatorLazy,
Lazy<LegacyNotificationPresenterExtensions> legacyNotificationPresenterExtensionsLazy) {
return featureFlags.isNewNotifPipelineRenderingEnabled()
? shadeEventCoordinatorLazy.get()
: legacyNotificationPresenterExtensionsLazy.get();
}
/** /**
* Provide a dismissal callback that's triggered when a user manually dismissed a notification * Provide a dismissal callback that's triggered when a user manually dismissed a notification
* from the notification shade or it gets auto-cancelled by click. * from the notification shade or it gets auto-cancelled by click.

View File

@@ -1249,6 +1249,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
@Override @Override
public void onConfigurationChanged(Configuration newConfig) { public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (mMenuRow != null && mMenuRow.getMenuView() != null) { if (mMenuRow != null && mMenuRow.getMenuView() != null) {
mMenuRow.onConfigurationChanged(); mMenuRow.onConfigurationChanged();
} }

View File

@@ -207,6 +207,7 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider; import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import com.android.systemui.statusbar.notification.init.NotificationsController; import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier; import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
@@ -535,6 +536,7 @@ public class StatusBar extends SystemUI implements
private final int[] mAbsPos = new int[2]; private final int[] mAbsPos = new int[2];
private final NotifShadeEventSource mNotifShadeEventSource;
protected final NotificationEntryManager mEntryManager; protected final NotificationEntryManager mEntryManager;
private final NotificationGutsManager mGutsManager; private final NotificationGutsManager mGutsManager;
private final NotificationLogger mNotificationLogger; private final NotificationLogger mNotificationLogger;
@@ -718,6 +720,7 @@ public class StatusBar extends SystemUI implements
FalsingManager falsingManager, FalsingManager falsingManager,
FalsingCollector falsingCollector, FalsingCollector falsingCollector,
BroadcastDispatcher broadcastDispatcher, BroadcastDispatcher broadcastDispatcher,
NotifShadeEventSource notifShadeEventSource,
NotificationEntryManager notificationEntryManager, NotificationEntryManager notificationEntryManager,
NotificationGutsManager notificationGutsManager, NotificationGutsManager notificationGutsManager,
NotificationLogger notificationLogger, NotificationLogger notificationLogger,
@@ -823,6 +826,7 @@ public class StatusBar extends SystemUI implements
mFalsingCollector = falsingCollector; mFalsingCollector = falsingCollector;
mFalsingManager = falsingManager; mFalsingManager = falsingManager;
mBroadcastDispatcher = broadcastDispatcher; mBroadcastDispatcher = broadcastDispatcher;
mNotifShadeEventSource = notifShadeEventSource;
mEntryManager = notificationEntryManager; mEntryManager = notificationEntryManager;
mGutsManager = notificationGutsManager; mGutsManager = notificationGutsManager;
mNotificationLogger = notificationLogger; mNotificationLogger = notificationLogger;
@@ -1506,6 +1510,7 @@ public class StatusBar extends SystemUI implements
mDynamicPrivacyController, mDynamicPrivacyController,
mKeyguardStateController, mKeyguardStateController,
mKeyguardIndicationController, mKeyguardIndicationController,
mFeatureFlags,
this /* statusBar */, this /* statusBar */,
mShadeController, mShadeController,
mLockscreenShadeTransitionController, mLockscreenShadeTransitionController,
@@ -1513,6 +1518,7 @@ public class StatusBar extends SystemUI implements
mViewHierarchyManager, mViewHierarchyManager,
mLockscreenUserManager, mLockscreenUserManager,
mStatusBarStateController, mStatusBarStateController,
mNotifShadeEventSource,
mEntryManager, mEntryManager,
mMediaManager, mMediaManager,
mGutsManager, mGutsManager,

View File

@@ -17,9 +17,7 @@ package com.android.systemui.statusbar.phone;
import static com.android.systemui.statusbar.phone.StatusBar.CLOSE_PANEL_WHEN_EMPTIED; import static com.android.systemui.statusbar.phone.StatusBar.CLOSE_PANEL_WHEN_EMPTIED;
import static com.android.systemui.statusbar.phone.StatusBar.DEBUG; import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
import static com.android.systemui.statusbar.phone.StatusBar.MULTIUSER_DEBUG; import static com.android.systemui.statusbar.phone.StatusBar.MULTIUSER_DEBUG;
import static com.android.systemui.statusbar.phone.StatusBar.SPEW;
import android.annotation.Nullable;
import android.app.KeyguardManager; import android.app.KeyguardManager;
import android.content.Context; import android.content.Context;
import android.os.RemoteException; import android.os.RemoteException;
@@ -36,7 +34,6 @@ import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.MessagingGroup; import com.android.internal.widget.MessagingGroup;
import com.android.internal.widget.MessagingMessage; import com.android.internal.widget.MessagingMessage;
import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitor;
@@ -44,6 +41,7 @@ import com.android.systemui.Dependency;
import com.android.systemui.ForegroundServiceNotificationListener; import com.android.systemui.ForegroundServiceNotificationListener;
import com.android.systemui.InitController; import com.android.systemui.InitController;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue;
@@ -59,10 +57,10 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.AboveShelfObserver; import com.android.systemui.statusbar.notification.AboveShelfObserver;
import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
@@ -88,6 +86,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
private final NotificationViewHierarchyManager mViewHierarchyManager; private final NotificationViewHierarchyManager mViewHierarchyManager;
private final NotificationLockscreenUserManager mLockscreenUserManager; private final NotificationLockscreenUserManager mLockscreenUserManager;
private final SysuiStatusBarStateController mStatusBarStateController; private final SysuiStatusBarStateController mStatusBarStateController;
private final NotifShadeEventSource mNotifShadeEventSource;
private final NotificationEntryManager mEntryManager; private final NotificationEntryManager mEntryManager;
private final NotificationMediaManager mMediaManager; private final NotificationMediaManager mMediaManager;
private final NotificationGutsManager mGutsManager; private final NotificationGutsManager mGutsManager;
@@ -100,6 +99,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
private final DozeScrimController mDozeScrimController; private final DozeScrimController mDozeScrimController;
private final ScrimController mScrimController; private final ScrimController mScrimController;
private final KeyguardIndicationController mKeyguardIndicationController; private final KeyguardIndicationController mKeyguardIndicationController;
private final FeatureFlags mFeatureFlags;
private final StatusBar mStatusBar; private final StatusBar mStatusBar;
private final ShadeController mShadeController; private final ShadeController mShadeController;
private final LockscreenShadeTransitionController mShadeTransitionController; private final LockscreenShadeTransitionController mShadeTransitionController;
@@ -127,6 +127,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
DynamicPrivacyController dynamicPrivacyController, DynamicPrivacyController dynamicPrivacyController,
KeyguardStateController keyguardStateController, KeyguardStateController keyguardStateController,
KeyguardIndicationController keyguardIndicationController, KeyguardIndicationController keyguardIndicationController,
FeatureFlags featureFlags,
StatusBar statusBar, StatusBar statusBar,
ShadeController shadeController, ShadeController shadeController,
LockscreenShadeTransitionController shadeTransitionController, LockscreenShadeTransitionController shadeTransitionController,
@@ -134,6 +135,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
NotificationViewHierarchyManager notificationViewHierarchyManager, NotificationViewHierarchyManager notificationViewHierarchyManager,
NotificationLockscreenUserManager lockscreenUserManager, NotificationLockscreenUserManager lockscreenUserManager,
SysuiStatusBarStateController sysuiStatusBarStateController, SysuiStatusBarStateController sysuiStatusBarStateController,
NotifShadeEventSource notifShadeEventSource,
NotificationEntryManager notificationEntryManager, NotificationEntryManager notificationEntryManager,
NotificationMediaManager notificationMediaManager, NotificationMediaManager notificationMediaManager,
NotificationGutsManager notificationGutsManager, NotificationGutsManager notificationGutsManager,
@@ -148,6 +150,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
mHeadsUpManager = headsUp; mHeadsUpManager = headsUp;
mDynamicPrivacyController = dynamicPrivacyController; mDynamicPrivacyController = dynamicPrivacyController;
mKeyguardIndicationController = keyguardIndicationController; mKeyguardIndicationController = keyguardIndicationController;
mFeatureFlags = featureFlags;
// TODO: use KeyguardStateController#isOccluded to remove this dependency // TODO: use KeyguardStateController#isOccluded to remove this dependency
mStatusBar = statusBar; mStatusBar = statusBar;
mShadeController = shadeController; mShadeController = shadeController;
@@ -156,6 +159,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
mViewHierarchyManager = notificationViewHierarchyManager; mViewHierarchyManager = notificationViewHierarchyManager;
mLockscreenUserManager = lockscreenUserManager; mLockscreenUserManager = lockscreenUserManager;
mStatusBarStateController = sysuiStatusBarStateController; mStatusBarStateController = sysuiStatusBarStateController;
mNotifShadeEventSource = notifShadeEventSource;
mEntryManager = notificationEntryManager; mEntryManager = notificationEntryManager;
mMediaManager = notificationMediaManager; mMediaManager = notificationMediaManager;
mGutsManager = notificationGutsManager; mGutsManager = notificationGutsManager;
@@ -186,30 +190,18 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
mNotificationPanel.createRemoteInputDelegate()); mNotificationPanel.createRemoteInputDelegate());
initController.addPostInitTask(() -> { initController.addPostInitTask(() -> {
NotificationEntryListener notificationEntryListener = new NotificationEntryListener() {
@Override
public void onEntryRemoved(
@Nullable NotificationEntry entry,
NotificationVisibility visibility,
boolean removedByUser,
int reason) {
StatusBarNotificationPresenter.this.onNotificationRemoved(
entry.getKey(), entry.getSbn(), reason);
if (removedByUser) {
maybeEndAmbientPulse();
}
}
};
mKeyguardIndicationController.init(); mKeyguardIndicationController.init();
mViewHierarchyManager.setUpWithPresenter(this, mViewHierarchyManager.setUpWithPresenter(this,
stackScrollerController.getNotificationListContainer()); stackScrollerController.getNotificationListContainer());
mNotifShadeEventSource.setShadeEmptiedCallback(this::maybeClosePanelForShadeEmptied);
mNotifShadeEventSource.setNotifRemovedByUserCallback(this::maybeEndAmbientPulse);
if (!mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
mEntryManager.setUpWithPresenter(this); mEntryManager.setUpWithPresenter(this);
mEntryManager.addNotificationEntryListener(notificationEntryListener);
mEntryManager.addNotificationLifetimeExtender(mHeadsUpManager); mEntryManager.addNotificationLifetimeExtender(mHeadsUpManager);
mEntryManager.addNotificationLifetimeExtender(mGutsManager); mEntryManager.addNotificationLifetimeExtender(mGutsManager);
mEntryManager.addNotificationLifetimeExtenders( mEntryManager.addNotificationLifetimeExtenders(
remoteInputManager.getLifetimeExtenders()); remoteInputManager.getLifetimeExtenders());
}
notificationInterruptStateProvider.addSuppressor(mInterruptSuppressor); notificationInterruptStateProvider.addSuppressor(mInterruptSuppressor);
mLockscreenUserManager.setUpWithPresenter(this); mLockscreenUserManager.setUpWithPresenter(this);
mMediaManager.setUpWithPresenter(this); mMediaManager.setUpWithPresenter(this);
@@ -226,8 +218,21 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
configurationController.addCallback(this); configurationController.addCallback(this);
} }
/** Called when the shade has been emptied to attempt to close the shade */
private void maybeClosePanelForShadeEmptied() {
if (CLOSE_PANEL_WHEN_EMPTIED
&& !mNotificationPanel.isTracking()
&& !mNotificationPanel.isQsExpanded()
&& mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED
&& !isCollapsing()) {
mStatusBarStateController.setState(StatusBarState.KEYGUARD);
}
}
@Override @Override
public void onDensityOrFontScaleChanged() { public void onDensityOrFontScaleChanged() {
// TODO(b/145659174): Remove legacy pipeline code
if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) return;
MessagingMessage.dropCache(); MessagingMessage.dropCache();
MessagingGroup.dropCache(); MessagingGroup.dropCache();
if (!mKeyguardUpdateMonitor.isSwitchingUser()) { if (!mKeyguardUpdateMonitor.isSwitchingUser()) {
@@ -239,8 +244,10 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
@Override @Override
public void onUiModeChanged() { public void onUiModeChanged() {
// TODO(b/145659174): Remove legacy pipeline code
if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) return;
if (!mKeyguardUpdateMonitor.isSwitchingUser()) { if (!mKeyguardUpdateMonitor.isSwitchingUser()) {
updateNotificationOnUiModeChanged(); updateNotificationsOnUiModeChanged();
} else { } else {
mDispatchUiModeChangeOnUserSwitched = true; mDispatchUiModeChangeOnUserSwitched = true;
} }
@@ -251,7 +258,9 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
onDensityOrFontScaleChanged(); onDensityOrFontScaleChanged();
} }
private void updateNotificationOnUiModeChanged() { private void updateNotificationsOnUiModeChanged() {
// TODO(b/145659174): Remove legacy pipeline code
if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) return;
List<NotificationEntry> userNotifications = List<NotificationEntry> userNotifications =
mEntryManager.getActiveNotificationsForCurrentUser(); mEntryManager.getActiveNotificationsForCurrentUser();
for (int i = 0; i < userNotifications.size(); i++) { for (int i = 0; i < userNotifications.size(); i++) {
@@ -264,6 +273,8 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
} }
private void updateNotificationsOnDensityOrFontScaleChanged() { private void updateNotificationsOnDensityOrFontScaleChanged() {
// TODO(b/145659174): Remove legacy pipeline code
if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) return;
List<NotificationEntry> userNotifications = List<NotificationEntry> userNotifications =
mEntryManager.getActiveNotificationsForCurrentUser(); mEntryManager.getActiveNotificationsForCurrentUser();
for (int i = 0; i < userNotifications.size(); i++) { for (int i = 0; i < userNotifications.size(); i++) {
@@ -276,6 +287,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
} }
} }
@Override @Override
public boolean isCollapsing() { public boolean isCollapsing() {
return mNotificationPanel.isCollapsing() return mNotificationPanel.isCollapsing()
@@ -308,21 +320,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
mNotificationPanel.updateNotificationViews(reason); mNotificationPanel.updateNotificationViews(reason);
} }
private void onNotificationRemoved(String key, StatusBarNotification old, int reason) {
if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
if (old != null && CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
&& !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()
&& mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED
&& !isCollapsing()) {
mStatusBarStateController.setState(StatusBarState.KEYGUARD);
}
}
public boolean hasActiveNotifications() {
return mEntryManager.hasActiveNotifications();
}
@Override @Override
public void onUserSwitched(int newUserId) { public void onUserSwitched(int newUserId) {
// Begin old BaseStatusBar.userSwitched // Begin old BaseStatusBar.userSwitched
@@ -335,7 +332,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
mReinflateNotificationsOnUserSwitched = false; mReinflateNotificationsOnUserSwitched = false;
} }
if (mDispatchUiModeChangeOnUserSwitched) { if (mDispatchUiModeChangeOnUserSwitched) {
updateNotificationOnUiModeChanged(); updateNotificationsOnUiModeChanged();
mDispatchUiModeChangeOnUserSwitched = false; mDispatchUiModeChangeOnUserSwitched = false;
} }
updateNotificationViews("user switched"); updateNotificationViews("user switched");

View File

@@ -68,6 +68,7 @@ import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import com.android.systemui.statusbar.notification.init.NotificationsController; import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier; import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
@@ -157,6 +158,7 @@ public interface StatusBarPhoneModule {
FalsingManager falsingManager, FalsingManager falsingManager,
FalsingCollector falsingCollector, FalsingCollector falsingCollector,
BroadcastDispatcher broadcastDispatcher, BroadcastDispatcher broadcastDispatcher,
NotifShadeEventSource notifShadeEventSource,
NotificationEntryManager notificationEntryManager, NotificationEntryManager notificationEntryManager,
NotificationGutsManager notificationGutsManager, NotificationGutsManager notificationGutsManager,
NotificationLogger notificationLogger, NotificationLogger notificationLogger,
@@ -260,6 +262,7 @@ public interface StatusBarPhoneModule {
falsingManager, falsingManager,
falsingCollector, falsingCollector,
broadcastDispatcher, broadcastDispatcher,
notifShadeEventSource,
notificationEntryManager, notificationEntryManager,
notificationGutsManager, notificationGutsManager,
notificationLogger, notificationLogger,

View File

@@ -0,0 +1,106 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.notification.collection.coordinator
import android.service.notification.NotificationListenerService.REASON_APP_CANCEL
import android.service.notification.NotificationListenerService.REASON_CANCEL
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.collection.NotifPipeline
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import com.android.systemui.util.mockito.argumentCaptor
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations.initMocks
@SmallTest
@RunWith(AndroidTestingRunner::class)
@RunWithLooper
class ShadeEventCoordinatorTest : SysuiTestCase() {
private lateinit var coordinator: ShadeEventCoordinator
private lateinit var notifCollectionListener: NotifCollectionListener
private lateinit var onBeforeRenderListListener: OnBeforeRenderListListener
private lateinit var entry1: NotificationEntry
private lateinit var entry2: NotificationEntry
@Mock private lateinit var pipeline: NotifPipeline
@Mock private lateinit var logger: ShadeEventCoordinatorLogger
@Mock private lateinit var notifRemovedByUserCallback: Runnable
@Mock private lateinit var shadeEmptiedCallback: Runnable
@Before
fun setUp() {
initMocks(this)
coordinator = ShadeEventCoordinator(logger)
coordinator.attach(pipeline)
notifCollectionListener = argumentCaptor<NotifCollectionListener>().let {
verify(pipeline).addCollectionListener(it.capture())
it.value!!
}
onBeforeRenderListListener = argumentCaptor<OnBeforeRenderListListener>().let {
verify(pipeline).addOnBeforeRenderListListener(it.capture())
it.value!!
}
coordinator.setNotifRemovedByUserCallback(notifRemovedByUserCallback)
coordinator.setShadeEmptiedCallback(shadeEmptiedCallback)
entry1 = NotificationEntryBuilder().setId(1).build()
entry2 = NotificationEntryBuilder().setId(2).build()
}
@Test
fun testUserCancelLastNotification() {
notifCollectionListener.onEntryRemoved(entry1, REASON_CANCEL)
verify(shadeEmptiedCallback, never()).run()
verify(notifRemovedByUserCallback, never()).run()
onBeforeRenderListListener.onBeforeRenderList(listOf())
verify(shadeEmptiedCallback).run()
verify(notifRemovedByUserCallback).run()
}
@Test
fun testAppCancelLastNotification() {
notifCollectionListener.onEntryRemoved(entry1, REASON_APP_CANCEL)
onBeforeRenderListListener.onBeforeRenderList(listOf())
verify(shadeEmptiedCallback).run()
verify(notifRemovedByUserCallback, never()).run()
}
@Test
fun testUserCancelOneOfTwoNotifications() {
notifCollectionListener.onEntryRemoved(entry1, REASON_CANCEL)
onBeforeRenderListListener.onBeforeRenderList(listOf(entry2))
verify(shadeEmptiedCallback, never()).run()
verify(notifRemovedByUserCallback).run()
}
@Test
fun testAppCancelOneOfTwoNotifications() {
notifCollectionListener.onEntryRemoved(entry1, REASON_APP_CANCEL)
onBeforeRenderListListener.onBeforeRenderList(listOf(entry2))
verify(shadeEmptiedCallback, never()).run()
verify(notifRemovedByUserCallback, never()).run()
}
}

View File

@@ -37,6 +37,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.ForegroundServiceNotificationListener; import com.android.systemui.ForegroundServiceNotificationListener;
import com.android.systemui.InitController; import com.android.systemui.InitController;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -51,6 +52,7 @@ import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
@@ -109,12 +111,15 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
mock(DozeScrimController.class), mock(ScrimController.class), mock(DozeScrimController.class), mock(ScrimController.class),
mock(NotificationShadeWindowController.class), mock(DynamicPrivacyController.class), mock(NotificationShadeWindowController.class), mock(DynamicPrivacyController.class),
mock(KeyguardStateController.class), mock(KeyguardStateController.class),
mock(KeyguardIndicationController.class), mStatusBar, mock(KeyguardIndicationController.class),
mock(FeatureFlags.class),
mStatusBar,
mock(ShadeControllerImpl.class), mock(LockscreenShadeTransitionController.class), mock(ShadeControllerImpl.class), mock(LockscreenShadeTransitionController.class),
mCommandQueue, mCommandQueue,
mock(NotificationViewHierarchyManager.class), mock(NotificationViewHierarchyManager.class),
mock(NotificationLockscreenUserManager.class), mock(NotificationLockscreenUserManager.class),
mock(SysuiStatusBarStateController.class), mock(SysuiStatusBarStateController.class),
mock(NotifShadeEventSource.class),
mock(NotificationEntryManager.class), mock(NotificationEntryManager.class),
mock(NotificationMediaManager.class), mock(NotificationMediaManager.class),
mock(NotificationGutsManager.class), mock(NotificationGutsManager.class),

View File

@@ -121,6 +121,7 @@ import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import com.android.systemui.statusbar.notification.init.NotificationsController; import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier; import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl;
@@ -210,6 +211,7 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private NotificationShadeWindowView mNotificationShadeWindowView; @Mock private NotificationShadeWindowView mNotificationShadeWindowView;
@Mock private BroadcastDispatcher mBroadcastDispatcher; @Mock private BroadcastDispatcher mBroadcastDispatcher;
@Mock private AssistManager mAssistManager; @Mock private AssistManager mAssistManager;
@Mock private NotifShadeEventSource mNotifShadeEventSource;
@Mock private NotificationEntryManager mNotificationEntryManager; @Mock private NotificationEntryManager mNotificationEntryManager;
@Mock private NotificationGutsManager mNotificationGutsManager; @Mock private NotificationGutsManager mNotificationGutsManager;
@Mock private NotificationMediaManager mNotificationMediaManager; @Mock private NotificationMediaManager mNotificationMediaManager;
@@ -377,6 +379,7 @@ public class StatusBarTest extends SysuiTestCase {
new FalsingManagerFake(), new FalsingManagerFake(),
new FalsingCollectorFake(), new FalsingCollectorFake(),
mBroadcastDispatcher, mBroadcastDispatcher,
mNotifShadeEventSource,
mNotificationEntryManager, mNotificationEntryManager,
mNotificationGutsManager, mNotificationGutsManager,
notificationLogger, notificationLogger,