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

Commit 88f4dbce authored by Steve Elliott's avatar Steve Elliott
Browse files

Defer MessagingMessage#recycle until bind ends

See ag/17158486 for context.

Fixes: 216202070
Test: manual
Change-Id: I924f917fbf757d2c3866fcd60de2fbfccae2eb6a
parent 4bf10e42
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -66,7 +66,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;

/**
 * A custom-built layout for the Notification.MessagingStyle allows dynamic addition and removal
@@ -76,8 +75,6 @@ import java.util.function.Consumer;
public class ConversationLayout extends FrameLayout
        implements ImageMessageConsumer, IMessagingLayout {

    private static final Consumer<MessagingMessage> REMOVE_MESSAGE
            = MessagingMessage::removeMessage;
    public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
    public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
    public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
@@ -150,7 +147,7 @@ public class ConversationLayout extends FrameLayout
    private Icon mShortcutIcon;
    private View mAppNameDivider;
    private TouchDelegateComposite mTouchDelegate = new TouchDelegateComposite(this);
    private ArrayList<MessagingGroup> mToRecycle = new ArrayList<>();
    private ArrayList<MessagingLinearLayout.MessagingChild> mToRecycle = new ArrayList<>();

    public ConversationLayout(@NonNull Context context) {
        super(context);
@@ -463,8 +460,12 @@ public class ConversationLayout extends FrameLayout
        removeGroups(oldGroups);

        // Let's remove the remaining messages
        mMessages.forEach(REMOVE_MESSAGE);
        mHistoricMessages.forEach(REMOVE_MESSAGE);
        for (MessagingMessage message : mMessages) {
            message.removeMessage(mToRecycle);
        }
        for (MessagingMessage historicMessage : mHistoricMessages) {
            historicMessage.removeMessage(mToRecycle);
        }

        mMessages = messages;
        mHistoricMessages = historicMessages;
@@ -475,8 +476,8 @@ public class ConversationLayout extends FrameLayout
        updateConversationLayout();

        // Recycle everything at the end of the update, now that we know it's no longer needed.
        for (MessagingGroup group : mToRecycle) {
            group.recycle();
        for (MessagingLinearLayout.MessagingChild child : mToRecycle) {
            child.recycle();
        }
        mToRecycle.clear();
    }
+7 −7
Original line number Diff line number Diff line
@@ -262,7 +262,8 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
        return createdGroup;
    }

    public void removeMessage(MessagingMessage messagingMessage) {
    public void removeMessage(MessagingMessage messagingMessage,
            ArrayList<MessagingLinearLayout.MessagingChild> toRecycle) {
        View view = messagingMessage.getView();
        boolean wasShown = view.isShown();
        ViewGroup messageParent = (ViewGroup) view.getParent();
@@ -270,15 +271,14 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
            return;
        }
        messageParent.removeView(view);
        Runnable recycleRunnable = () -> {
            messageParent.removeTransientView(view);
            messagingMessage.recycle();
        };
        if (wasShown && !MessagingLinearLayout.isGone(view)) {
            messageParent.addTransientView(view, 0);
            performRemoveAnimation(view, recycleRunnable);
            performRemoveAnimation(view, () -> {
                messageParent.removeTransientView(view);
                messagingMessage.recycle();
            });
        } else {
            recycleRunnable.run();
            toRecycle.add(messagingMessage);
        }
    }

+18 −11
Original line number Diff line number Diff line
@@ -51,7 +51,6 @@ import com.android.internal.util.ContrastColorUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * A custom-built layout for the Notification.MessagingStyle allows dynamic addition and removal
@@ -62,8 +61,6 @@ public class MessagingLayout extends FrameLayout
        implements ImageMessageConsumer, IMessagingLayout {

    private static final float COLOR_SHIFT_AMOUNT = 60;
    private static final Consumer<MessagingMessage> REMOVE_MESSAGE
            = MessagingMessage::removeMessage;
    public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
    public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
    public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
@@ -89,6 +86,7 @@ public class MessagingLayout extends FrameLayout
    private boolean mIsCollapsed;
    private ImageResolver mImageResolver;
    private CharSequence mConversationTitle;
    private ArrayList<MessagingLinearLayout.MessagingChild> mToRecycle = new ArrayList<>();

    public MessagingLayout(@NonNull Context context) {
        super(context);
@@ -212,8 +210,12 @@ public class MessagingLayout extends FrameLayout
        removeGroups(oldGroups);

        // Let's remove the remaining messages
        mMessages.forEach(REMOVE_MESSAGE);
        mHistoricMessages.forEach(REMOVE_MESSAGE);
        for (MessagingMessage message : mMessages) {
            message.removeMessage(mToRecycle);
        }
        for (MessagingMessage historicMessage : mHistoricMessages) {
            historicMessage.removeMessage(mToRecycle);
        }

        mMessages = messages;
        mHistoricMessages = historicMessages;
@@ -223,6 +225,12 @@ public class MessagingLayout extends FrameLayout
        // after groups are finalized, hide the first sender name if it's showing as the title
        mPeopleHelper.maybeHideFirstSenderName(mGroups, mIsOneToOne, mConversationTitle);
        updateImageMessages();

        // Recycle everything at the end of the update, now that we know it's no longer needed.
        for (MessagingLinearLayout.MessagingChild child : mToRecycle) {
            child.recycle();
        }
        mToRecycle.clear();
    }

    private void updateImageMessages() {
@@ -263,18 +271,17 @@ public class MessagingLayout extends FrameLayout
            MessagingGroup group = oldGroups.get(i);
            if (!mGroups.contains(group)) {
                List<MessagingMessage> messages = group.getMessages();
                Runnable endRunnable = () -> {
                    mMessagingLinearLayout.removeTransientView(group);
                    group.recycle();
                };

                boolean wasShown = group.isShown();
                mMessagingLinearLayout.removeView(group);
                if (wasShown && !MessagingLinearLayout.isGone(group)) {
                    mMessagingLinearLayout.addTransientView(group, 0);
                    group.removeGroupAnimated(endRunnable);
                    group.removeGroupAnimated(() -> {
                        mMessagingLinearLayout.removeTransientView(group);
                        group.recycle();
                    });
                } else {
                    endRunnable.run();
                    mToRecycle.add(group);
                }
                mMessages.removeAll(messages);
                mHistoricMessages.removeAll(messages);
+1 −0
Original line number Diff line number Diff line
@@ -365,6 +365,7 @@ public class MessagingLinearLayout extends ViewGroup {
        default int getExtraSpacing() {
            return 0;
        }
        void recycle();
    }

    public static class LayoutParams extends MarginLayoutParams {
+3 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.app.ActivityManager;
import android.app.Notification;
import android.view.View;

import java.util.ArrayList;
import java.util.Objects;

/**
@@ -96,8 +97,8 @@ public interface MessagingMessage extends MessagingLinearLayout.MessagingChild {
        return sameAs(message.getMessage());
    }

    default void removeMessage() {
        getGroup().removeMessage(this);
    default void removeMessage(ArrayList<MessagingLinearLayout.MessagingChild> toRecycle) {
        getGroup().removeMessage(this, toRecycle);
    }

    default void setMessagingGroup(MessagingGroup group) {