Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0d069be authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Remove filtering old pipeline filtering...

Merge "Remove filtering old pipeline filtering inNotificationInterruptStateProviderImpl" into tm-dev
parents 35fed17b 5d1b9943
Loading
Loading
Loading
Loading
+8 −190
Original line number Diff line number Diff line
@@ -16,36 +16,16 @@

package com.android.systemui.statusbar.notification.collection.coordinator;

import static android.app.Notification.VISIBILITY_SECRET;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;

import androidx.annotation.MainThread;

import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider;
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.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;

import javax.inject.Inject;

@@ -56,171 +36,48 @@ import javax.inject.Inject;
@CoordinatorScope
public class KeyguardCoordinator implements Coordinator {
    private static final String TAG = "KeyguardCoordinator";

    private final Context mContext;
    private final Handler mMainHandler;
    private final KeyguardStateController mKeyguardStateController;
    private final NotificationLockscreenUserManager mLockscreenUserManager;
    private final BroadcastDispatcher mBroadcastDispatcher;
    private final StatusBarStateController mStatusBarStateController;
    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
    private final HighPriorityProvider mHighPriorityProvider;
    private final SectionHeaderVisibilityProvider mSectionHeaderVisibilityProvider;

    private boolean mHideSilentNotificationsOnLockscreen;
    private final KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;

    @Inject
    public KeyguardCoordinator(
            Context context,
            @MainThread Handler mainThreadHandler,
            KeyguardStateController keyguardStateController,
            NotificationLockscreenUserManager lockscreenUserManager,
            BroadcastDispatcher broadcastDispatcher,
            StatusBarStateController statusBarStateController,
            KeyguardUpdateMonitor keyguardUpdateMonitor,
            HighPriorityProvider highPriorityProvider,
            SectionHeaderVisibilityProvider sectionHeaderVisibilityProvider) {
        mContext = context;
        mMainHandler = mainThreadHandler;
        mKeyguardStateController = keyguardStateController;
        mLockscreenUserManager = lockscreenUserManager;
        mBroadcastDispatcher = broadcastDispatcher;
            SectionHeaderVisibilityProvider sectionHeaderVisibilityProvider,
            KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider) {
        mStatusBarStateController = statusBarStateController;
        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
        mHighPriorityProvider = highPriorityProvider;
        mSectionHeaderVisibilityProvider = sectionHeaderVisibilityProvider;
        mKeyguardNotificationVisibilityProvider = keyguardNotificationVisibilityProvider;
    }

    @Override
    public void attach(NotifPipeline pipeline) {
        readShowSilentNotificationSetting();

        setupInvalidateNotifListCallbacks();
        // Filter at the "finalize" stage so that views remain bound by PreparationCoordinator
        pipeline.addFinalizeFilter(mNotifFilter);

        mKeyguardNotificationVisibilityProvider
                .addOnStateChangedListener(this::invalidateListFromFilter);
        updateSectionHeadersVisibility();
    }

    private final NotifFilter mNotifFilter = new NotifFilter(TAG) {
        @Override
        public boolean shouldFilterOut(NotificationEntry entry, long now) {
            final StatusBarNotification sbn = entry.getSbn();

            // FILTER OUT the notification when the keyguard is showing and...
            if (mKeyguardStateController.isShowing()) {
                // ... user settings or the device policy manager doesn't allow lockscreen
                // notifications;
                if (!mLockscreenUserManager.shouldShowLockscreenNotifications()) {
                    return true;
                }

                final int currUserId = mLockscreenUserManager.getCurrentUserId();
                final int notifUserId = (sbn.getUser().getIdentifier() == UserHandle.USER_ALL)
                        ? currUserId : sbn.getUser().getIdentifier();

                // ... user is in lockdown
                if (mKeyguardUpdateMonitor.isUserInLockdown(currUserId)
                        || mKeyguardUpdateMonitor.isUserInLockdown(notifUserId)) {
                    return true;
                }

                // ... device is in public mode and the user's settings doesn't allow
                // notifications to show in public mode
                if (mLockscreenUserManager.isLockscreenPublicMode(currUserId)
                        || mLockscreenUserManager.isLockscreenPublicMode(notifUserId)) {
                    if (entry.getRanking().getLockscreenVisibilityOverride() == VISIBILITY_SECRET) {
                        return true;
                    }

                    if (!mLockscreenUserManager.userAllowsNotificationsInPublic(currUserId)
                            || !mLockscreenUserManager.userAllowsNotificationsInPublic(
                            notifUserId)) {
                        return true;
                    }
                }

                // ... neither this notification nor its group have high enough priority
                // to be shown on the lockscreen
                if (entry.getParent() != null) {
                    final GroupEntry parent = entry.getParent();
                    if (priorityExceedsLockscreenShowingThreshold(parent)) {
                        return false;
                    }
                }
                return !priorityExceedsLockscreenShowingThreshold(entry);
            }
            return false;
            return mKeyguardNotificationVisibilityProvider.hideNotification(entry);
        }
    };

