| Index: chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
|
| index b70c0ed6cce9b7be334c7424fcbb09da9c1ce199..78832c1fcebe35a9f8a5ce49543205101a7cbbef 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
|
| @@ -5,6 +5,7 @@
|
| package org.chromium.chrome.browser.ntp.cards;
|
|
|
| import org.chromium.base.Log;
|
| +import org.chromium.base.VisibleForTesting;
|
| import org.chromium.chrome.browser.ChromeFeatureList;
|
| import org.chromium.chrome.browser.ntp.snippets.CategoryInt;
|
| import org.chromium.chrome.browser.ntp.snippets.CategoryStatus;
|
| @@ -17,9 +18,13 @@
|
| import org.chromium.chrome.browser.suggestions.SuggestionsRanker;
|
| import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate;
|
|
|
| +import java.util.Arrays;
|
| +import java.util.HashSet;
|
| +import java.util.Iterator;
|
| import java.util.LinkedHashMap;
|
| import java.util.List;
|
| import java.util.Map;
|
| +import java.util.Set;
|
|
|
| /**
|
| * A node in the tree containing a list of all suggestions sections. It listens to changes in the
|
| @@ -31,6 +36,8 @@
|
|
|
| /** Maps suggestion categories to sections, with stable iteration ordering. */
|
| private final Map<Integer, SuggestionsSection> mSections = new LinkedHashMap<>();
|
| + /** List of categories that are hidden because they have no content to show. */
|
| + private final Set<Integer> mBlacklistedCategories = new HashSet<>();
|
| private final SuggestionsUiDelegate mUiDelegate;
|
| private final OfflinePageBridge mOfflinePageBridge;
|
| private final SuggestionsRanker mSuggestionsRanker;
|
| @@ -99,8 +106,11 @@ private int resetSection(@CategoryInt int category, @CategoryStatus int category
|
|
|
| // Do not show an empty section if not allowed.
|
| if (suggestions.isEmpty() && !info.showIfEmpty() && !alwaysAllowEmptySections) {
|
| + mBlacklistedCategories.add(category);
|
| if (section != null) removeSection(section);
|
| return 0;
|
| + } else {
|
| + mBlacklistedCategories.remove(category);
|
| }
|
|
|
| // Create the section if needed.
|
| @@ -145,6 +155,9 @@ public void onCategoryStatusChanged(@CategoryInt int category, @CategoryStatus i
|
| // Observers should not be registered for this state.
|
| assert status != CategoryStatus.ALL_SUGGESTIONS_EXPLICITLY_DISABLED;
|
|
|
| + // If the category was blacklisted, we note that there might be new content to show.
|
| + mBlacklistedCategories.remove(category);
|
| +
|
| // If there is no section for this category there is nothing to do.
|
| if (!mSections.containsKey(category)) return;
|
|
|
| @@ -225,12 +238,9 @@ public boolean isEmpty() {
|
| public void synchroniseWithSource() {
|
| int[] categories = mUiDelegate.getSuggestionsSource().getCategories();
|
|
|
| - // TODO(dgn): this naive implementation does not quite work as some sections are removed
|
| - // from the UI when they are empty, even though they stay around in the backend. Also, we
|
| - // might not always get notifications of new content for local sections.
|
| - // See https://crbug.com/711414, https://crbug.com/689962
|
| -
|
| if (categoriesChanged(categories)) {
|
| + Log.d(TAG, "The categories have changed: old=%s, new=%s - Resetting all the sections.",
|
| + mSections.keySet(), Arrays.toString(categories));
|
| // The number or the order of the sections changed. We reset everything.
|
| resetSections(/* alwaysAllowEmptySections = */ false);
|
| return;
|
| @@ -241,6 +251,7 @@ public void synchroniseWithSource() {
|
|
|
| @CategoryInt
|
| int category = sectionsEntry.getKey();
|
| + Log.d(TAG, "The section for category %d is stale - Resetting.", category);
|
| resetSection(category, mUiDelegate.getSuggestionsSource().getCategoryStatus(category),
|
| /* alwaysAllowEmptySections = */ false);
|
| }
|
| @@ -271,15 +282,19 @@ private void maybeHideArticlesHeader() {
|
| * Checks that the list of categories currently displayed by this list is the same as
|
| * {@code newCategories}: same categories in the same order.
|
| */
|
| - private boolean categoriesChanged(@CategoryInt int[] newCategories) {
|
| - if (mSections.size() != newCategories.length) return true;
|
| -
|
| - int index = 0;
|
| - for (@CategoryInt int category : mSections.keySet()) {
|
| - if (category != newCategories[index++]) return true;
|
| + @VisibleForTesting
|
| + boolean categoriesChanged(@CategoryInt int[] newCategories) {
|
| + Iterator<Integer> shownCategories = mSections.keySet().iterator();
|
| + for (int category : newCategories) {
|
| + if (mBlacklistedCategories.contains(category)) {
|
| + Log.d(TAG, "categoriesChanged: ignoring blacklisted category %d", category);
|
| + continue;
|
| + }
|
| + if (!shownCategories.hasNext()) return true;
|
| + if (shownCategories.next() != category) return true;
|
| }
|
|
|
| - return false;
|
| + return shownCategories.hasNext();
|
| }
|
|
|
| /**
|
| @@ -288,6 +303,9 @@ private boolean categoriesChanged(@CategoryInt int[] newCategories) {
|
| * compatible with displaying content.
|
| */
|
| private boolean canProcessSuggestions(@CategoryInt int category, @CategoryStatus int status) {
|
| + // If the category was blacklisted, we note that there might be new content to show.
|
| + mBlacklistedCategories.remove(category);
|
| +
|
| // We never want to add suggestions from unknown categories.
|
| if (!mSections.containsKey(category)) return false;
|
|
|
|
|