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

Commit 29aaf624 authored by Fan Zhang's avatar Fan Zhang
Browse files

Only replace updated cards after loading from db.

There are currently 2 ways a list of contextual cards can be updated:
1. through loader onFinishLoading
2. onContextualCardUpdated

We need to make the data handling logic consistent between the 2 paths.

Also changed some loops to stream for simplicity.

Change-Id: I242732e180a14092f5745271e5f63c18a6e482e0
Fixes: 115572494
Test: robotests
parent 0f8536b0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -33,10 +33,10 @@ public class ContextualCard {
    /**
     * Flags indicating the type of the ContextualCard.
     */
    @IntDef({CardType.INVALID, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL})
    @IntDef({CardType.DEFAULT, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL})
    @Retention(RetentionPolicy.SOURCE)
    public @interface CardType {
        int INVALID = -1;
        int DEFAULT = 0;
        int SLICE = 1;
        int SUGGESTION = 2;
        int CONDITIONAL = 3;
+33 −32
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * This is a centralized manager of multiple {@link ContextualCardController}.
@@ -58,13 +60,15 @@ public class ContextualCardManager implements CardContentLoader.CardContentLoade
    private final ControllerRendererPool mControllerRendererPool;
    private final Lifecycle mLifecycle;
    private final List<ContextualCard> mContextualCards;
    private final List<LifecycleObserver> mLifecycleObservers;

    private ContextualCardUpdateListener mListener;

    public ContextualCardManager(Context context, Lifecycle lifecycle) {
    public ContextualCardManager(Context context, @NonNull Lifecycle lifecycle) {
        mContext = context;
        mLifecycle = lifecycle;
        mContextualCards = new ArrayList<>();
        mLifecycleObservers = new ArrayList<>();
        mControllerRendererPool = new ControllerRendererPool();
        //for data provided by Settings
        for (int cardType : SETTINGS_CARDS) {
@@ -81,12 +85,10 @@ public class ContextualCardManager implements CardContentLoader.CardContentLoade
    }

    private void loadCardControllers() {
        if (mContextualCards != null) {
        for (ContextualCard card : mContextualCards) {
            setupController(card.getCardType());
        }
    }
    }

    private void setupController(int cardType) {
        final ContextualCardController controller = mControllerRendererPool.getController(mContext,
@@ -96,53 +98,52 @@ public class ContextualCardManager implements CardContentLoader.CardContentLoade
            return;
        }
        controller.setCardUpdateListener(this);
        if (controller instanceof LifecycleObserver) {
            if (mLifecycle != null) {
        if (controller instanceof LifecycleObserver && !mLifecycleObservers.contains(controller)) {
            mLifecycleObservers.add((LifecycleObserver) controller);
            mLifecycle.addObserver((LifecycleObserver) controller);
        }
    }
    }

    //TODO(b/111822376): implement sorting mechanism.
    private void sortCards() {
    private void sortCards(List<ContextualCard> cards) {
        //take mContextualCards as the source and do the ranking based on the rule.
    }

    @Override
    public void onContextualCardUpdated(int cardType, List<ContextualCard> updateList) {
    public void onContextualCardUpdated(List<ContextualCard> updateList) {
        //TODO(b/112245748): Should implement a DiffCallback.
        //Keep the old list for comparison.
        final List<ContextualCard> prevCards = mContextualCards;

        //Remove the existing data that matches the certain cardType so as to insert the new data.
        for (int i = mContextualCards.size() - 1; i >= 0; i--) {
            if (mContextualCards.get(i).getCardType() == cardType) {
                mContextualCards.remove(i);
            }
        }

        //Append the new data
        mContextualCards.addAll(updateList);
        final Set<Integer> cardTypes = updateList
                .stream()
                .map(card -> card.getCardType())
                .collect(Collectors.toSet());
        //Remove the existing data that matches the certain cardType before inserting new data.
        final List<ContextualCard> cardsToKeep = mContextualCards
                .stream()
                .filter(card -> !cardTypes.contains(card.getCardType()))
                .collect(Collectors.toList());
        final List<ContextualCard> allCards = new ArrayList<>();
        allCards.addAll(cardsToKeep);
        allCards.addAll(updateList);

        sortCards(allCards);

        //replace with the new data
        mContextualCards.clear();
        mContextualCards.addAll(allCards);

        sortCards();
        loadCardControllers();

        if (mListener != null) {
            mListener.onContextualCardUpdated(ContextualCard.CardType.INVALID, mContextualCards);
            mListener.onContextualCardUpdated(mContextualCards);
        }
    }

    @Override
    public void onFinishCardLoading(List<ContextualCard> contextualCards) {
        mContextualCards.clear();
        if (contextualCards != null) {
            mContextualCards.addAll(contextualCards);
        }

        //Force card sorting here in case CardControllers of custom view have nothing to update
        // for the first launch.
        sortCards();

        loadCardControllers();
        onContextualCardUpdated(contextualCards);
    }

    void setListener(ContextualCardUpdateListener listener) {
+1 −1
Original line number Diff line number Diff line
@@ -27,5 +27,5 @@ import java.util.List;
 * ContextualCardsAdapter} in this case.
 */
public interface ContextualCardUpdateListener {
    void onContextualCardUpdated(int cardType, List<ContextualCard> updateList);
    void onContextualCardUpdated(List<ContextualCard> updateList);
}
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -101,7 +101,7 @@ public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.Vi
    }

    @Override
    public void onContextualCardUpdated(int cardType, List<ContextualCard> contextualCards) {
    public void onContextualCardUpdated(List<ContextualCard> contextualCards) {
        //TODO(b/112245748): Should implement a DiffCallback so we can use notifyItemChanged()
        // instead.
        if (contextualCards == null) {
+1 −1
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ public class ConditionContextualCardController implements ContextualCardControll

    @Override
    public void onDataUpdated(List<ContextualCard> cardList) {
        mListener.onContextualCardUpdated(getCardType(), cardList);
        mListener.onContextualCardUpdated(cardList);
    }

    @Override