    private boolean priorityExceedsLockscreenShowingThreshold(ListEntry entry) {
        if (entry == null) {
            return false;
        }
        if (mHideSilentNotificationsOnLockscreen) {
            return mHighPriorityProvider.isHighPriority(entry);
        } else {
            return entry.getRepresentativeEntry() != null
                    && !entry.getRepresentativeEntry().getRanking().isAmbient();
        }
    }

    // TODO(b/206118999): merge this class with SensitiveContentCoordinator which also depends on
    // these same updates
    private void setupInvalidateNotifListCallbacks() {
        // register onKeyguardShowing callback
        mKeyguardStateController.addCallback(mKeyguardCallback);
        mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);

        // register lockscreen settings changed callbacks:
        final ContentObserver settingsObserver = new ContentObserver(mMainHandler) {
            @Override
            public void onChange(boolean selfChange, Uri uri) {
                if (uri.equals(Settings.Secure.getUriFor(
                        Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS))) {
                    readShowSilentNotificationSetting();
                }

                if (mKeyguardStateController.isShowing()) {
                    invalidateListFromFilter("Settings " + uri + " changed");
                }
            }
        };

        mContext.getContentResolver().registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS),
                false,
                settingsObserver,
                UserHandle.USER_ALL);

        mContext.getContentResolver().registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
                true,
                settingsObserver,
                UserHandle.USER_ALL);

        mContext.getContentResolver().registerContentObserver(
                Settings.Global.getUriFor(Settings.Global.ZEN_MODE),
                false,
                settingsObserver);

        mContext.getContentResolver().registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS),
                false,
                settingsObserver,
                UserHandle.USER_ALL);

        // register (maybe) public mode changed callbacks:
        mStatusBarStateController.addCallback(mStatusBarStateListener);
        mBroadcastDispatcher.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (mKeyguardStateController.isShowing()) {
                    // maybe public mode changed
                    invalidateListFromFilter(intent.getAction());
                }
            }}, new IntentFilter(Intent.ACTION_USER_SWITCHED));
    }

    private void invalidateListFromFilter(String reason) {
@@ -228,49 +85,10 @@ public class KeyguardCoordinator implements Coordinator {
        mNotifFilter.invalidateList();
    }

    private void readShowSilentNotificationSetting() {
        mHideSilentNotificationsOnLockscreen =
                Settings.Secure.getInt(
                        mContext.getContentResolver(),
                        Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS,
                        1) == 0;
    }

    private void updateSectionHeadersVisibility() {
        boolean onKeyguard = mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
        boolean neverShowSections = mSectionHeaderVisibilityProvider.getNeverShowSectionHeaders();
        boolean showSections = !onKeyguard && !neverShowSections;
        mSectionHeaderVisibilityProvider.setSectionHeadersVisible(showSections);
    }

    private final KeyguardStateController.Callback mKeyguardCallback =
            new KeyguardStateController.Callback() {
        @Override
        public void onUnlockedChanged() {
            invalidateListFromFilter("onUnlockedChanged");
        }

        @Override
        public void onKeyguardShowingChanged() {
            invalidateListFromFilter("onKeyguardShowingChanged");
        }
    };

    private final StatusBarStateController.StateListener mStatusBarStateListener =
            new StatusBarStateController.StateListener() {
                @Override
                public void onStateChanged(int newState) {
                    // maybe public mode changed
                    invalidateListFromFilter("onStatusBarStateChanged");
                }
    };

    private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
            new KeyguardUpdateMonitorCallback() {
        @Override
        public void onStrongAuthStateChanged(int userId) {
            // maybe lockdown mode changed
            invalidateListFromFilter("onStrongAuthStateChanged");
        }
    };
}
+186 −0
Original line number Diff line number Diff line
package com.android.systemui.statusbar.notification.interruption

