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

Commit 5755efb9 authored by Jeff DeCew's avatar Jeff DeCew Committed by Android (Google) Code Review
Browse files

Merge "Fix crash when adding a notification to a group while it is animating away."

parents ca77f562 b1085622
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -23,8 +23,10 @@ import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.FrameLayout;

import androidx.annotation.Nullable;
@@ -517,6 +519,36 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
        return mChangingPosition;
    }

    /**
     * Called before adding this view to a group, which would always throw an exception if this view
     * has a parent, so clean up the transient container and throw an exception if the parent isn't
     * a transient container.  Provide as much detail in the event of a crash as possible.
     */
    public void removeFromTransientContainerForAdditionTo(ViewGroup newParent) {
        final ViewParent parent = getParent();
        if (parent == null) {
            // If this view has no parent, the add will succeed, so do nothing.
            return;
        }
        ViewGroup transientContainer = getTransientContainer();
        if (transientContainer == null) {
            throw new IllegalStateException(
                    "Can't add view " + this + " to container " + newParent + "; current parent "
                            + parent + " is not a transient container");
        }
        if (transientContainer != parent) {
            throw new IllegalStateException(
                    "Expandable view " + this + " has transient container " + transientContainer
                            + " which is not the same as its parent " + parent);
        }
        if (parent != newParent) {
            Log.w(TAG, "Moving view " + this + " from transient container "
                    + transientContainer + " to parent " + newParent);
        }
        transientContainer.removeTransientView(this);
        setTransientContainer(null);
    }

    public void setTransientContainer(ViewGroup transientContainer) {
        mTransientContainer = transientContainer;
    }
+12 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import com.android.systemui.statusbar.notification.NotificationFadeAware;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.HybridGroupManager;
import com.android.systemui.statusbar.notification.row.HybridNotificationView;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
@@ -272,6 +273,7 @@ public class NotificationChildrenContainer extends ViewGroup
     * @param childIndex the index to add it at, if -1 it will be added at the end
     */
    public void addNotification(ExpandableNotificationRow row, int childIndex) {
        ensureRemovedFromTransientContainer(row);
        int newIndex = childIndex < 0 ? mAttachedChildren.size() : childIndex;
        mAttachedChildren.add(newIndex, row);
        addView(row);
@@ -291,6 +293,16 @@ public class NotificationChildrenContainer extends ViewGroup
        }
    }

    private void ensureRemovedFromTransientContainer(View v) {
        if (v.getParent() != null && v instanceof ExpandableView) {
            // If the child is animating away, it will still have a parent, so detach it first
            // TODO: We should really cancel the active animations here. This will
            //  happen automatically when the view's intro animation starts, but
            //  it's a fragile link.
            ((ExpandableView) v).removeFromTransientContainerForAdditionTo(this);
        }
    }

    public void removeNotification(ExpandableNotificationRow row) {
        int childIndex = mAttachedChildren.indexOf(row);
        mAttachedChildren.remove(row);
+3 −9
Original line number Diff line number Diff line
@@ -4655,18 +4655,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
    }

    private void ensureRemovedFromTransientContainer(View v) {
        if (v.getParent() == this && v instanceof ExpandableView) {
            ExpandableView expandableView = (ExpandableView) v;
            ViewGroup transientContainer = expandableView.getTransientContainer();
            // If the child is animating away, it will still have a parent, so
            // detach it first
        if (v.getParent() != null && v instanceof ExpandableView) {
            // If the child is animating away, it will still have a parent, so detach it first
            // TODO: We should really cancel the active animations here. This will
            //  happen automatically when the view's intro animation starts, but
            //  it's a fragile link.
            if (transientContainer != null) {
                transientContainer.removeTransientView(v);
                expandableView.setTransientContainer(null);
            }
            ((ExpandableView) v).removeFromTransientContainerForAdditionTo(this);
        }
    }