| Index: chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
|
| index d0406d625ed5517fbf681827825046b9b4601ed0..e393cafc04fa1e8155fcffbc27b8ea47a4557c23 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
|
| @@ -45,12 +45,9 @@ public class SuggestionsSection extends InnerNode {
|
|
|
| private boolean mIsNtpDestroyed;
|
|
|
| - // Keep track of impressions of the suggestions so that we replace only suggestions that
|
| - // have not been impressed, yet. We keep track of the first suggestion separately as the
|
| - // first is often impressed in the form of a peeking card and we still want to be able to
|
| - // replace something in this case.
|
| - private boolean mFirstSuggestionSeen;
|
| - private boolean mSubsequentSuggestionsSeen;
|
| + // Keep track of how many suggestions have been seen by the user so that we replace only
|
| + // suggestions that have not been seen, yet.
|
| + private int mNumberOfSuggestionsSeen;
|
|
|
| /**
|
| * Delegate interface that allows dismissing this section without introducing
|
| @@ -136,13 +133,13 @@ public class SuggestionsSection extends InnerNode {
|
| }
|
|
|
| /**
|
| - * Clears all suggestions except the first one.
|
| + * Clears all suggestions except for the first {@code n} suggestions.
|
| */
|
| - private void clearAllButFirst() {
|
| + private void clearAllButFirstN(int n) {
|
| int itemCount = mSuggestions.size();
|
| - if (itemCount > 1) {
|
| - mSuggestions.subList(1, itemCount).clear();
|
| - notifyItemRangeRemoved(1, itemCount - 1);
|
| + if (itemCount > n) {
|
| + mSuggestions.subList(n, itemCount).clear();
|
| + notifyItemRangeRemoved(n, itemCount - 1);
|
| }
|
| }
|
|
|
| @@ -268,18 +265,15 @@ public class SuggestionsSection extends InnerNode {
|
| * @param position Position in the list being shown (the first suggestion being at index 1,
|
| * as at index 0, there is a non-suggestion).
|
| */
|
| - @VisibleForTesting
|
| - public void childSeen(int position) {
|
| + private void childSeen(int position) {
|
| Log.d(TAG, "childSeen: position %d in category %d", position, mCategoryInfo.getCategory());
|
| assert getStartingOffsetForChild(mSuggestionsList) == 1;
|
| + // We assume all non-snippet cards come after all cards of type SNIPPET.
|
| if (getItemViewType(position) == ItemViewType.SNIPPET) {
|
| - // We assume all non-snippet cards come after all cards of type SNIPPET.
|
| - int positionAmongSuggestions = position - 1;
|
| - if (positionAmongSuggestions == 0) {
|
| - mFirstSuggestionSeen = true;
|
| - } else if (positionAmongSuggestions > 0) {
|
| - mSubsequentSuggestionsSeen = true;
|
| - }
|
| + // As asserted above, first suggestion has position 1, etc., so the position of this
|
| + // child coincides with the number of suggestions above this child (including this one).
|
| + mNumberOfSuggestionsSeen =
|
| + Math.max(mNumberOfSuggestionsSeen, position);
|
| }
|
| }
|
|
|
| @@ -332,26 +326,34 @@ public class SuggestionsSection extends InnerNode {
|
|
|
| // Remove suggestions to be replaced.
|
| if (replaceExisting && hasSuggestions()) {
|
| - if (CardsVariationParameters.ignoreUpdatesForExistingSuggestions()
|
| - || mSubsequentSuggestionsSeen) {
|
| - Log.d(TAG, "setSuggestions: replacing existing suggestion not possible");
|
| + if (CardsVariationParameters.ignoreUpdatesForExistingSuggestions()) {
|
| + Log.d(TAG, "setSuggestions: replacing existing suggestion disabled");
|
| return;
|
| }
|
|
|
| - if (mFirstSuggestionSeen) {
|
| - Log.d(TAG, "setSuggestions: keeping the first suggestion");
|
| - mSuggestionsList.clearAllButFirst();
|
| + if (mNumberOfSuggestionsSeen >= getSuggestionsCount()) {
|
| + Log.d(TAG, "setSuggestions: replacing existing suggestion not possible, all seen");
|
| + return;
|
| + }
|
|
|
| - // Make sure that {@code mSuggestionsList} will contain as many elements as newly
|
| - // provided in {@code suggestions}. Remove the kept first element from the new
|
| - // collection, if it repeats there. Otherwise, remove the last element of the new
|
| - // collection.
|
| - if (!suggestions.remove(mSuggestionsList.getSuggestionAt(0))) {
|
| - suggestions.remove(suggestions.size() - 1);
|
| + Log.d(TAG, "setSuggestions: keeping the first %d suggestion",
|
| + mNumberOfSuggestionsSeen);
|
| + mSuggestionsList.clearAllButFirstN(mNumberOfSuggestionsSeen);
|
| +
|
| + if (mNumberOfSuggestionsSeen > 0) {
|
| + // Make sure that mSuggestionsList will contain as many elements as newly provided
|
| + // in suggestions. Remove the kept first element from the new collection, if it
|
| + // repeats there. Otherwise, remove the last element of the new collection.
|
| + int targetCountToAppend =
|
| + Math.max(0, suggestions.size() - mNumberOfSuggestionsSeen);
|
| + for (SnippetArticle suggestion : mSuggestionsList) {
|
| + suggestions.remove(suggestion);
|
| + }
|
| + if (suggestions.size() > targetCountToAppend) {
|
| + Log.d(TAG, "setSuggestions: removing %d excess elements from the end",
|
| + suggestions.size() - targetCountToAppend);
|
| + suggestions.subList(targetCountToAppend, suggestions.size()).clear();
|
| }
|
| - } else {
|
| - Log.d(TAG, "setSuggestions: removing all suggestions");
|
| - mSuggestionsList.clear();
|
| }
|
| }
|
|
|
|
|