import android.app.Notification
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.database.ContentObserver
import android.net.Uri
import android.os.Handler
import android.os.UserHandle
import android.provider.Settings
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.CoreStartable
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.notification.collection.ListEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.ListenerSet
import java.util.function.Consumer
import javax.inject.Inject

/**
 * Determines if notifications should be visible based on the state of the keyguard
 */
class KeyguardNotificationVisibilityProvider @Inject constructor(
    context: Context,
    @Main private val handler: Handler,
    private val keyguardStateController: KeyguardStateController,
    private val lockscreenUserManager: NotificationLockscreenUserManager,
    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
    private val highPriorityProvider: HighPriorityProvider,
    private val statusBarStateController: StatusBarStateController,
    private val broadcastDispatcher: BroadcastDispatcher
) : CoreStartable(context) {
    private val onStateChangedListeners = ListenerSet<Consumer<String>>()
    private var hideSilentNotificationsOnLockscreen: Boolean = false

    override fun start() {
        readShowSilentNotificationSetting()
        keyguardStateController.addCallback(object : KeyguardStateController.Callback {
            override fun onUnlockedChanged() {
                notifyStateChanged("onUnlockedChanged")
            }

            override fun onKeyguardShowingChanged() {
                notifyStateChanged("onKeyguardShowingChanged")
            }
        })
        keyguardUpdateMonitor.registerCallback(object : KeyguardUpdateMonitorCallback() {
            override fun onStrongAuthStateChanged(userId: Int) {
                notifyStateChanged("onStrongAuthStateChanged")
            }
        })

        // register lockscreen settings changed callbacks:
        val settingsObserver: ContentObserver = object : ContentObserver(handler) {
            override fun onChange(selfChange: Boolean, uri: Uri) {
                if (keyguardStateController.isShowing) {
                    notifyStateChanged("Settings $uri changed")
                }
            }
        }

        mContext.contentResolver.registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS),
                false,
                settingsObserver,
                UserHandle.USER_ALL)

        mContext.contentResolver.registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
                true,
                settingsObserver,
                UserHandle.USER_ALL)

        mContext.contentResolver.registerContentObserver(
                Settings.Global.getUriFor(Settings.Global.ZEN_MODE),
                false,
                settingsObserver)

        mContext.contentResolver.registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS),
                false,
                settingsObserver,
                UserHandle.USER_ALL)

        // register (maybe) public mode changed callbacks:
        statusBarStateController.addCallback(object : StatusBarStateController.StateListener {
            override fun onStateChanged(state: Int) {
                notifyStateChanged("onStatusBarStateChanged")
            }
        })
        broadcastDispatcher.registerReceiver(object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                if (keyguardStateController.isShowing()) {
                    // maybe public mode changed
                    notifyStateChanged(intent.action)
                }
            }
        }, IntentFilter(Intent.ACTION_USER_SWITCHED))
    }

    fun addOnStateChangedListener(listener: Consumer<String>) {
        onStateChangedListeners.addIfAbsent(listener)
    }

    fun removeOnStateChangedListener(listener: Consumer<String>) {
        onStateChangedListeners.remove(listener)
    }

    private fun notifyStateChanged(reason: String) {
        onStateChangedListeners.forEach({ it.accept(reason) })
    }

    /**
     * Determines if the given notification should be hidden based on the current keyguard state.
     * If Listener#onKeyguardStateChanged is invoked, the results of this method may no longer
     * be valid, and so should be re-queried
     */
    fun hideNotification(entry: NotificationEntry): Boolean {
        val sbn = entry.sbn
        // FILTER OUT the notification when the keyguard is showing and...
        if (keyguardStateController.isShowing()) {
            // ... user settings or the device policy manager doesn't allow lockscreen
            // notifications;
            if (!lockscreenUserManager.shouldShowLockscreenNotifications()) {
                return true
            }
            val currUserId: Int = lockscreenUserManager.getCurrentUserId()
            val notifUserId =
                    if (sbn.user.identifier == UserHandle.USER_ALL) currUserId
                    else sbn.user.identifier

            // ... user is in lockdown
            if (keyguardUpdateMonitor.isUserInLockdown(currUserId) ||
                    keyguardUpdateMonitor.isUserInLockdown(notifUserId)) {
                return true
            }

            // ... device is in public mode and the user's settings doesn't allow
            // notifications to show in public mode
            if (lockscreenUserManager.isLockscreenPublicMode(currUserId) ||
                    lockscreenUserManager.isLockscreenPublicMode(notifUserId)) {
                if (entry.ranking.lockscreenVisibilityOverride == Notification.VISIBILITY_SECRET) {
                    return true
                }
                if (!lockscreenUserManager.userAllowsNotificationsInPublic(currUserId) ||
                        !lockscreenUserManager.userAllowsNotificationsInPublic(
                                notifUserId)) {
                    return true
                }
            }

            // ... neither this notification nor its group have high enough priority
            // to be shown on the lockscreen
            if (entry.parent != null) {
                val parent = entry.parent
                if (priorityExceedsLockscreenShowingThreshold(parent)) {
                    return false
                }
            }
            return !priorityExceedsLockscreenShowingThreshold(entry)
        }
        return false
    }

    private fun priorityExceedsLockscreenShowingThreshold(entry: ListEntry?): Boolean =
        when {
            entry == null -> false
            hideSilentNotificationsOnLockscreen -> highPriorityProvider.isHighPriority(entry)
            else -> entry.representativeEntry?.ranking?.isAmbient == false
        }

    private fun readShowSilentNotificationSetting() {
        hideSilentNotificationsOnLockscreen = Settings.Secure.getInt(
                mContext.getContentResolver(),
                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS,
                1) == 0
    }
}
 No newline at end of file
