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

Commit ef5127ea authored by Selim Cinek's avatar Selim Cinek
Browse files

Isolating heads up children from their groups now

Group children are now isolated into their own group for a few seconds
until it's merged into the group again when they are
heads upped. This makes notifications groups finally usable with
HUNs again.

Change-Id: I0cb5e4f7a70e09989030dfe70ddcbb50575c1c02
parent 5bc852a9
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -584,13 +584,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
    private void updateChildrenVisibility() {
        mPrivateLayout.setVisibility(!mShowingPublic && !mIsSummaryWithChildren ? VISIBLE
                : INVISIBLE);
        if (mChildrenContainer == null) {
            return;
        }
        if (mChildrenContainer != null) {
            mChildrenContainer.setVisibility(!mShowingPublic && mIsSummaryWithChildren ? VISIBLE
                    : INVISIBLE);
        }
        if (mNotificationHeader != null) {
            mNotificationHeader.setVisibility(!mShowingPublic && mIsSummaryWithChildren ? VISIBLE
                    : INVISIBLE);
        }
        // The limits might have changed if the view suddenly became a group or vice versa
        updateLimits();
    }
+97 −27
Original line number Diff line number Diff line
@@ -16,12 +16,13 @@

package com.android.systemui.statusbar.phone;

import android.app.Notification;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;

import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.policy.HeadsUpManager;

import java.util.HashMap;
import java.util.HashSet;
@@ -29,18 +30,19 @@ import java.util.HashSet;
/**
 * A class to handle notifications and their corresponding groups.
 */
public class NotificationGroupManager {
public class NotificationGroupManager implements HeadsUpManager.OnHeadsUpChangedListener {

    private final HashMap<String, NotificationGroup> mGroupMap = new HashMap<>();
    private OnGroupChangeListener mListener;
    private int mBarState = -1;
    private ArraySet<String> mHeadsUpedEntries = new ArraySet<>();

    public void setOnGroupChangeListener(OnGroupChangeListener listener) {
        mListener = listener;
    }

