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

Commit 7c1ad5b2 authored by Beverly's avatar Beverly
Browse files

Introduce IsHighPriorityProvider

The IsHighPriorityProvider caches the isHighPriority
value for ListEntries instead of requiring the
NotificationRankingManager to set the value.

To interface with the current notification pipeline, we
use the GroupManager to look for grouping information, but
this code will eventually be deleted (b/145659174)

Test: atest GroupEntryTest NotificationEntryTest IsHighPriorityProviderTest NotificationRankingManagerTest
Test: atest SystemUiTests
Bug: 145134683
Change-Id: I24fbfddb648183552eb46d6b94cbb726e64468c8
parent 2753e748
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 * Represents a set of grouped notifications. The final notification list is usually a mix of
@@ -57,15 +58,22 @@ public class GroupEntry extends ListEntry {

    @VisibleForTesting
    public void setSummary(@Nullable NotificationEntry summary) {
        if (!Objects.equals(mSummary, summary)) {
            mSummary = summary;
            onGroupingUpdated();
        }
    }

    void clearChildren() {
        if (mChildren.size() != 0) {
            mChildren.clear();
            onGroupingUpdated();
        }
    }

    void addChild(NotificationEntry child) {
        mChildren.add(child);
        onGroupingUpdated();
    }

    void sortChildren(Comparator<? super NotificationEntry> c) {
@@ -77,4 +85,5 @@ public class GroupEntry extends ListEntry {
    }

    public static final GroupEntry ROOT_ENTRY = new GroupEntry("<root>");

}
+76 −1
Original line number Diff line number Diff line
@@ -19,6 +19,14 @@ package com.android.systemui.statusbar.notification.collection;
import android.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
import com.android.systemui.statusbar.notification.collection.provider.DerivedMember;
import com.android.systemui.statusbar.notification.collection.provider.IsHighPriorityProvider;
import com.android.systemui.statusbar.phone.NotificationGroupManager;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * Abstract superclass for top-level entries, i.e. things that can appear in the final notification
@@ -26,14 +34,23 @@ import com.android.internal.annotations.VisibleForTesting;
 */
public abstract class ListEntry {
    private final String mKey;
    private final IsHighPriorityProvider mIsHighPriorityProvider = new IsHighPriorityProvider();
    private final List<DerivedMember> mDerivedMemberList = Arrays.asList(mIsHighPriorityProvider);

    @Nullable private GroupEntry mParent;
    @Nullable private GroupEntry mPreviousParent;
    private int mSection;
    int mFirstAddedIteration = -1;

    // TODO: (b/145659174) remove groupManager when moving to NewNotifPipeline. Logic
    //  replaced in GroupEntry and NotifListBuilderImpl
    private final NotificationGroupManager mGroupManager;

    ListEntry(String key) {
        mKey = key;

        // TODO: (b/145659174) remove
        mGroupManager = Dependency.get(NotificationGroupManager.class);
    }

    public String getKey() {
@@ -53,7 +70,11 @@ public abstract class ListEntry {

    @VisibleForTesting
    public void setParent(@Nullable GroupEntry parent) {
        if (!Objects.equals(mParent, parent)) {
            invalidateParent();
            mParent = parent;
            onGroupingUpdated();
        }
    }

    @Nullable public GroupEntry getPreviousParent() {
@@ -72,4 +93,58 @@ public abstract class ListEntry {
    void setSection(int section) {
        mSection = section;
    }

    /**
     * Resets the cached values of DerivedMembers.
     */
    void invalidateDerivedMembers() {
        for (int i = 0; i < mDerivedMemberList.size(); i++) {
            mDerivedMemberList.get(i).invalidate();
        }
    }

    /**
     * Whether this notification is shown to the user as a high priority notification: visible on
     * the lock screen/status bar and in the top section in the shade.
     */
    public boolean isHighPriority() {
        return mIsHighPriorityProvider.get(this);
    }

    private void invalidateParent() {
        // invalidate our parent (GroupEntry) since DerivedMembers may be dependent on children
        if (getParent() != null) {
            getParent().invalidateDerivedMembers();
        }

        // TODO: (b/145659174) remove
        final NotificationEntry notifEntry = getRepresentativeEntry();
        if (notifEntry != null && mGroupManager.isGroupChild(notifEntry.getSbn())) {
            NotificationEntry summary = mGroupManager.getLogicalGroupSummary(notifEntry.getSbn());
            if (summary != null) {
                summary.invalidateDerivedMembers();
            }
        }
    }

    void onGroupingUpdated() {
        for (int i = 0; i < mDerivedMemberList.size(); i++) {
            mDerivedMemberList.get(i).onGroupingUpdated();
        }
        invalidateParent();
    }

    void onSbnUpdated() {
        for (int i = 0; i < mDerivedMemberList.size(); i++) {
            mDerivedMemberList.get(i).onSbnUpdated();
        }
        invalidateParent();
    }

    void onRankingUpdated() {
        for (int i = 0; i < mDerivedMemberList.size(); i++) {
            mDerivedMemberList.get(i).onRankingUpdated();
        }
        invalidateParent();
    }
}
+9 −54
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static android.app.Notification.CATEGORY_CALL;
import static android.app.Notification.CATEGORY_EVENT;
import static android.app.Notification.CATEGORY_MESSAGE;
import static android.app.Notification.CATEGORY_REMINDER;
import static android.app.Notification.EXTRA_MESSAGES;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
@@ -42,7 +41,6 @@ import android.app.Person;
import android.content.Context;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.SystemClock;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.SnoozeCriterion;
@@ -92,7 +90,6 @@ public final class NotificationEntry extends ListEntry {
    private StatusBarNotification mSbn;
    private Ranking mRanking;


    /*
     * Bookkeeping members
     */
@@ -120,7 +117,6 @@ public final class NotificationEntry extends ListEntry {
    public int targetSdk;
    private long lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET;
    public CharSequence remoteInputText;
    private final List<Person> mAssociatedPeople = new ArrayList<>();
    private Notification.BubbleMetadata mBubbleMetadata;

    /**
@@ -157,12 +153,6 @@ public final class NotificationEntry extends ListEntry {
     */
    private boolean hasSentReply;

    /**
     * Whether this notification is shown to the user as a high priority notification: visible on
     * the lock screen/status bar and in the top section in the shade.
     */
    private boolean mHighPriority;

    private boolean mSensitive = true;
    private Runnable mOnSensitiveChangedListener;
    private boolean mAutoHeadsUp;
@@ -212,9 +202,11 @@ public final class NotificationEntry extends ListEntry {
                    + " doesn't match existing key " + mKey);
        }

        if (!Objects.equals(mSbn, sbn)) {
            mSbn = sbn;
            mBubbleMetadata = mSbn.getNotification().getBubbleMetadata();
        updatePeopleList();
            onSbnUpdated();
        }
    }

    /**
@@ -239,9 +231,11 @@ public final class NotificationEntry extends ListEntry {
                    + " doesn't match existing key " + mKey);
        }

        if (!Objects.equals(mRanking, ranking)) {
            mRanking = ranking;
            onRankingUpdated();
        }
    }


    /*
     * Convenience getters for SBN and Ranking members
@@ -304,49 +298,10 @@ public final class NotificationEntry extends ListEntry {
        return interruption;
    }

    public boolean isHighPriority() {
        return mHighPriority;
    }

    public void setIsHighPriority(boolean highPriority) {
        this.mHighPriority = highPriority;
    }

    public boolean isBubble() {
        return (mSbn.getNotification().flags & FLAG_BUBBLE) != 0;
    }

    private void updatePeopleList() {
        mAssociatedPeople.clear();

        Bundle extras = mSbn.getNotification().extras;
        if (extras == null) {
            return;
        }

        List<Person> p = extras.getParcelableArrayList(Notification.EXTRA_PEOPLE_LIST);

        if (p != null) {
            mAssociatedPeople.addAll(p);
        }

        if (Notification.MessagingStyle.class.equals(
                mSbn.getNotification().getNotificationStyle())) {
            final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES);
            if (!ArrayUtils.isEmpty(messages)) {
                for (Notification.MessagingStyle.Message message :
                        Notification.MessagingStyle.Message
                                .getMessagesFromBundleArray(messages)) {
                    mAssociatedPeople.add(message.getSenderPerson());
                }
            }
        }
    }

    boolean hasAssociatedPeople() {
        return mAssociatedPeople.size() > 0;
    }

    /**
     * Returns the data needed for a bubble for this notification, if it exists.
     */
+4 −42
Original line number Diff line number Diff line
@@ -16,14 +16,11 @@

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

import android.app.NotificationManager.IMPORTANCE_DEFAULT
import android.app.NotificationManager.IMPORTANCE_HIGH
import android.app.NotificationManager.IMPORTANCE_LOW
import android.app.NotificationManager.IMPORTANCE_MIN
import android.service.notification.NotificationListenerService.Ranking
import android.service.notification.NotificationListenerService.RankingMap
import android.service.notification.StatusBarNotification
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.statusbar.NotificationMediaManager
import com.android.systemui.statusbar.notification.NotificationFilter
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
@@ -105,44 +102,6 @@ open class NotificationRankingManager @Inject constructor(
        return entry.key == mediaManager.mediaNotificationKey && importance > IMPORTANCE_MIN
    }

    @VisibleForTesting
    protected fun isHighPriority(entry: NotificationEntry): Boolean {
        if (entry.importance >= IMPORTANCE_DEFAULT ||
                hasHighPriorityCharacteristics(entry)) {
            return true
        }

        if (groupManager.isSummaryOfGroup(entry.sbn)) {
            val logicalChildren = groupManager.getLogicalChildren(entry.sbn)
            for (child in logicalChildren) {
                if (isHighPriority(child)) {
                    return true
                }
            }
        }

        return false
    }

    private fun hasHighPriorityCharacteristics(entry: NotificationEntry): Boolean {
        val c = entry.channel
        val n = entry.sbn.notification

        if ((n.isForegroundService && entry.ranking.importance >= IMPORTANCE_LOW) ||
                n.hasMediaSession() ||
                entry.isPeopleNotification()) {
            // Users who have long pressed and demoted to silent should not see the notification
            // in the top section
            if (c != null && c.hasUserSetImportance()) {
                return false
            }

            return true
        }

        return false
    }

    fun updateRanking(
        newRankingMap: RankingMap?,
        entries: Collection<NotificationEntry>,
@@ -219,7 +178,10 @@ open class NotificationRankingManager @Inject constructor(
                        // TODO: notify group manager here?
                        groupManager.onEntryUpdated(entry, oldSbn)
                    }
                    entry.setIsHighPriority(isHighPriority(entry))

                    // TODO: (b/145659174) remove after moving to new NotifPipeline
                    // (should be able to remove all groupManager code post-migration)
                    entry.invalidateDerivedMembers()
                }
            }
        }
+6 −4
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
@@ -133,8 +135,8 @@ public class KeyguardCoordinator implements Coordinator {
                // to be shown on the lockscreen
                // TODO: grouping hasn't happened yet (b/145134683)
                if (entry.getParent() != null) {
                    final NotificationEntry summary = entry.getParent().getRepresentativeEntry();
                    if (priorityExceedsLockscreenShowingThreshold(summary)) {
                    final GroupEntry parent = entry.getParent();
                    if (priorityExceedsLockscreenShowingThreshold(parent)) {
                        return false;
                    }
                }
@@ -144,7 +146,7 @@ public class KeyguardCoordinator implements Coordinator {
        }
    };

    private boolean priorityExceedsLockscreenShowingThreshold(NotificationEntry entry) {
    private boolean priorityExceedsLockscreenShowingThreshold(ListEntry entry) {
        if (entry == null) {
            return false;
        }
@@ -154,7 +156,7 @@ public class KeyguardCoordinator implements Coordinator {
            //  correctly updated before reaching this point (b/145134683)
            return entry.isHighPriority();
        } else {
            return !entry.getRanking().isAmbient();
            return !entry.getRepresentativeEntry().getRanking().isAmbient();
        }
    }

Loading