+8 −0
Original line number Diff line number Diff line
@@ -211,6 +211,14 @@ class NotificationInterruptLogger @Inject constructor(
            "Pulsing: $str1"
        })
    }

    fun keyguardHideNotification(key: String) {
        hunBuffer.log(TAG, DEBUG, {
            str1 = key
        }, {
            "Keyguard Hide Notification: $str1"
        })
    }
}

private const val TAG = "InterruptionStateProvider"
+14 −2
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -66,6 +67,8 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
    private final ContentObserver mHeadsUpObserver;
    private final HeadsUpManager mHeadsUpManager;
    private final NotificationInterruptLogger mLogger;
    private final NotifPipelineFlags mFlags;
    private final KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;

    @VisibleForTesting
    protected boolean mUseHeadsUp = false;
@@ -81,7 +84,9 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
            StatusBarStateController statusBarStateController,
            HeadsUpManager headsUpManager,
            NotificationInterruptLogger logger,
            @Main Handler mainHandler) {
            @Main Handler mainHandler,
            NotifPipelineFlags flags,
            KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider) {
        mContentResolver = contentResolver;
        mPowerManager = powerManager;
        mDreamManager = dreamManager;
@@ -91,6 +96,8 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
        mStatusBarStateController = statusBarStateController;
        mHeadsUpManager = headsUpManager;
        mLogger = logger;
        mFlags = flags;
        mKeyguardNotificationVisibilityProvider = keyguardNotificationVisibilityProvider;
        mHeadsUpObserver = new ContentObserver(mainHandler) {
            @Override
            public void onChange(boolean selfChange) {
@@ -282,7 +289,7 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
    private boolean canAlertCommon(NotificationEntry entry) {
        StatusBarNotification sbn = entry.getSbn();

        if (mNotificationFilter.shouldFilterOut(entry)) {
        if (!mFlags.isNewPipelineEnabled() && mNotificationFilter.shouldFilterOut(entry)) {
            mLogger.logNoAlertingFilteredOut(sbn);
            return false;
        }
@@ -305,6 +312,11 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
            return false;
        }

        if (mKeyguardNotificationVisibilityProvider.hideNotification(entry)) {
            mLogger.keyguardHideNotification(entry.getKey());
            return false;
        }

        return true;
    }

+5 −186

File changed.

Preview size limit exceeded, changes collapsed.

Loading