    public boolean isGroupExpanded(StatusBarNotification sbn) {
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        NotificationGroup group = mGroupMap.get(getGroupKey(sbn));
        if (group == null) {
            return false;
        }
@@ -48,7 +50,7 @@ public class NotificationGroupManager {
    }

    public void setGroupExpanded(StatusBarNotification sbn, boolean expanded) {
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        NotificationGroup group = mGroupMap.get(getGroupKey(sbn));
        if (group == null) {
            return;
        }
@@ -75,8 +77,7 @@ public class NotificationGroupManager {
     */
    private void onEntryRemovedInternal(NotificationData.Entry removed,
            final StatusBarNotification sbn) {
        Notification notif = sbn.getNotification();
        String groupKey = sbn.getGroupKey();
        String groupKey = getGroupKey(sbn);
        final NotificationGroup group = mGroupMap.get(groupKey);
        if (group == null) {
            // When an app posts 2 different notifications as summary of the same group, then a
@@ -85,7 +86,7 @@ public class NotificationGroupManager {
            // the close future. See b/23676310 for reference.
            return;
        }
        if (notif.isGroupChild()) {
        if (isGroupChild(sbn)) {
            group.children.remove(removed);
        } else {
            group.summary = null;
@@ -97,16 +98,16 @@ public class NotificationGroupManager {
        }
    }

    public void onEntryAdded(NotificationData.Entry added) {
        StatusBarNotification sbn = added.notification;
        Notification notif = sbn.getNotification();
        String groupKey = sbn.getGroupKey();
    public void onEntryAdded(final NotificationData.Entry added) {
        final StatusBarNotification sbn = added.notification;
        boolean isGroupChild = isGroupChild(sbn);
        String groupKey = getGroupKey(sbn);
        NotificationGroup group = mGroupMap.get(groupKey);
        if (group == null) {
            group = new NotificationGroup();
            mGroupMap.put(groupKey, group);
        }
        if (notif.isGroupChild()) {
        if (isGroupChild) {
            group.children.add(added);
        } else {
            group.summary = added;
@@ -119,17 +120,17 @@ public class NotificationGroupManager {

    public void onEntryUpdated(NotificationData.Entry entry,
            StatusBarNotification oldNotification) {
        if (mGroupMap.get(oldNotification.getGroupKey()) != null) {
        if (mGroupMap.get(getGroupKey(oldNotification)) != null) {
            onEntryRemovedInternal(entry, oldNotification);
        }
        onEntryAdded(entry);
    }

    public boolean isVisible(StatusBarNotification sbn) {
        if (!sbn.getNotification().isGroupChild()) {
        if (!isGroupChild(sbn)) {
            return true;
        }
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        NotificationGroup group = mGroupMap.get(getGroupKey(sbn));
        if (group != null && (group.expanded || group.summary == null)) {
            return true;
        }
@@ -137,10 +138,10 @@ public class NotificationGroupManager {
    }

    public boolean hasGroupChildren(StatusBarNotification sbn) {
        if (!sbn.getNotification().isGroupSummary()) {
        if (!isGroupSummary(sbn)) {
            return false;
        }
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        NotificationGroup group = mGroupMap.get(getGroupKey(sbn));
        if (group == null) {
            return false;
        }
@@ -165,10 +166,10 @@ public class NotificationGroupManager {
     * @return whether a given notification is a child in a group which has a summary
     */
    public boolean isChildInGroupWithSummary(StatusBarNotification sbn) {
        if (!sbn.getNotification().isGroupChild()) {
        if (!isGroupChild(sbn)) {
            return false;
        }
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        NotificationGroup group = mGroupMap.get(getGroupKey(sbn));
        if (group == null || group.summary == null) {
            return false;
        }
@@ -179,10 +180,10 @@ public class NotificationGroupManager {
     * @return whether a given notification is a summary in a group which has children
     */
    public boolean isSummaryOfGroup(StatusBarNotification sbn) {
        if (!sbn.getNotification().isGroupSummary()) {
        if (!isGroupSummary(sbn)) {
            return false;
        }
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        NotificationGroup group = mGroupMap.get(getGroupKey(sbn));
        if (group == null) {
            return false;
        }
@@ -190,24 +191,88 @@ public class NotificationGroupManager {
    }

    public ExpandableNotificationRow getGroupSummary(StatusBarNotification sbn) {
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        NotificationGroup group = mGroupMap.get(getGroupKey(sbn));
        return group == null ? null
                : group.summary == null ? null
                : group.summary.row;
    }

    public void onEntryHeadsUped(NotificationData.Entry headsUp) {
        // TODO: handle this nicely
    }

    public void toggleGroupExpansion(StatusBarNotification sbn) {
        NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
        NotificationGroup group = mGroupMap.get(getGroupKey(sbn));
        if (group == null) {
            return;
        }
        setGroupExpanded(group, !group.expanded);
    }

    private boolean isIsolated(StatusBarNotification sbn) {
        return mHeadsUpedEntries.contains(sbn.getKey()) && sbn.getNotification().isGroupChild();
    }

    private boolean isGroupSummary(StatusBarNotification sbn) {
        if (isIsolated(sbn)) {
            return true;
        }
        return sbn.getNotification().isGroupSummary();
    }
    private boolean isGroupChild(StatusBarNotification sbn) {
        if (isIsolated(sbn)) {
            return false;
        }
        return sbn.getNotification().isGroupChild();
    }

    private String getGroupKey(StatusBarNotification sbn) {
        if (isIsolated(sbn)) {
            return sbn.getKey();
        }
        return sbn.getGroupKey();
    }

    @Override
    public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
    }

    @Override
    public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
    }

    @Override
    public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
    }

    @Override
    public void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
        final StatusBarNotification sbn = entry.notification;
        if (entry.row.isHeadsUp()) {
            if (!mHeadsUpedEntries.contains(sbn.getKey())) {
                final boolean groupChild = sbn.getNotification().isGroupChild();
                if (groupChild) {
                    // We will be isolated now, so lets update the groups
                    onEntryRemovedInternal(entry, entry.notification);
                }
                mHeadsUpedEntries.add(sbn.getKey());
                if (groupChild) {
                    onEntryAdded(entry);
                    mListener.onChildIsolationChanged();
                }
            }
        } else {
            if (mHeadsUpedEntries.contains(sbn.getKey())) {
                boolean isolatedBefore = isIsolated(sbn);
                if (isolatedBefore) {
                    // not isolated anymore, we need to update the groups
                    onEntryRemovedInternal(entry, entry.notification);
                }
                mHeadsUpedEntries.remove(sbn.getKey());
                if (isolatedBefore) {
                    onEntryAdded(entry);
                    mListener.onChildIsolationChanged();
                }
            }
        }
    }

    public static class NotificationGroup {
        public final HashSet<NotificationData.Entry> children = new HashSet<>();
        public NotificationData.Entry summary;
@@ -230,5 +295,10 @@ public class NotificationGroupManager {
         * @param group the group created
         */
        void onGroupCreatedFromChildren(NotificationGroup group);

        /**
         * The isolation of a child has changed i.e it's group changes.
         */
        void onChildIsolationChanged();
    }
}
+13 −3
Original line number Diff line number Diff line
@@ -707,6 +707,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        mHeadsUpManager.setBar(this);
        mHeadsUpManager.addListener(this);
        mHeadsUpManager.addListener(mNotificationPanel);
        mHeadsUpManager.addListener(mGroupManager);
        mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
        mNotificationData.setHeadsUpManager(mHeadsUpManager);

@@ -1408,16 +1409,21 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,

        }

        ArrayList<View> toRemove = new ArrayList<>();
        ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
        for (int i=0; i< mStackScroller.getChildCount(); i++) {
            View child = mStackScroller.getChildAt(i);
            if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
                toRemove.add(child);
                toRemove.add((ExpandableNotificationRow) child);
            }
        }

        for (View remove : toRemove) {
        for (ExpandableNotificationRow remove : toRemove) {
            if (mGroupManager.isChildInGroupWithSummary(remove.getStatusBarNotification())) {
                // we are only transfering this notification to its parent, don't generate an animation
                mStackScroller.setChildTransferInProgress(true);
            }
            mStackScroller.removeView(remove);
            mStackScroller.setChildTransferInProgress(false);
        }
        for (int i=0; i<toShow.size(); i++) {
            View v = toShow.get(i);
@@ -1573,6 +1579,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        mIconController.updateNotificationIcons(mNotificationData);
    }

    public void requestNotificationUpdate() {
        updateNotifications();
    }

    @Override
    protected void updateRowStates() {
        super.updateRowStates();
+0 −1
Original line number Diff line number Diff line
@@ -190,7 +190,6 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
        if (alert) {
            HeadsUpEntry headsUpEntry = mHeadsUpEntries.get(headsUp.key);
            headsUpEntry.updateEntry();
            mGroupManager.onEntryHeadsUped(headsUp);
            setEntryPinned(headsUpEntry, shouldHeadsUpBecomePinned(headsUp));
        }
    }
+12 −8
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ public class NotificationStackScrollLayout extends ViewGroup
    private final StackStateAnimator mStateAnimator = new StackStateAnimator(this);
    private boolean mAnimationsEnabled;
    private boolean mChangePositionInProgress;
    private boolean mChildTransferInProgress;

    /**
     * The raw amount of the overScroll on the top, which is not rubber-banded.
@@ -1632,12 +1633,16 @@ public class NotificationStackScrollLayout extends ViewGroup
        }
    }

    public void setChildTransferInProgress(boolean childTransferInProgress) {
        mChildTransferInProgress = childTransferInProgress;
    }

    @Override
    public void onViewRemoved(View child) {
        super.onViewRemoved(child);
        // we only call our internal methods if this is actually a removal and not just a
        // notification which becomes a child notification
        if (!isChildInGroup(child)) {
        if (!mChildTransferInProgress) {
            onViewRemovedInternal(child);
        }
    }
@@ -2819,13 +2824,12 @@ public class NotificationStackScrollLayout extends ViewGroup

    @Override
    public void onGroupCreatedFromChildren(NotificationGroupManager.NotificationGroup group) {
        for (NotificationData.Entry entry : group.children) {
            ExpandableNotificationRow row = entry.row;
            if (indexOfChild(row) != -1) {
                removeView(row);
                group.summary.row.addChildNotification(row);
            }
        mPhoneStatusBar.requestNotificationUpdate();
    }

    @Override
    public void onChildIsolationChanged() {
        mPhoneStatusBar.requestNotificationUpdate();
    }

    public void generateChildOrderChangedEvent() {
Loading