Chromium Code Reviews| Index: components/offline_pages/content/suggested_articles_observer.cc |
| diff --git a/components/offline_pages/content/suggested_articles_observer.cc b/components/offline_pages/content/suggested_articles_observer.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..bfce5968c958b5ea75e31963138e27c612042649 |
| --- /dev/null |
| +++ b/components/offline_pages/content/suggested_articles_observer.cc |
| @@ -0,0 +1,148 @@ |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "components/offline_pages/content/suggested_articles_observer.h" |
| + |
| +#include <unordered_set> |
| + |
| +#include "base/memory/ptr_util.h" |
| +#include "components/ntp_snippets/category.h" |
| +#include "components/ntp_snippets/category_status.h" |
| +#include "components/offline_pages/content/prefetch_service_factory.h" |
| +#include "components/offline_pages/core/client_namespace_constants.h" |
| +#include "components/offline_pages/core/offline_page_feature.h" |
| +#include "components/offline_pages/core/prefetch/prefetch_service_impl.h" |
| + |
| +using ntp_snippets::Category; |
| +using ntp_snippets::ContentSuggestion; |
| + |
| +namespace offline_pages { |
| + |
| +namespace { |
| + |
| +int kOfflinePageSuggestedArticlesObserverUserDataKey; |
| + |
| +const ntp_snippets::Category& ArticlesCategory() { |
| + static ntp_snippets::Category articles = |
| + Category::FromKnownCategory(ntp_snippets::KnownCategories::ARTICLES); |
| + return articles; |
| +} |
| + |
| +ClientId CreateClientIDFromSuggestionId(const ContentSuggestion::ID& id) { |
| + return ClientId(kSuggestedArticlesNamespace, id.id_within_category()); |
| +} |
| + |
| +// The default delegate that contains external dependencies for the Offline Page |
| +// Suggestions Observer. This is unused in tests, which implement their own |
| +// Delegate. |
| +class DefaultDelegate : public SuggestedArticlesObserver::Delegate { |
| + public: |
| + explicit DefaultDelegate(ntp_snippets::ContentSuggestionsService* service); |
| + ~DefaultDelegate() override = default; |
| + |
| + const std::vector<ContentSuggestion>& GetSuggestions( |
| + const Category& category) override; |
| + PrefetchService* GetPrefetchService( |
| + content::BrowserContext* context) override; |
| + |
| + private: |
| + ntp_snippets::ContentSuggestionsService* service_; |
| +}; |
| + |
| +DefaultDelegate::DefaultDelegate( |
| + ntp_snippets::ContentSuggestionsService* service) |
| + : service_(service) {} |
| + |
| +const std::vector<ContentSuggestion>& DefaultDelegate::GetSuggestions( |
| + const Category& category) { |
| + return service_->GetSuggestionsForCategory(category); |
| +} |
| + |
| +PrefetchService* DefaultDelegate::GetPrefetchService( |
| + content::BrowserContext* context) { |
| + return PrefetchServiceFactory::GetForBrowserContext(context); |
| +} |
| + |
| +} // namespace |
| + |
| +// static |
| +void SuggestedArticlesObserver::ObserveContentSuggestionsService( |
| + content::BrowserContext* browser_context, |
| + ntp_snippets::ContentSuggestionsService* service) { |
| + if (!offline_pages::IsPrefetchingOfflinePagesEnabled()) |
| + return; |
| + |
| + auto suggestions_observer = base::MakeUnique<SuggestedArticlesObserver>( |
| + browser_context, base::MakeUnique<DefaultDelegate>(service)); |
| + service->AddObserver(suggestions_observer.get()); |
| + service->SetUserData( |
| + &kOfflinePageSuggestedArticlesObserverUserDataKey, |
| + // Note that |service| will take ownership of suggestions_observer |
| + // despite accepting a raw pointer. |
| + suggestions_observer.release()); |
| +} |
| + |
| +SuggestedArticlesObserver::SuggestedArticlesObserver( |
| + content::BrowserContext* browser_context, |
| + std::unique_ptr<Delegate> delegate) |
| + : browser_context_(browser_context), delegate_(std::move(delegate)) {} |
| + |
| +SuggestedArticlesObserver::~SuggestedArticlesObserver() = default; |
| + |
| +void SuggestedArticlesObserver::OnNewSuggestions(Category category) { |
| + if (category != ArticlesCategory() || |
|
jkrcal
2017/04/21 13:57:06
This special-casing to KnownCategories::ARTICLES i
dewittj
2017/04/21 21:59:04
Done.
|
| + category_status_ != ntp_snippets::CategoryStatus::AVAILABLE) { |
| + return; |
| + } |
| + |
| + const std::vector<ContentSuggestion>& suggestions = |
| + delegate_->GetSuggestions(ArticlesCategory()); |
| + if (suggestions.empty()) |
| + return; |
| + |
| + std::vector<PrefetchService::PrefetchURL> prefetch_urls; |
| + for (const ContentSuggestion& suggestion : suggestions) { |
| + prefetch_urls.push_back( |
| + {CreateClientIDFromSuggestionId(suggestion.id()), suggestion.url()}); |
| + } |
| + |
| + PrefetchService* service = delegate_->GetPrefetchService(browser_context_); |
|
jkrcal
2017/04/21 13:57:07
Shouldn't you check for nullptr?
Does the factory
dewittj
2017/04/21 21:59:04
Done.
|
| + service->AddCandidatePrefetchURLs(prefetch_urls); |
| +} |
| + |
| +void SuggestedArticlesObserver::OnCategoryStatusChanged( |
| + Category category, |
| + ntp_snippets::CategoryStatus new_status) { |
| + if (category != ArticlesCategory() || category_status_ == new_status) |
| + return; |
| + |
| + category_status_ = new_status; |
| + |
| + if (category_status_ == |
| + ntp_snippets::CategoryStatus::CATEGORY_EXPLICITLY_DISABLED || |
| + category_status_ == |
| + ntp_snippets::CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED) { |
| + PrefetchService* service = delegate_->GetPrefetchService(browser_context_); |
|
jkrcal
2017/04/21 13:57:07
ditto
dewittj
2017/04/21 21:59:04
Done.
|
| + service->RemoveAllUnprocessedPrefetchURLs(kSuggestedArticlesNamespace); |
| + } |
| +} |
| + |
| +void SuggestedArticlesObserver::OnSuggestionInvalidated( |
| + const ContentSuggestion::ID& suggestion_id) { |
| + PrefetchService* service = delegate_->GetPrefetchService(browser_context_); |
| + service->RemovePrefetchURLsByClientId( |
| + CreateClientIDFromSuggestionId(suggestion_id)); |
| +} |
| + |
| +void SuggestedArticlesObserver::OnFullRefreshRequired() { |
| + PrefetchService* service = delegate_->GetPrefetchService(browser_context_); |
| + service->RemoveAllUnprocessedPrefetchURLs(kSuggestedArticlesNamespace); |
| + OnNewSuggestions(ArticlesCategory()); |
| +} |
| + |
| +void SuggestedArticlesObserver::ContentSuggestionsServiceShutdown() { |
| + // No need to do anything here, we will just stop getting events. |
| +} |
| + |
| +} // namespace offline_pages |