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

Commit 61989bcc authored by Beverly Tai's avatar Beverly Tai Committed by Android (Google) Code Review
Browse files

Merge "resolve merge conflicts of 6fb6adc7 to master"

parents d4b266a1 67381d17
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import com.android.keyguard.AlphaOptimizedLinearLayout;
import com.android.systemui.R;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry.OnSensitivityChangedListener;

import java.util.List;

@@ -159,20 +160,30 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout {
    }

    public void setEntry(NotificationEntry entry) {
        if (entry != null) {
        if (mShowingEntry != null) {
            mShowingEntry.removeOnSensitivityChangedListener(mOnSensitivityChangedListener);
        }
        mShowingEntry = entry;

        if (mShowingEntry != null) {
            CharSequence text = entry.headsUpStatusBarText;
            if (entry.isSensitive()) {
                text = entry.headsUpStatusBarTextPublic;
            }
            mTextView.setText(text);
            mShowingEntry.setOnSensitiveChangedListener(() -> setEntry(entry));
        } else if (mShowingEntry != null){
            mShowingEntry.setOnSensitiveChangedListener(null);
            mShowingEntry = null;
            mShowingEntry.addOnSensitivityChangedListener(mOnSensitivityChangedListener);
        }
    }

    private final OnSensitivityChangedListener mOnSensitivityChangedListener = entry -> {
        if (entry != mShowingEntry) {
            throw new IllegalStateException("Got a sensitivity change for " + entry
                    + " but mShowingEntry is " + mShowingEntry);
        }
        // Update the text
        setEntry(entry);
    };

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
+4 −4
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -262,11 +263,11 @@ public class NotificationMediaManager implements Dumpable {
        synchronized (mEntryManager) {
            NotificationEntry entry = mEntryManager
                    .getActiveNotificationUnfiltered(mMediaNotificationKey);
            if (entry == null || entry.expandedIcon == null) {
            if (entry == null || entry.getIcons().getShelfIcon() == null) {
                return null;
            }

            return entry.expandedIcon.getSourceIcon();
            return entry.getIcons().getShelfIcon().getSourceIcon();
        }
    }

@@ -284,8 +285,7 @@ public class NotificationMediaManager implements Dumpable {
        boolean metaDataChanged = false;

        synchronized (mEntryManager) {
            Set<NotificationEntry> allNotifications =
                    mEntryManager.getPendingAndActiveNotifications();
            Collection<NotificationEntry> allNotifications = mEntryManager.getAllNotifs();

            // Promote the media notification with a controller in 'playing' state, if any.
            NotificationEntry mediaNotification = null;
+3 −3
Original line number Diff line number Diff line
@@ -329,7 +329,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
                    expandableRow.setAboveShelf(false);
                }
                if (notGoneIndex == 0) {
                    StatusBarIconView icon = expandableRow.getEntry().expandedIcon;
                    StatusBarIconView icon = expandableRow.getEntry().getIcons().getShelfIcon();
                    NotificationIconContainer.IconState iconState = getIconState(icon);
                    // The icon state might be null in rare cases where the notification is actually
                    // added to the layout, but not to the shelf. An example are replied messages,
@@ -432,7 +432,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
            // if the shelf is clipped, lets make sure we also clip the icon
            maxTop = Math.max(maxTop, getTranslationY() + getClipTopAmount());
        }
        StatusBarIconView icon = row.getEntry().expandedIcon;
        StatusBarIconView icon = row.getEntry().getIcons().getShelfIcon();
        float shelfIconPosition = getTranslationY() + icon.getTop() + icon.getTranslationY();
        if (shelfIconPosition < maxTop && !mAmbientState.isFullyHidden()) {
            int top = (int) (maxTop - shelfIconPosition);
@@ -444,7 +444,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
    }

    private void updateContinuousClipping(final ExpandableNotificationRow row) {
        StatusBarIconView icon = row.getEntry().expandedIcon;
        StatusBarIconView icon = row.getEntry().getIcons().getShelfIcon();
        boolean needsContinuousClipping = ViewState.isAnimatingY(icon) && !mAmbientState.isDozing();
        boolean isContinuousClipping = icon.getTag(TAG_CONTINUOUS_CLIPPING) != null;
        if (needsContinuousClipping && !isContinuousClipping) {
+19 −11
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
@@ -56,9 +57,9 @@ import com.android.systemui.util.leak.LeakDetector;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -105,6 +106,10 @@ public class NotificationEntryManager implements
     */
    public static final int UNDEFINED_DISMISS_REASON = 0;

    private final Set<NotificationEntry> mAllNotifications = new ArraySet<>();
    private final Set<NotificationEntry> mReadOnlyAllNotifications =
            Collections.unmodifiableSet(mAllNotifications);

    /** Pending notifications are ones awaiting inflation */
    @VisibleForTesting
    protected final HashMap<String, NotificationEntry> mPendingNotifications = new HashMap<>();
@@ -468,6 +473,8 @@ public class NotificationEntryManager implements
                    entry.removeRow();
                }

                mAllNotifications.remove(entry);

                // Let's remove the children if this was a summary
                handleGroupSummaryRemoved(key);
                removeVisibleNotification(key);
@@ -548,6 +555,7 @@ public class NotificationEntryManager implements
                notification,
                ranking,
                mFgsFeatureController.isForegroundServiceDismissalEnabled());
        mAllNotifications.add(entry);

        mLeakDetector.trackInstance(entry);

@@ -708,15 +716,6 @@ public class NotificationEntryManager implements
        return mPendingNotifications.values();
    }

    /**
     * @return all notifications we're currently aware of (both pending and active notifications)
     */
    public Set<NotificationEntry> getPendingAndActiveNotifications() {
        Set<NotificationEntry> allNotifs = new HashSet<>(mPendingNotifications.values());
        allNotifs.addAll(mSortedAndFiltered);
        return allNotifs;
    }

    /**
     * Use this method to retrieve a notification entry that has been prepared for presentation.
     * Note that the notification may be filtered out and never shown to the user.
@@ -842,7 +841,7 @@ public class NotificationEntryManager implements

    private void dumpEntry(PrintWriter pw, String indent, int i, NotificationEntry e) {
        pw.print(indent);
        pw.println("  [" + i + "] key=" + e.getKey() + " icon=" + e.icon);
        pw.println("  [" + i + "] key=" + e.getKey() + " icon=" + e.getIcons().getStatusBarIcon());
        StatusBarNotification n = e.getSbn();
        pw.print(indent);
        pw.println("      pkg=" + n.getPackageName() + " id=" + n.getId() + " importance="
@@ -861,6 +860,15 @@ public class NotificationEntryManager implements
        return mReadOnlyNotifications;
    }

    /**
     * Returns a collections containing ALL notifications we know about, including ones that are
     * hidden or for other users. See {@link CommonNotifCollection#getAllNotifs()}.
     */
    @Override
    public Collection<NotificationEntry> getAllNotifs() {
        return mReadOnlyAllNotifications;
    }

    /** @return A count of the active notifications */
    public int getActiveNotificationsCount() {
        return mReadOnlyNotifications.size();
+48 −81
Original line number Diff line number Diff line
@@ -64,24 +64,34 @@ import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.notification.collection.coalescer.CoalescedEvent;
import com.android.systemui.statusbar.notification.collection.coalescer.GroupCoalescer;
import com.android.systemui.statusbar.notification.collection.coalescer.GroupCoalescer.BatchableNotificationHandler;
import com.android.systemui.statusbar.notification.collection.notifcollection.CleanUpEntryEvent;
import com.android.systemui.statusbar.notification.collection.notifcollection.CollectionReadyForBuildListener;
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.EntryAddedEvent;
import com.android.systemui.statusbar.notification.collection.notifcollection.EntryRemovedEvent;
import com.android.systemui.statusbar.notification.collection.notifcollection.EntryUpdatedEvent;
import com.android.systemui.statusbar.notification.collection.notifcollection.InitEntryEvent;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionLogger;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifEvent;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
import com.android.systemui.statusbar.notification.collection.notifcollection.RankingAppliedEvent;
import com.android.systemui.statusbar.notification.collection.notifcollection.RankingUpdatedEvent;
import com.android.systemui.util.Assert;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;

import javax.inject.Inject;
import javax.inject.Singleton;
@@ -124,6 +134,8 @@ public class NotifCollection implements Dumpable {
    private final List<NotifLifetimeExtender> mLifetimeExtenders = new ArrayList<>();
    private final List<NotifDismissInterceptor> mDismissInterceptors = new ArrayList<>();

    private Queue<NotifEvent> mEventQueue = new ArrayDeque<>();

    private boolean mAttached = false;
    private boolean mAmDispatchingToOtherCode;

@@ -160,8 +172,8 @@ public class NotifCollection implements Dumpable {
        mBuildListener = buildListener;
    }

    /** @see NotifPipeline#getActiveNotifs() */
    Collection<NotificationEntry> getActiveNotifs() {
    /** @see NotifPipeline#getAllNotifs() */
    Collection<NotificationEntry> getAllNotifs() {
        Assert.isMainThread();
        return mReadOnlyNotificationSet;
    }
@@ -243,7 +255,7 @@ public class NotifCollection implements Dumpable {
        }

        locallyDismissNotifications(entriesToLocallyDismiss);
        rebuildList();
        dispatchEventsAndRebuildList();
    }

    /**
@@ -269,7 +281,7 @@ public class NotifCollection implements Dumpable {
            mLogger.logRemoteExceptionOnClearAllNotifications(e);
        }

        final List<NotificationEntry> entries = new ArrayList<>(getActiveNotifs());
        final List<NotificationEntry> entries = new ArrayList<>(getAllNotifs());
        for (int i = entries.size() - 1; i >= 0; i--) {
            NotificationEntry entry = entries.get(i);
            if (!shouldDismissOnClearAll(entry, userId)) {
@@ -284,7 +296,7 @@ public class NotifCollection implements Dumpable {
        }

        locallyDismissNotifications(entries);
        rebuildList();
        dispatchEventsAndRebuildList();
    }

    /**
@@ -327,8 +339,9 @@ public class NotifCollection implements Dumpable {
    private void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
        Assert.isMainThread();

        postNotification(sbn, requireRanking(rankingMap, sbn.getKey()), rankingMap);
        rebuildList();
        postNotification(sbn, requireRanking(rankingMap, sbn.getKey()));
        applyRanking(rankingMap);
        dispatchEventsAndRebuildList();
    }

    private void onNotificationGroupPosted(List<CoalescedEvent> batch) {
@@ -337,9 +350,9 @@ public class NotifCollection implements Dumpable {
        mLogger.logNotifGroupPosted(batch.get(0).getSbn().getGroupKey(), batch.size());

        for (CoalescedEvent event : batch) {
            postNotification(event.getSbn(), event.getRanking(), null);
            postNotification(event.getSbn(), event.getRanking());
        }
        rebuildList();
        dispatchEventsAndRebuildList();
    }

    private void onNotificationRemoved(
@@ -355,55 +368,49 @@ public class NotifCollection implements Dumpable {
            throw new IllegalStateException("No notification to remove with key " + sbn.getKey());
        }
        entry.mCancellationReason = reason;
        applyRanking(rankingMap);
        tryRemoveNotification(entry);
        rebuildList();
        applyRanking(rankingMap);
        dispatchEventsAndRebuildList();
    }

    private void onNotificationRankingUpdate(RankingMap rankingMap) {
        Assert.isMainThread();
        mEventQueue.add(new RankingUpdatedEvent(rankingMap));
        applyRanking(rankingMap);
        dispatchNotificationRankingUpdate(rankingMap);
        rebuildList();
        dispatchEventsAndRebuildList();
    }

    private void postNotification(
            StatusBarNotification sbn,
            Ranking ranking,
            @Nullable RankingMap rankingMap) {
            Ranking ranking) {
        NotificationEntry entry = mNotificationSet.get(sbn.getKey());

        if (entry == null) {
            // A new notification!
            mLogger.logNotifPosted(sbn.getKey());

            entry = new NotificationEntry(sbn, ranking);
            mNotificationSet.put(sbn.getKey(), entry);
            dispatchOnEntryInit(entry);

            if (rankingMap != null) {
                applyRanking(rankingMap);
            }

            dispatchOnEntryAdded(entry);
            mLogger.logNotifPosted(sbn.getKey());
            mEventQueue.add(new InitEntryEvent(entry));
            mEventQueue.add(new EntryAddedEvent(entry));

        } else {
            // Update to an existing entry
            mLogger.logNotifUpdated(sbn.getKey());

            // Notification is updated so it is essentially re-added and thus alive again, so we
            // can reset its state.
            // TODO: If a coalesced event ever gets here, it's possible to lose track of children,
            //  since their rankings might have been updated earlier (and thus we may no longer
            //  think a child is associated with this locally-dismissed entry).
            cancelLocalDismissal(entry);
            cancelLifetimeExtension(entry);
            cancelDismissInterception(entry);
            entry.mCancellationReason = REASON_NOT_CANCELED;

            entry.setSbn(sbn);
            if (rankingMap != null) {
                applyRanking(rankingMap);
            }

            dispatchOnEntryUpdated(entry);
            mLogger.logNotifUpdated(sbn.getKey());
            mEventQueue.add(new EntryUpdatedEvent(entry));
        }
    }

@@ -433,8 +440,8 @@ public class NotifCollection implements Dumpable {
        if (!isLifetimeExtended(entry)) {
            mNotificationSet.remove(entry.getKey());
            cancelDismissInterception(entry);
            dispatchOnEntryRemoved(entry, entry.mCancellationReason);
            dispatchOnEntryCleanUp(entry);
            mEventQueue.add(new EntryRemovedEvent(entry, entry.mCancellationReason));
            mEventQueue.add(new CleanUpEntryEvent(entry));
            return true;
        } else {
            return false;
@@ -467,9 +474,16 @@ public class NotifCollection implements Dumpable {
                }
            }
        }
        mEventQueue.add(new RankingAppliedEvent());
    }

    private void dispatchEventsAndRebuildList() {
        mAmDispatchingToOtherCode = true;
        while (!mEventQueue.isEmpty()) {
            mEventQueue.remove().dispatchTo(mNotifCollectionListeners);
        }
        mAmDispatchingToOtherCode = false;

    private void rebuildList() {
        if (mBuildListener != null) {
            mBuildListener.onBuildList(mReadOnlyNotificationSet);
        }
@@ -492,7 +506,7 @@ public class NotifCollection implements Dumpable {

        if (!isLifetimeExtended(entry)) {
            if (tryRemoveNotification(entry)) {
                rebuildList();
                dispatchEventsAndRebuildList();
            }
        }
    }
@@ -661,57 +675,9 @@ public class NotifCollection implements Dumpable {
                || entry.getSbn().getUser().getIdentifier() == userId;
    }

    private void dispatchOnEntryInit(NotificationEntry entry) {
        mAmDispatchingToOtherCode = true;
        for (NotifCollectionListener listener : mNotifCollectionListeners) {
            listener.onEntryInit(entry);
        }
        mAmDispatchingToOtherCode = false;
    }

    private void dispatchOnEntryAdded(NotificationEntry entry) {
        mAmDispatchingToOtherCode = true;
        for (NotifCollectionListener listener : mNotifCollectionListeners) {
            listener.onEntryAdded(entry);
        }
        mAmDispatchingToOtherCode = false;
    }

    private void dispatchOnEntryUpdated(NotificationEntry entry) {
        mAmDispatchingToOtherCode = true;
        for (NotifCollectionListener listener : mNotifCollectionListeners) {
            listener.onEntryUpdated(entry);
        }
        mAmDispatchingToOtherCode = false;
    }

    private void dispatchNotificationRankingUpdate(RankingMap map) {
        mAmDispatchingToOtherCode = true;
        for (NotifCollectionListener listener : mNotifCollectionListeners) {
            listener.onRankingUpdate(map);
        }
        mAmDispatchingToOtherCode = false;
    }

    private void dispatchOnEntryRemoved(NotificationEntry entry, @CancellationReason int reason) {
        mAmDispatchingToOtherCode = true;
        for (NotifCollectionListener listener : mNotifCollectionListeners) {
            listener.onEntryRemoved(entry, reason);
        }
        mAmDispatchingToOtherCode = false;
    }

    private void dispatchOnEntryCleanUp(NotificationEntry entry) {
        mAmDispatchingToOtherCode = true;
        for (NotifCollectionListener listener : mNotifCollectionListeners) {
            listener.onEntryCleanUp(entry);
        }
        mAmDispatchingToOtherCode = false;
    }

    @Override
    public void dump(@NonNull FileDescriptor fd, PrintWriter pw, @NonNull String[] args) {
        final List<NotificationEntry> entries = new ArrayList<>(getActiveNotifs());
        final List<NotificationEntry> entries = new ArrayList<>(getAllNotifs());

        pw.println("\t" + TAG + " unsorted/unfiltered notifications:");
        if (entries.size() == 0) {
@@ -755,6 +721,7 @@ public class NotifCollection implements Dumpable {
    private static final String TAG = "NotifCollection";

    @IntDef(prefix = { "REASON_" }, value = {
            REASON_NOT_CANCELED,
            REASON_UNKNOWN,
            REASON_CLICK,
            REASON_CANCEL_ALL,
Loading