Merge changes from topic "b204127880_pipeline_backport_2" into sc-v2-dev
* changes: New Pipeline: Disable legacy dynamic privacy listener Fix Coordinators failing to build with gradle build in sysui-studio Enforce Coordinator encapsulation w/ Dagger Add sensitive content redaction to notif pipeline
This commit is contained in:
@@ -18,6 +18,8 @@ package com.android.systemui.flags;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.FeatureFlagUtils;
|
import android.util.FeatureFlagUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
@@ -86,6 +88,22 @@ public class FeatureFlags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void assertLegacyPipelineEnabled() {
|
||||||
|
if (isNewNotifPipelineRenderingEnabled()) {
|
||||||
|
throw new IllegalStateException("Old pipeline code running w/ new pipeline enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkLegacyPipelineEnabled() {
|
||||||
|
if (!isNewNotifPipelineRenderingEnabled()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Log.d("NotifPipeline", "Old pipeline code running w/ new pipeline enabled",
|
||||||
|
new Exception());
|
||||||
|
Toast.makeText(mContext, "Old pipeline code running!", Toast.LENGTH_SHORT).show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isNewNotifPipelineEnabled() {
|
public boolean isNewNotifPipelineEnabled() {
|
||||||
return isEnabled(Flags.NEW_NOTIFICATION_PIPELINE);
|
return isEnabled(Flags.NEW_NOTIFICATION_PIPELINE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.view.ViewGroup;
|
|||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
|
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.dagger.StatusBarModule;
|
import com.android.systemui.statusbar.dagger.StatusBarModule;
|
||||||
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
|
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
|
||||||
@@ -72,6 +73,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
|
|||||||
|
|
||||||
// Dependencies:
|
// Dependencies:
|
||||||
private final DynamicChildBindController mDynamicChildBindController;
|
private final DynamicChildBindController mDynamicChildBindController;
|
||||||
|
private final FeatureFlags mFeatureFlags;
|
||||||
protected final NotificationLockscreenUserManager mLockscreenUserManager;
|
protected final NotificationLockscreenUserManager mLockscreenUserManager;
|
||||||
protected final NotificationGroupManagerLegacy mGroupManager;
|
protected final NotificationGroupManagerLegacy mGroupManager;
|
||||||
protected final VisualStabilityManager mVisualStabilityManager;
|
protected final VisualStabilityManager mVisualStabilityManager;
|
||||||
@@ -107,6 +109,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
|
|||||||
public NotificationViewHierarchyManager(
|
public NotificationViewHierarchyManager(
|
||||||
Context context,
|
Context context,
|
||||||
@Main Handler mainHandler,
|
@Main Handler mainHandler,
|
||||||
|
FeatureFlags featureFlags,
|
||||||
NotificationLockscreenUserManager notificationLockscreenUserManager,
|
NotificationLockscreenUserManager notificationLockscreenUserManager,
|
||||||
NotificationGroupManagerLegacy groupManager,
|
NotificationGroupManagerLegacy groupManager,
|
||||||
VisualStabilityManager visualStabilityManager,
|
VisualStabilityManager visualStabilityManager,
|
||||||
@@ -121,6 +124,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
|
|||||||
AssistantFeedbackController assistantFeedbackController) {
|
AssistantFeedbackController assistantFeedbackController) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mHandler = mainHandler;
|
mHandler = mainHandler;
|
||||||
|
mFeatureFlags = featureFlags;
|
||||||
mLockscreenUserManager = notificationLockscreenUserManager;
|
mLockscreenUserManager = notificationLockscreenUserManager;
|
||||||
mBypassController = bypassController;
|
mBypassController = bypassController;
|
||||||
mGroupManager = groupManager;
|
mGroupManager = groupManager;
|
||||||
@@ -142,7 +146,9 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
|
|||||||
NotificationListContainer listContainer) {
|
NotificationListContainer listContainer) {
|
||||||
mPresenter = presenter;
|
mPresenter = presenter;
|
||||||
mListContainer = listContainer;
|
mListContainer = listContainer;
|
||||||
mDynamicPrivacyController.addListener(this);
|
if (!mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
|
||||||
|
mDynamicPrivacyController.addListener(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -151,6 +157,10 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
|
|||||||
//TODO: Rewrite this to focus on Entries, or some other data object instead of views
|
//TODO: Rewrite this to focus on Entries, or some other data object instead of views
|
||||||
public void updateNotificationViews() {
|
public void updateNotificationViews() {
|
||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
|
if (!mFeatureFlags.checkLegacyPipelineEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
beginUpdate();
|
beginUpdate();
|
||||||
|
|
||||||
List<NotificationEntry> activeNotifications = mEntryManager.getVisibleNotifications();
|
List<NotificationEntry> activeNotifications = mEntryManager.getVisibleNotifications();
|
||||||
@@ -425,6 +435,10 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
|
|||||||
*/
|
*/
|
||||||
public void updateRowStates() {
|
public void updateRowStates() {
|
||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
|
if (!mFeatureFlags.checkLegacyPipelineEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
beginUpdate();
|
beginUpdate();
|
||||||
updateRowStatesInternal();
|
updateRowStatesInternal();
|
||||||
endUpdate();
|
endUpdate();
|
||||||
@@ -510,6 +524,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDynamicPrivacyChanged() {
|
public void onDynamicPrivacyChanged() {
|
||||||
|
mFeatureFlags.assertLegacyPipelineEnabled();
|
||||||
if (mPerformingUpdate) {
|
if (mPerformingUpdate) {
|
||||||
Log.w(TAG, "onDynamicPrivacyChanged made a re-entrant call");
|
Log.w(TAG, "onDynamicPrivacyChanged made a re-entrant call");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ public interface StatusBarDependenciesModule {
|
|||||||
static NotificationViewHierarchyManager provideNotificationViewHierarchyManager(
|
static NotificationViewHierarchyManager provideNotificationViewHierarchyManager(
|
||||||
Context context,
|
Context context,
|
||||||
@Main Handler mainHandler,
|
@Main Handler mainHandler,
|
||||||
|
FeatureFlags featureFlags,
|
||||||
NotificationLockscreenUserManager notificationLockscreenUserManager,
|
NotificationLockscreenUserManager notificationLockscreenUserManager,
|
||||||
NotificationGroupManagerLegacy groupManager,
|
NotificationGroupManagerLegacy groupManager,
|
||||||
VisualStabilityManager visualStabilityManager,
|
VisualStabilityManager visualStabilityManager,
|
||||||
@@ -199,6 +200,7 @@ public interface StatusBarDependenciesModule {
|
|||||||
return new NotificationViewHierarchyManager(
|
return new NotificationViewHierarchyManager(
|
||||||
context,
|
context,
|
||||||
mainHandler,
|
mainHandler,
|
||||||
|
featureFlags,
|
||||||
notificationLockscreenUserManager,
|
notificationLockscreenUserManager,
|
||||||
groupManager,
|
groupManager,
|
||||||
visualStabilityManager,
|
visualStabilityManager,
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.OnBefo
|
|||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
|
||||||
@@ -216,6 +217,11 @@ public class NotifPipeline implements CommonNotifCollection {
|
|||||||
mShadeListBuilder.addOnBeforeRenderListListener(listener);
|
mShadeListBuilder.addOnBeforeRenderListListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Registers an invalidator that can be used to invalidate the entire notif list. */
|
||||||
|
public void addPreRenderInvalidator(Invalidator invalidator) {
|
||||||
|
mShadeListBuilder.addPreRenderInvalidator(invalidator);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a read-only view in to the current shade list, i.e. the list of notifications that
|
* Returns a read-only view in to the current shade list, i.e. the list of notifications that
|
||||||
* are currently present in the shade. If this method is called during pipeline execution it
|
* are currently present in the shade. If this method is called during pipeline execution it
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.OnBefo
|
|||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.ShadeListBuilderLogger;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.ShadeListBuilderLogger;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
|
||||||
@@ -174,6 +175,13 @@ public class ShadeListBuilder implements Dumpable {
|
|||||||
mOnBeforeRenderListListeners.add(listener);
|
mOnBeforeRenderListListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addPreRenderInvalidator(Invalidator invalidator) {
|
||||||
|
Assert.isMainThread();
|
||||||
|
|
||||||
|
mPipelineState.requireState(STATE_IDLE);
|
||||||
|
invalidator.setInvalidationListener(this::onPreRenderInvalidated);
|
||||||
|
}
|
||||||
|
|
||||||
void addPreGroupFilter(NotifFilter filter) {
|
void addPreGroupFilter(NotifFilter filter) {
|
||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
mPipelineState.requireState(STATE_IDLE);
|
mPipelineState.requireState(STATE_IDLE);
|
||||||
@@ -256,6 +264,14 @@ public class ShadeListBuilder implements Dumpable {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private void onPreRenderInvalidated(Invalidator invalidator) {
|
||||||
|
Assert.isMainThread();
|
||||||
|
|
||||||
|
mLogger.logPreRenderInvalidated(invalidator.getName(), mPipelineState.getState());
|
||||||
|
|
||||||
|
rebuildListIfBefore(STATE_FINALIZING);
|
||||||
|
}
|
||||||
|
|
||||||
private void onPreGroupFilterInvalidated(NotifFilter filter) {
|
private void onPreGroupFilterInvalidated(NotifFilter filter) {
|
||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
|
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ import android.service.notification.StatusBarNotification;
|
|||||||
|
|
||||||
import com.android.systemui.ForegroundServiceController;
|
import com.android.systemui.ForegroundServiceController;
|
||||||
import com.android.systemui.appops.AppOpsController;
|
import com.android.systemui.appops.AppOpsController;
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
import com.android.systemui.statusbar.notification.collection.ListEntry;
|
import com.android.systemui.statusbar.notification.collection.ListEntry;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt;
|
import com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt;
|
||||||
@@ -48,7 +48,7 @@ import javax.inject.Inject;
|
|||||||
* frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener
|
* frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener
|
||||||
* frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender
|
* frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender
|
||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@CoordinatorScope
|
||||||
public class AppOpsCoordinator implements Coordinator {
|
public class AppOpsCoordinator implements Coordinator {
|
||||||
private static final String TAG = "AppOpsCoordinator";
|
private static final String TAG = "AppOpsCoordinator";
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.notification.collection.coordinator;
|
package com.android.systemui.statusbar.notification.collection.coordinator;
|
||||||
|
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
|
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
|
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
|
||||||
@@ -53,7 +53,7 @@ import javax.inject.Inject;
|
|||||||
* respond to app-cancellations (ie: remove the bubble if the app cancels the notification).
|
* respond to app-cancellations (ie: remove the bubble if the app cancels the notification).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@CoordinatorScope
|
||||||
public class BubbleCoordinator implements Coordinator {
|
public class BubbleCoordinator implements Coordinator {
|
||||||
private static final String TAG = "BubbleCoordinator";
|
private static final String TAG = "BubbleCoordinator";
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.notification.collection.coordinator
|
package com.android.systemui.statusbar.notification.collection.coordinator
|
||||||
|
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
|
||||||
import com.android.systemui.statusbar.notification.collection.ListEntry
|
import com.android.systemui.statusbar.notification.collection.ListEntry
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NodeController
|
import com.android.systemui.statusbar.notification.collection.render.NodeController
|
||||||
@@ -34,7 +34,7 @@ import javax.inject.Inject
|
|||||||
* - Elevates important conversation notifications
|
* - Elevates important conversation notifications
|
||||||
* - Puts conversations into its own people section. @see [NotifCoordinators] for section ordering.
|
* - Puts conversations into its own people section. @see [NotifCoordinators] for section ordering.
|
||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@CoordinatorScope
|
||||||
class ConversationCoordinator @Inject constructor(
|
class ConversationCoordinator @Inject constructor(
|
||||||
private val peopleNotificationIdentifier: PeopleNotificationIdentifier,
|
private val peopleNotificationIdentifier: PeopleNotificationIdentifier,
|
||||||
@PeopleHeader peopleHeaderController: NodeController
|
@PeopleHeader peopleHeaderController: NodeController
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ import android.content.pm.PackageManager;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.service.notification.StatusBarNotification;
|
import android.service.notification.StatusBarNotification;
|
||||||
|
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ import javax.inject.Inject;
|
|||||||
* Special notifications with extra permissions and tags won't be filtered out even when the
|
* Special notifications with extra permissions and tags won't be filtered out even when the
|
||||||
* device is unprovisioned.
|
* device is unprovisioned.
|
||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@CoordinatorScope
|
||||||
public class DeviceProvisionedCoordinator implements Coordinator {
|
public class DeviceProvisionedCoordinator implements Coordinator {
|
||||||
private static final String TAG = "DeviceProvisionedCoordinator";
|
private static final String TAG = "DeviceProvisionedCoordinator";
|
||||||
|
|
||||||
|
|||||||
@@ -17,17 +17,17 @@ package com.android.systemui.statusbar.notification.collection.coordinator
|
|||||||
|
|
||||||
import android.util.ArraySet
|
import android.util.ArraySet
|
||||||
import com.android.systemui.Dumpable
|
import com.android.systemui.Dumpable
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
|
||||||
import com.android.systemui.dump.DumpManager
|
import com.android.systemui.dump.DumpManager
|
||||||
import com.android.systemui.statusbar.notification.collection.ListEntry
|
import com.android.systemui.statusbar.notification.collection.ListEntry
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender
|
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender.OnEndLifetimeExtensionCallback
|
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender.OnEndLifetimeExtensionCallback
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationGuts
|
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationGutsManager
|
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewListener
|
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewListener
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager
|
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager
|
||||||
|
import com.android.systemui.statusbar.notification.row.NotificationGuts
|
||||||
|
import com.android.systemui.statusbar.notification.row.NotificationGutsManager
|
||||||
import java.io.FileDescriptor
|
import java.io.FileDescriptor
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -38,7 +38,7 @@ private const val TAG = "GutsCoordinator"
|
|||||||
* Coordinates the guts displayed by the [NotificationGutsManager] with the pipeline.
|
* Coordinates the guts displayed by the [NotificationGutsManager] with the pipeline.
|
||||||
* Specifically, this just adds the lifetime extension necessary to keep guts from disappearing.
|
* Specifically, this just adds the lifetime extension necessary to keep guts from disappearing.
|
||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@CoordinatorScope
|
||||||
class GutsCoordinator @Inject constructor(
|
class GutsCoordinator @Inject constructor(
|
||||||
private val notifGutsViewManager: NotifGutsViewManager,
|
private val notifGutsViewManager: NotifGutsViewManager,
|
||||||
private val logger: GutsCoordinatorLogger,
|
private val logger: GutsCoordinatorLogger,
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ import static com.android.systemui.statusbar.notification.interruption.HeadsUpCo
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
|
||||||
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
||||||
import com.android.systemui.statusbar.notification.collection.ListEntry;
|
import com.android.systemui.statusbar.notification.collection.ListEntry;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
||||||
@@ -57,7 +57,7 @@ import javax.inject.Inject;
|
|||||||
*
|
*
|
||||||
* Note: The inflation callback in {@link PreparationCoordinator} handles showing HUNs.
|
* Note: The inflation callback in {@link PreparationCoordinator} handles showing HUNs.
|
||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@CoordinatorScope
|
||||||
public class HeadsUpCoordinator implements Coordinator {
|
public class HeadsUpCoordinator implements Coordinator {
|
||||||
private static final String TAG = "HeadsUpCoordinator";
|
private static final String TAG = "HeadsUpCoordinator";
|
||||||
|
|
||||||
|
|||||||
@@ -20,13 +20,21 @@ import static com.android.systemui.statusbar.notification.collection.Notificatio
|
|||||||
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters out notifications that have been dismissed locally (by the user) but that system server
|
* Filters out notifications that have been dismissed locally (by the user) but that system server
|
||||||
* hasn't yet confirmed the removal of.
|
* hasn't yet confirmed the removal of.
|
||||||
*/
|
*/
|
||||||
|
@CoordinatorScope
|
||||||
public class HideLocallyDismissedNotifsCoordinator implements Coordinator {
|
public class HideLocallyDismissedNotifsCoordinator implements Coordinator {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
HideLocallyDismissedNotifsCoordinator() { }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void attach(NotifPipeline pipeline) {
|
public void attach(NotifPipeline pipeline) {
|
||||||
pipeline.addPreGroupFilter(mFilter);
|
pipeline.addPreGroupFilter(mFilter);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
|||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener;
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -37,6 +38,7 @@ import javax.inject.Inject;
|
|||||||
* TODO: The NotificationLockscreenUserManager currently maintains the list of active user profiles.
|
* TODO: The NotificationLockscreenUserManager currently maintains the list of active user profiles.
|
||||||
* We should spin that off into a standalone section at some point.
|
* We should spin that off into a standalone section at some point.
|
||||||
*/
|
*/
|
||||||
|
@CoordinatorScope
|
||||||
public class HideNotifsForOtherUsersCoordinator implements Coordinator {
|
public class HideNotifsForOtherUsersCoordinator implements Coordinator {
|
||||||
private final NotificationLockscreenUserManager mLockscreenUserManager;
|
private final NotificationLockscreenUserManager mLockscreenUserManager;
|
||||||
private final SharedCoordinatorLogger mLogger;
|
private final SharedCoordinatorLogger mLogger;
|
||||||
|
|||||||
@@ -34,13 +34,13 @@ import androidx.annotation.MainThread;
|
|||||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
||||||
import com.android.systemui.statusbar.notification.collection.GroupEntry;
|
import com.android.systemui.statusbar.notification.collection.GroupEntry;
|
||||||
import com.android.systemui.statusbar.notification.collection.ListEntry;
|
import com.android.systemui.statusbar.notification.collection.ListEntry;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
@@ -50,7 +50,7 @@ import javax.inject.Inject;
|
|||||||
/**
|
/**
|
||||||
* Filters low priority and privacy-sensitive notifications from the lockscreen.
|
* Filters low priority and privacy-sensitive notifications from the lockscreen.
|
||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@CoordinatorScope
|
||||||
public class KeyguardCoordinator implements Coordinator {
|
public class KeyguardCoordinator implements Coordinator {
|
||||||
private static final String TAG = "KeyguardCoordinator";
|
private static final String TAG = "KeyguardCoordinator";
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import static com.android.systemui.media.MediaDataManagerKt.isMediaNotification;
|
|||||||
import com.android.systemui.media.MediaFeatureFlag;
|
import com.android.systemui.media.MediaFeatureFlag;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -28,6 +29,7 @@ import javax.inject.Inject;
|
|||||||
/**
|
/**
|
||||||
* Coordinates hiding (filtering) of media notifications.
|
* Coordinates hiding (filtering) of media notifications.
|
||||||
*/
|
*/
|
||||||
|
@CoordinatorScope
|
||||||
public class MediaCoordinator implements Coordinator {
|
public class MediaCoordinator implements Coordinator {
|
||||||
private static final String TAG = "MediaCoordinator";
|
private static final String TAG = "MediaCoordinator";
|
||||||
|
|
||||||
|
|||||||
@@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.systemui.statusbar.notification.collection.coordinator;
|
|
||||||
|
|
||||||
import com.android.systemui.Dumpable;
|
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
|
||||||
import com.android.systemui.dump.DumpManager;
|
|
||||||
import com.android.systemui.flags.FeatureFlags;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
|
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the attachment of {@link Coordinator}s to the {@link NotifPipeline} so that the
|
|
||||||
* Coordinators can register their respective callbacks.
|
|
||||||
*/
|
|
||||||
@SysUISingleton
|
|
||||||
public class NotifCoordinators implements Dumpable {
|
|
||||||
private static final String TAG = "NotifCoordinators";
|
|
||||||
private final List<Coordinator> mCoordinators = new ArrayList<>();
|
|
||||||
private final List<NotifSectioner> mOrderedSections = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates all the coordinators.
|
|
||||||
*/
|
|
||||||
@Inject
|
|
||||||
public NotifCoordinators(
|
|
||||||
DumpManager dumpManager,
|
|
||||||
FeatureFlags featureFlags,
|
|
||||||
HideNotifsForOtherUsersCoordinator hideNotifsForOtherUsersCoordinator,
|
|
||||||
KeyguardCoordinator keyguardCoordinator,
|
|
||||||
RankingCoordinator rankingCoordinator,
|
|
||||||
AppOpsCoordinator appOpsCoordinator,
|
|
||||||
DeviceProvisionedCoordinator deviceProvisionedCoordinator,
|
|
||||||
BubbleCoordinator bubbleCoordinator,
|
|
||||||
HeadsUpCoordinator headsUpCoordinator,
|
|
||||||
GutsCoordinator gutsCoordinator,
|
|
||||||
ConversationCoordinator conversationCoordinator,
|
|
||||||
PreparationCoordinator preparationCoordinator,
|
|
||||||
MediaCoordinator mediaCoordinator,
|
|
||||||
ShadeEventCoordinator shadeEventCoordinator,
|
|
||||||
SmartspaceDedupingCoordinator smartspaceDedupingCoordinator,
|
|
||||||
ViewConfigCoordinator viewConfigCoordinator,
|
|
||||||
VisualStabilityCoordinator visualStabilityCoordinator) {
|
|
||||||
dumpManager.registerDumpable(TAG, this);
|
|
||||||
|
|
||||||
mCoordinators.add(new HideLocallyDismissedNotifsCoordinator());
|
|
||||||
mCoordinators.add(hideNotifsForOtherUsersCoordinator);
|
|
||||||
mCoordinators.add(keyguardCoordinator);
|
|
||||||
mCoordinators.add(rankingCoordinator);
|
|
||||||
mCoordinators.add(appOpsCoordinator);
|
|
||||||
mCoordinators.add(deviceProvisionedCoordinator);
|
|
||||||
mCoordinators.add(bubbleCoordinator);
|
|
||||||
mCoordinators.add(conversationCoordinator);
|
|
||||||
mCoordinators.add(mediaCoordinator);
|
|
||||||
mCoordinators.add(shadeEventCoordinator);
|
|
||||||
mCoordinators.add(viewConfigCoordinator);
|
|
||||||
mCoordinators.add(visualStabilityCoordinator);
|
|
||||||
|
|
||||||
if (featureFlags.isSmartspaceDedupingEnabled()) {
|
|
||||||
mCoordinators.add(smartspaceDedupingCoordinator);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (featureFlags.isNewNotifPipelineRenderingEnabled()) {
|
|
||||||
mCoordinators.add(headsUpCoordinator);
|
|
||||||
mCoordinators.add(gutsCoordinator);
|
|
||||||
mCoordinators.add(preparationCoordinator);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manually add Ordered Sections
|
|
||||||
// HeadsUp > FGS > People > Alerting > Silent > Unknown/Default
|
|
||||||
if (featureFlags.isNewNotifPipelineRenderingEnabled()) {
|
|
||||||
mOrderedSections.add(headsUpCoordinator.getSectioner()); // HeadsUp
|
|
||||||
}
|
|
||||||
mOrderedSections.add(appOpsCoordinator.getSectioner()); // ForegroundService
|
|
||||||
mOrderedSections.add(conversationCoordinator.getSectioner()); // People
|
|
||||||
mOrderedSections.add(rankingCoordinator.getAlertingSectioner()); // Alerting
|
|
||||||
mOrderedSections.add(rankingCoordinator.getSilentSectioner()); // Silent
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends the pipeline to each coordinator when the pipeline is ready to accept
|
|
||||||
* {@link Pluggable}s, {@link NotifCollectionListener}s and {@link NotifLifetimeExtender}s.
|
|
||||||
*/
|
|
||||||
public void attach(NotifPipeline pipeline) {
|
|
||||||
for (Coordinator c : mCoordinators) {
|
|
||||||
c.attach(pipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
pipeline.setSections(mOrderedSections);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
|
||||||
pw.println();
|
|
||||||
pw.println(TAG + ":");
|
|
||||||
for (Coordinator c : mCoordinators) {
|
|
||||||
pw.println("\t" + c.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (NotifSectioner s : mOrderedSections) {
|
|
||||||
pw.println("\t" + s.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.android.systemui.statusbar.notification.collection.coordinator
|
||||||
|
|
||||||
|
import com.android.systemui.Dumpable
|
||||||
|
import com.android.systemui.dump.DumpManager
|
||||||
|
import com.android.systemui.flags.FeatureFlags
|
||||||
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
|
||||||
|
import java.io.FileDescriptor
|
||||||
|
import java.io.PrintWriter
|
||||||
|
import java.util.ArrayList
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the attachment of [Coordinator]s to the [NotifPipeline] so that the
|
||||||
|
* Coordinators can register their respective callbacks.
|
||||||
|
*/
|
||||||
|
interface NotifCoordinators : Coordinator, Dumpable
|
||||||
|
|
||||||
|
@CoordinatorScope
|
||||||
|
class NotifCoordinatorsImpl @Inject constructor(
|
||||||
|
dumpManager: DumpManager,
|
||||||
|
featureFlags: FeatureFlags,
|
||||||
|
hideLocallyDismissedNotifsCoordinator: HideLocallyDismissedNotifsCoordinator,
|
||||||
|
hideNotifsForOtherUsersCoordinator: HideNotifsForOtherUsersCoordinator,
|
||||||
|
keyguardCoordinator: KeyguardCoordinator,
|
||||||
|
rankingCoordinator: RankingCoordinator,
|
||||||
|
appOpsCoordinator: AppOpsCoordinator,
|
||||||
|
deviceProvisionedCoordinator: DeviceProvisionedCoordinator,
|
||||||
|
bubbleCoordinator: BubbleCoordinator,
|
||||||
|
headsUpCoordinator: HeadsUpCoordinator,
|
||||||
|
gutsCoordinator: GutsCoordinator,
|
||||||
|
conversationCoordinator: ConversationCoordinator,
|
||||||
|
preparationCoordinator: PreparationCoordinator,
|
||||||
|
mediaCoordinator: MediaCoordinator,
|
||||||
|
shadeEventCoordinator: ShadeEventCoordinator,
|
||||||
|
smartspaceDedupingCoordinator: SmartspaceDedupingCoordinator,
|
||||||
|
viewConfigCoordinator: ViewConfigCoordinator,
|
||||||
|
visualStabilityCoordinator: VisualStabilityCoordinator,
|
||||||
|
sensitiveContentCoordinator: SensitiveContentCoordinator
|
||||||
|
) : NotifCoordinators {
|
||||||
|
|
||||||
|
private val mCoordinators: MutableList<Coordinator> = ArrayList()
|
||||||
|
private val mOrderedSections: MutableList<NotifSectioner> = ArrayList()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates all the coordinators.
|
||||||
|
*/
|
||||||
|
init {
|
||||||
|
dumpManager.registerDumpable(TAG, this)
|
||||||
|
mCoordinators.add(hideLocallyDismissedNotifsCoordinator)
|
||||||
|
mCoordinators.add(hideNotifsForOtherUsersCoordinator)
|
||||||
|
mCoordinators.add(keyguardCoordinator)
|
||||||
|
mCoordinators.add(rankingCoordinator)
|
||||||
|
mCoordinators.add(appOpsCoordinator)
|
||||||
|
mCoordinators.add(deviceProvisionedCoordinator)
|
||||||
|
mCoordinators.add(bubbleCoordinator)
|
||||||
|
mCoordinators.add(conversationCoordinator)
|
||||||
|
mCoordinators.add(mediaCoordinator)
|
||||||
|
mCoordinators.add(shadeEventCoordinator)
|
||||||
|
mCoordinators.add(viewConfigCoordinator)
|
||||||
|
mCoordinators.add(visualStabilityCoordinator)
|
||||||
|
mCoordinators.add(sensitiveContentCoordinator)
|
||||||
|
if (featureFlags.isSmartspaceDedupingEnabled) {
|
||||||
|
mCoordinators.add(smartspaceDedupingCoordinator)
|
||||||
|
}
|
||||||
|
if (featureFlags.isNewNotifPipelineRenderingEnabled) {
|
||||||
|
mCoordinators.add(headsUpCoordinator)
|
||||||
|
mCoordinators.add(gutsCoordinator)
|
||||||
|
mCoordinators.add(preparationCoordinator)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manually add Ordered Sections
|
||||||
|
// HeadsUp > FGS > People > Alerting > Silent > Unknown/Default
|
||||||
|
if (featureFlags.isNewNotifPipelineRenderingEnabled) {
|
||||||
|
mOrderedSections.add(headsUpCoordinator.sectioner) // HeadsUp
|
||||||
|
}
|
||||||
|
mOrderedSections.add(appOpsCoordinator.sectioner) // ForegroundService
|
||||||
|
mOrderedSections.add(conversationCoordinator.sectioner) // People
|
||||||
|
mOrderedSections.add(rankingCoordinator.alertingSectioner) // Alerting
|
||||||
|
mOrderedSections.add(rankingCoordinator.silentSectioner) // Silent
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the pipeline to each coordinator when the pipeline is ready to accept
|
||||||
|
* [Pluggable]s, [NotifCollectionListener]s and [NotifLifetimeExtender]s.
|
||||||
|
*/
|
||||||
|
override fun attach(pipeline: NotifPipeline) {
|
||||||
|
for (c in mCoordinators) {
|
||||||
|
c.attach(pipeline)
|
||||||
|
}
|
||||||
|
pipeline.setSections(mOrderedSections)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
|
||||||
|
pw.println()
|
||||||
|
pw.println("$TAG:")
|
||||||
|
for (c in mCoordinators) {
|
||||||
|
pw.println("\t${c.javaClass}")
|
||||||
|
}
|
||||||
|
for (s in mOrderedSections) {
|
||||||
|
pw.println("\t${s.name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "NotifCoordinators"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -57,6 +57,7 @@ import javax.inject.Inject;
|
|||||||
* If a notification was uninflated, this coordinator will filter the notification out from the
|
* If a notification was uninflated, this coordinator will filter the notification out from the
|
||||||
* {@link ShadeListBuilder} until it is inflated.
|
* {@link ShadeListBuilder} until it is inflated.
|
||||||
*/
|
*/
|
||||||
|
// TODO(b/204468557): Move to @CoordinatorScope
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
public class PreparationCoordinator implements Coordinator {
|
public class PreparationCoordinator implements Coordinator {
|
||||||
private static final String TAG = "PreparationCoordinator";
|
private static final String TAG = "PreparationCoordinator";
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ package com.android.systemui.statusbar.notification.collection.coordinator;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.statusbar.notification.collection.ListEntry;
|
import com.android.systemui.statusbar.notification.collection.ListEntry;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
||||||
@@ -44,7 +44,7 @@ import javax.inject.Inject;
|
|||||||
* - whether the notification's app is suspended or hiding its notifications
|
* - whether the notification's app is suspended or hiding its notifications
|
||||||
* - whether DND settings are hiding notifications from ambient display or the notification list
|
* - whether DND settings are hiding notifications from ambient display or the notification list
|
||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@CoordinatorScope
|
||||||
public class RankingCoordinator implements Coordinator {
|
public class RankingCoordinator implements Coordinator {
|
||||||
public static final boolean SHOW_ALL_SECTIONS = false;
|
public static final boolean SHOW_ALL_SECTIONS = false;
|
||||||
private final StatusBarStateController mStatusBarStateController;
|
private final StatusBarStateController mStatusBarStateController;
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* 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.os.UserHandle
|
||||||
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
||||||
|
import com.android.systemui.statusbar.notification.DynamicPrivacyController
|
||||||
|
import com.android.systemui.statusbar.notification.collection.GroupEntry
|
||||||
|
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.coordinator.dagger.CoordinatorScope
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
|
||||||
|
@Module
|
||||||
|
object SensitiveContentCoordinatorModule {
|
||||||
|
@Provides
|
||||||
|
@JvmStatic
|
||||||
|
@CoordinatorScope
|
||||||
|
fun provideCoordinator(
|
||||||
|
dynamicPrivacyController: DynamicPrivacyController,
|
||||||
|
lockscreenUserManager: NotificationLockscreenUserManager
|
||||||
|
): SensitiveContentCoordinator =
|
||||||
|
SensitiveContentCoordinatorImpl(dynamicPrivacyController, lockscreenUserManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Coordinates re-inflation and post-processing of sensitive notification content. */
|
||||||
|
interface SensitiveContentCoordinator : Coordinator
|
||||||
|
|
||||||
|
private class SensitiveContentCoordinatorImpl(
|
||||||
|
private val dynamicPrivacyController: DynamicPrivacyController,
|
||||||
|
private val lockscreenUserManager: NotificationLockscreenUserManager
|
||||||
|
) : Invalidator("SensitiveContentInvalidator"),
|
||||||
|
SensitiveContentCoordinator,
|
||||||
|
DynamicPrivacyController.Listener,
|
||||||
|
OnBeforeRenderListListener {
|
||||||
|
|
||||||
|
override fun attach(pipeline: NotifPipeline) {
|
||||||
|
dynamicPrivacyController.addListener(this)
|
||||||
|
pipeline.addOnBeforeRenderListListener(this)
|
||||||
|
pipeline.addPreRenderInvalidator(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDynamicPrivacyChanged(): Unit = invalidateList()
|
||||||
|
|
||||||
|
override fun onBeforeRenderList(entries: List<ListEntry>) {
|
||||||
|
val currentUserId = lockscreenUserManager.currentUserId
|
||||||
|
val devicePublic = lockscreenUserManager.isLockscreenPublicMode(currentUserId)
|
||||||
|
val deviceSensitive = devicePublic &&
|
||||||
|
!lockscreenUserManager.userAllowsPrivateNotificationsInPublic(currentUserId)
|
||||||
|
val dynamicallyUnlocked = dynamicPrivacyController.isDynamicallyUnlocked
|
||||||
|
for (entry in extractAllRepresentativeEntries(entries).filter { it.rowExists() }) {
|
||||||
|
val notifUserId = entry.sbn.user.identifier
|
||||||
|
val userLockscreen = devicePublic ||
|
||||||
|
lockscreenUserManager.isLockscreenPublicMode(notifUserId)
|
||||||
|
val userPublic = when {
|
||||||
|
// if we're not on the lockscreen, we're definitely private
|
||||||
|
!userLockscreen -> false
|
||||||
|
// we are on the lockscreen, so unless we're dynamically unlocked, we're
|
||||||
|
// definitely public
|
||||||
|
!dynamicallyUnlocked -> true
|
||||||
|
// we're dynamically unlocked, but check if the notification needs
|
||||||
|
// a separate challenge if it's from a work profile
|
||||||
|
else -> when (notifUserId) {
|
||||||
|
currentUserId -> false
|
||||||
|
UserHandle.USER_ALL -> false
|
||||||
|
else -> lockscreenUserManager.needsSeparateWorkChallenge(notifUserId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val needsRedaction = lockscreenUserManager.needsRedaction(entry)
|
||||||
|
val isSensitive = userPublic && needsRedaction
|
||||||
|
entry.setSensitive(isSensitive, deviceSensitive)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun extractAllRepresentativeEntries(
|
||||||
|
entries: List<ListEntry>
|
||||||
|
): Sequence<NotificationEntry> =
|
||||||
|
entries.asSequence().flatMap(::extractAllRepresentativeEntries)
|
||||||
|
|
||||||
|
private fun extractAllRepresentativeEntries(listEntry: ListEntry): Sequence<NotificationEntry> =
|
||||||
|
sequence {
|
||||||
|
listEntry.representativeEntry?.let { yield(it) }
|
||||||
|
if (listEntry is GroupEntry) {
|
||||||
|
yieldAll(extractAllRepresentativeEntries(listEntry.children))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ import javax.inject.Inject
|
|||||||
* A coordinator which provides callbacks to a view surfaces for various events relevant to the
|
* 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.
|
* shade, such as when the user removes a notification, or when the shade is emptied.
|
||||||
*/
|
*/
|
||||||
|
// TODO(b/204468557): Move to @CoordinatorScope
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
class ShadeEventCoordinator @Inject internal constructor(
|
class ShadeEventCoordinator @Inject internal constructor(
|
||||||
private val mLogger: ShadeEventCoordinatorLogger
|
private val mLogger: ShadeEventCoordinatorLogger
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.notification.collection.coordinator
|
|||||||
|
|
||||||
import android.app.smartspace.SmartspaceTarget
|
import android.app.smartspace.SmartspaceTarget
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
|
||||||
import com.android.systemui.dagger.qualifiers.Main
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
||||||
@@ -28,6 +27,7 @@ import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController
|
|||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager
|
import com.android.systemui.statusbar.notification.NotificationEntryManager
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
|
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
|
||||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||||
@@ -45,7 +45,7 @@ import javax.inject.Inject
|
|||||||
*/
|
*/
|
||||||
// This class is a singleton so that the same instance can be accessed by both the old and new
|
// This class is a singleton so that the same instance can be accessed by both the old and new
|
||||||
// pipelines
|
// pipelines
|
||||||
@SysUISingleton
|
@CoordinatorScope
|
||||||
class SmartspaceDedupingCoordinator @Inject constructor(
|
class SmartspaceDedupingCoordinator @Inject constructor(
|
||||||
private val statusBarStateController: SysuiStatusBarStateController,
|
private val statusBarStateController: SysuiStatusBarStateController,
|
||||||
private val smartspaceController: LockscreenSmartspaceController,
|
private val smartspaceController: LockscreenSmartspaceController,
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ package com.android.systemui.statusbar.notification.collection.coordinator
|
|||||||
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
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
|
||||||
import com.android.systemui.flags.FeatureFlags
|
import com.android.systemui.flags.FeatureFlags
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl
|
import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationGutsManager
|
import com.android.systemui.statusbar.notification.row.NotificationGutsManager
|
||||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -33,7 +33,7 @@ import javax.inject.Inject
|
|||||||
* for the current uiMode and screen properties; additionally deferring those changes when a user
|
* for the current uiMode and screen properties; additionally deferring those changes when a user
|
||||||
* change is in progress until that process has completed.
|
* change is in progress until that process has completed.
|
||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@CoordinatorScope
|
||||||
class ViewConfigCoordinator @Inject internal constructor(
|
class ViewConfigCoordinator @Inject internal constructor(
|
||||||
configurationController: ConfigurationController,
|
configurationController: ConfigurationController,
|
||||||
lockscreenUserManager: NotificationLockscreenUserManagerImpl,
|
lockscreenUserManager: NotificationLockscreenUserManagerImpl,
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import javax.inject.Inject;
|
|||||||
* This is now integrated in the data-layer via
|
* This is now integrated in the data-layer via
|
||||||
* {@link com.android.systemui.statusbar.notification.collection.ShadeListBuilder}.
|
* {@link com.android.systemui.statusbar.notification.collection.ShadeListBuilder}.
|
||||||
*/
|
*/
|
||||||
|
// TODO(b/204468557): Move to @CoordinatorScope
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
public class VisualStabilityCoordinator implements Coordinator {
|
public class VisualStabilityCoordinator implements Coordinator {
|
||||||
private final DelayableExecutor mDelayableExecutor;
|
private final DelayableExecutor mDelayableExecutor;
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* 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.dagger
|
||||||
|
|
||||||
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinatorsImpl
|
||||||
|
import com.android.systemui.statusbar.notification.collection.coordinator.SensitiveContentCoordinatorModule
|
||||||
|
import dagger.Binds
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.Subcomponent
|
||||||
|
import javax.inject.Qualifier
|
||||||
|
import javax.inject.Scope
|
||||||
|
|
||||||
|
@Module(subcomponents = [CoordinatorsSubcomponent::class])
|
||||||
|
object CoordinatorsModule {
|
||||||
|
@SysUISingleton
|
||||||
|
@JvmStatic
|
||||||
|
@Provides
|
||||||
|
fun notifCoordinators(factory: CoordinatorsSubcomponent.Factory): NotifCoordinators =
|
||||||
|
factory.create().notifCoordinators
|
||||||
|
}
|
||||||
|
|
||||||
|
@CoordinatorScope
|
||||||
|
@Subcomponent(modules = [InternalCoordinatorsModule::class])
|
||||||
|
interface CoordinatorsSubcomponent {
|
||||||
|
@get:Internal val notifCoordinators: NotifCoordinators
|
||||||
|
|
||||||
|
@Subcomponent.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(): CoordinatorsSubcomponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Module(includes = [SensitiveContentCoordinatorModule::class])
|
||||||
|
private abstract class InternalCoordinatorsModule {
|
||||||
|
@Binds
|
||||||
|
@Internal
|
||||||
|
abstract fun bindNotifCoordinators(impl: NotifCoordinatorsImpl): NotifCoordinators
|
||||||
|
}
|
||||||
|
|
||||||
|
@Qualifier
|
||||||
|
@MustBeDocumented
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
private annotation class Internal
|
||||||
|
|
||||||
|
@Scope
|
||||||
|
@MustBeDocumented
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
annotation class CoordinatorScope
|
||||||
@@ -47,6 +47,15 @@ class ShadeListBuilderLogger @Inject constructor(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun logPreRenderInvalidated(filterName: String, pipelineState: Int) {
|
||||||
|
buffer.log(TAG, DEBUG, {
|
||||||
|
str1 = filterName
|
||||||
|
int1 = pipelineState
|
||||||
|
}, {
|
||||||
|
"""Pre-render Invalidator "$str1" invalidated; pipeline state is $int1"""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fun logPreGroupFilterInvalidated(filterName: String, pipelineState: Int) {
|
fun logPreGroupFilterInvalidated(filterName: String, pipelineState: Int) {
|
||||||
buffer.log(TAG, DEBUG, {
|
buffer.log(TAG, DEBUG, {
|
||||||
str1 = filterName
|
str1 = filterName
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* 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.listbuilder.pluggable;
|
||||||
|
|
||||||
|
/** A {@link Pluggable} that can only invalidate. */
|
||||||
|
public abstract class Invalidator extends Pluggable<Invalidator> {
|
||||||
|
protected Invalidator(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,6 +47,7 @@ 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.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.coordinator.dagger.CoordinatorsModule;
|
||||||
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;
|
||||||
@@ -93,7 +94,10 @@ import dagger.Provides;
|
|||||||
/**
|
/**
|
||||||
* Dagger Module for classes found within the com.android.systemui.statusbar.notification package.
|
* Dagger Module for classes found within the com.android.systemui.statusbar.notification package.
|
||||||
*/
|
*/
|
||||||
@Module(includes = {NotificationSectionHeadersModule.class})
|
@Module(includes = {
|
||||||
|
NotificationSectionHeadersModule.class,
|
||||||
|
CoordinatorsModule.class
|
||||||
|
})
|
||||||
public interface NotificationsModule {
|
public interface NotificationsModule {
|
||||||
@Binds
|
@Binds
|
||||||
StackScrollAlgorithm.SectionProvider bindSectionProvider(
|
StackScrollAlgorithm.SectionProvider bindSectionProvider(
|
||||||
|
|||||||
@@ -314,9 +314,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
|
|||||||
mShadeController.addPostCollapseAction(() -> updateNotificationViews(reason));
|
mShadeController.addPostCollapseAction(() -> updateNotificationViews(reason));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mViewHierarchyManager.updateNotificationViews();
|
mViewHierarchyManager.updateNotificationViews();
|
||||||
|
|
||||||
mNotificationPanel.updateNotificationViews(reason);
|
mNotificationPanel.updateNotificationViews(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import android.widget.LinearLayout;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
|
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
|
||||||
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
|
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
|
||||||
import com.android.systemui.statusbar.notification.DynamicChildBindController;
|
import com.android.systemui.statusbar.notification.DynamicChildBindController;
|
||||||
@@ -75,6 +76,7 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase {
|
|||||||
@Spy private FakeListContainer mListContainer = new FakeListContainer();
|
@Spy private FakeListContainer mListContainer = new FakeListContainer();
|
||||||
|
|
||||||
// Dependency mocks:
|
// Dependency mocks:
|
||||||
|
@Mock private FeatureFlags mFeatureFlags;
|
||||||
@Mock private NotificationEntryManager mEntryManager;
|
@Mock private NotificationEntryManager mEntryManager;
|
||||||
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
|
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
|
||||||
@Mock private NotificationGroupManagerLegacy mGroupManager;
|
@Mock private NotificationGroupManagerLegacy mGroupManager;
|
||||||
@@ -101,10 +103,14 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase {
|
|||||||
when(mVisualStabilityManager.areGroupChangesAllowed()).thenReturn(true);
|
when(mVisualStabilityManager.areGroupChangesAllowed()).thenReturn(true);
|
||||||
when(mVisualStabilityManager.isReorderingAllowed()).thenReturn(true);
|
when(mVisualStabilityManager.isReorderingAllowed()).thenReturn(true);
|
||||||
|
|
||||||
|
when(mFeatureFlags.isNewNotifPipelineEnabled()).thenReturn(false);
|
||||||
|
when(mFeatureFlags.checkLegacyPipelineEnabled()).thenReturn(true);
|
||||||
|
|
||||||
mHelper = new NotificationTestHelper(mContext, mDependency, TestableLooper.get(this));
|
mHelper = new NotificationTestHelper(mContext, mDependency, TestableLooper.get(this));
|
||||||
|
|
||||||
mViewHierarchyManager = new NotificationViewHierarchyManager(mContext,
|
mViewHierarchyManager = new NotificationViewHierarchyManager(mContext,
|
||||||
mHandler, mLockscreenUserManager, mGroupManager, mVisualStabilityManager,
|
mHandler, mFeatureFlags, mLockscreenUserManager, mGroupManager,
|
||||||
|
mVisualStabilityManager,
|
||||||
mock(StatusBarStateControllerImpl.class), mEntryManager,
|
mock(StatusBarStateControllerImpl.class), mEntryManager,
|
||||||
mock(KeyguardBypassController.class),
|
mock(KeyguardBypassController.class),
|
||||||
Optional.of(mock(Bubbles.class)),
|
Optional.of(mock(Bubbles.class)),
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.OnBefo
|
|||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.ShadeListBuilderLogger;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.ShadeListBuilderLogger;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
|
||||||
@@ -847,11 +848,13 @@ public class ShadeListBuilderTest extends SysuiTestCase {
|
|||||||
NotifPromoter idPromoter = new IdPromoter(4);
|
NotifPromoter idPromoter = new IdPromoter(4);
|
||||||
NotifSectioner section = new PackageSectioner(PACKAGE_1);
|
NotifSectioner section = new PackageSectioner(PACKAGE_1);
|
||||||
NotifComparator hypeComparator = new HypeComparator(PACKAGE_2);
|
NotifComparator hypeComparator = new HypeComparator(PACKAGE_2);
|
||||||
|
Invalidator preRenderInvalidator = new Invalidator("PreRenderInvalidator") {};
|
||||||
|
|
||||||
mListBuilder.addPreGroupFilter(packageFilter);
|
mListBuilder.addPreGroupFilter(packageFilter);
|
||||||
mListBuilder.addPromoter(idPromoter);
|
mListBuilder.addPromoter(idPromoter);
|
||||||
mListBuilder.setSectioners(singletonList(section));
|
mListBuilder.setSectioners(singletonList(section));
|
||||||
mListBuilder.setComparators(singletonList(hypeComparator));
|
mListBuilder.setComparators(singletonList(hypeComparator));
|
||||||
|
mListBuilder.addPreRenderInvalidator(preRenderInvalidator);
|
||||||
|
|
||||||
// GIVEN a set of random notifs
|
// GIVEN a set of random notifs
|
||||||
addNotif(0, PACKAGE_1);
|
addNotif(0, PACKAGE_1);
|
||||||
@@ -876,6 +879,10 @@ public class ShadeListBuilderTest extends SysuiTestCase {
|
|||||||
clearInvocations(mOnRenderListListener);
|
clearInvocations(mOnRenderListListener);
|
||||||
hypeComparator.invalidateList();
|
hypeComparator.invalidateList();
|
||||||
verify(mOnRenderListListener).onRenderList(anyList());
|
verify(mOnRenderListListener).onRenderList(anyList());
|
||||||
|
|
||||||
|
clearInvocations(mOnRenderListListener);
|
||||||
|
preRenderInvalidator.invalidateList();
|
||||||
|
verify(mOnRenderListListener).onRenderList(anyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* 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.os.UserHandle
|
||||||
|
import android.service.notification.StatusBarNotification
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
||||||
|
import com.android.systemui.statusbar.notification.DynamicPrivacyController
|
||||||
|
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.listbuilder.OnBeforeRenderListListener
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator
|
||||||
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable
|
||||||
|
import com.android.systemui.util.mockito.withArgCaptor
|
||||||
|
import com.android.systemui.util.mockito.mock
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.Mockito.`when` as whenever
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
class SensitiveContentCoordinatorTest : SysuiTestCase() {
|
||||||
|
|
||||||
|
val dynamicPrivacyController: DynamicPrivacyController = mock()
|
||||||
|
val lockscreenUserManager: NotificationLockscreenUserManager = mock()
|
||||||
|
val pipeline: NotifPipeline = mock()
|
||||||
|
|
||||||
|
val coordinator: SensitiveContentCoordinator = SensitiveContentCoordinatorModule
|
||||||
|
.provideCoordinator(dynamicPrivacyController, lockscreenUserManager)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onDynamicPrivacyChanged_invokeInvalidationListener() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val invalidator = withArgCaptor<Invalidator> {
|
||||||
|
verify(pipeline).addPreRenderInvalidator(capture())
|
||||||
|
}
|
||||||
|
val dynamicPrivacyListener = withArgCaptor<DynamicPrivacyController.Listener> {
|
||||||
|
verify(dynamicPrivacyController).addListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>()
|
||||||
|
invalidator.setInvalidationListener(invalidationListener)
|
||||||
|
|
||||||
|
dynamicPrivacyListener.onDynamicPrivacyChanged()
|
||||||
|
|
||||||
|
verify(invalidationListener).onPluggableInvalidated(invalidator)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
|
||||||
|
val entry = fakeNotification(1, false)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
|
||||||
|
val entry = fakeNotification(1, true)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
|
||||||
|
val entry = fakeNotification(1, false)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
|
||||||
|
val entry = fakeNotification(1, false)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(false, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceLocked_notifNeedsRedaction() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
|
||||||
|
val entry = fakeNotification(1, true)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(true, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
|
||||||
|
val entry = fakeNotification(1, true)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(false, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge() {
|
||||||
|
coordinator.attach(pipeline)
|
||||||
|
val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> {
|
||||||
|
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||||
|
}
|
||||||
|
|
||||||
|
whenever(lockscreenUserManager.currentUserId).thenReturn(1)
|
||||||
|
whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
|
||||||
|
whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
|
||||||
|
whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
|
||||||
|
|
||||||
|
val entry = fakeNotification(2, true)
|
||||||
|
|
||||||
|
onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
|
||||||
|
|
||||||
|
verify(entry.representativeEntry!!).setSensitive(true, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fakeNotification(notifUserId: Int, needsRedaction: Boolean): ListEntry {
|
||||||
|
val mockUserHandle = mock<UserHandle>().apply {
|
||||||
|
whenever(identifier).thenReturn(notifUserId)
|
||||||
|
}
|
||||||
|
val mockSbn: StatusBarNotification = mock<StatusBarNotification>().apply {
|
||||||
|
whenever(user).thenReturn(mockUserHandle)
|
||||||
|
}
|
||||||
|
val mockEntry = mock<NotificationEntry>().apply {
|
||||||
|
whenever(sbn).thenReturn(mockSbn)
|
||||||
|
}
|
||||||
|
whenever(lockscreenUserManager.needsRedaction(mockEntry)).thenReturn(needsRedaction)
|
||||||
|
whenever(mockEntry.rowExists()).thenReturn(true)
|
||||||
|
return object : ListEntry("key", 0) {
|
||||||
|
override fun getRepresentativeEntry(): NotificationEntry = mockEntry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user