Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/android/offline_pages/offline_page_suggestions_observer .h" | |
| 6 | |
| 7 #include <unordered_set> | |
| 8 | |
| 9 #include "base/threading/thread_task_runner_handle.h" | |
| 10 #include "chrome/browser/android/offline_pages/prefetch_service_factory.h" | |
| 11 #include "components/ntp_snippets/category.h" | |
| 12 #include "components/ntp_snippets/category_status.h" | |
| 13 #include "components/offline_pages/core/offline_page_model.h" | |
| 14 #include "components/offline_pages/core/offline_page_model_query.h" | |
| 15 #include "components/offline_pages/core/prefetch/prefetch_service_impl.h" | |
| 16 | |
| 17 namespace offline_pages { | |
| 18 | |
| 19 int kOfflinePageSuggestionsObserverUserDataKey; | |
|
carlosk
2017/04/11 17:31:35
Where is this initialized?
dewittj
2017/04/11 21:25:48
Nowhere, its address is used for KeyedService purp
| |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 // The default delegate that contains external dependencies for the Offline Page | |
| 24 // Suggestions Observer. This is unused in tests. | |
|
carlosk
2017/04/11 17:31:36
nit: s/unused/replaced/
dewittj
2017/04/11 21:25:48
DefaultDelegate is unused :) Reworded.
| |
| 25 class DefaultDelegate : public OfflinePageSuggestionsObserver::Delegate { | |
| 26 public: | |
| 27 DefaultDelegate(offline_pages::OfflinePageModel* offline_page_model, | |
| 28 ntp_snippets::ContentSuggestionsService* service, | |
| 29 const ntp_snippets::Category& category); | |
| 30 ~DefaultDelegate() override = default; | |
| 31 | |
| 32 std::vector<GURL> GetSuggestionURLs() override; | |
| 33 void GetPagesWithURLs( | |
| 34 const std::vector<GURL>& suggestion_urls, | |
| 35 const MultipleOfflinePageItemCallback& callback) override; | |
| 36 | |
| 37 private: | |
| 38 offline_pages::OfflinePageModel* offline_page_model_; | |
| 39 ntp_snippets::ContentSuggestionsService* service_; | |
| 40 ntp_snippets::Category category_; | |
| 41 }; | |
| 42 | |
| 43 DefaultDelegate::DefaultDelegate( | |
| 44 offline_pages::OfflinePageModel* offline_page_model, | |
| 45 ntp_snippets::ContentSuggestionsService* service, | |
| 46 const ntp_snippets::Category& category) | |
| 47 : offline_page_model_(offline_page_model), | |
| 48 service_(service), | |
| 49 category_(category) {} | |
| 50 | |
| 51 std::vector<GURL> DefaultDelegate::GetSuggestionURLs() { | |
| 52 std::vector<GURL> suggestion_urls; | |
| 53 for (const auto& suggestion : | |
|
carlosk
2017/04/11 17:31:35
nit: explicitly mentioning ContentSuggestion here
dewittj
2017/04/11 21:25:48
Done.
| |
| 54 service_->GetSuggestionsForCategory(category_)) { | |
| 55 suggestion_urls.emplace_back(suggestion.url()); | |
| 56 } | |
| 57 return suggestion_urls; | |
| 58 } | |
| 59 | |
| 60 void DefaultDelegate::GetPagesWithURLs( | |
| 61 const std::vector<GURL>& suggestion_urls, | |
| 62 const MultipleOfflinePageItemCallback& callback) { | |
| 63 OfflinePageModelQueryBuilder builder; | |
| 64 builder.SetUrls(OfflinePageModelQuery::Requirement::INCLUDE_MATCHING, | |
| 65 suggestion_urls); | |
| 66 offline_page_model_->GetPagesMatchingQuery( | |
| 67 builder.Build(offline_page_model_->GetPolicyController()), callback); | |
| 68 } | |
| 69 | |
| 70 } // namespace | |
| 71 | |
| 72 // static | |
| 73 void OfflinePageSuggestionsObserver::ObserveContentSuggestionsService( | |
| 74 content::BrowserContext* browser_context, | |
| 75 offline_pages::OfflinePageModel* offline_page_model, | |
| 76 ntp_snippets::ContentSuggestionsService* service) { | |
| 77 auto category = ntp_snippets::Category::FromKnownCategory( | |
| 78 ntp_snippets::KnownCategories::ARTICLES); | |
| 79 auto suggestions_observer = base::MakeUnique<OfflinePageSuggestionsObserver>( | |
| 80 browser_context, | |
| 81 base::MakeUnique<DefaultDelegate>(offline_page_model, service, category), | |
| 82 category); | |
| 83 service->AddObserver(suggestions_observer.get()); | |
| 84 service->SetUserData(&kOfflinePageSuggestionsObserverUserDataKey, | |
| 85 suggestions_observer.release()); | |
| 86 } | |
| 87 | |
| 88 OfflinePageSuggestionsObserver::OfflinePageSuggestionsObserver( | |
| 89 content::BrowserContext* browser_context, | |
| 90 std::unique_ptr<Delegate> delegate, | |
| 91 const ntp_snippets::Category& category) | |
| 92 : delegate_(std::move(delegate)), | |
| 93 browser_context_(browser_context), | |
| 94 category_(category), | |
| 95 weak_ptr_factory_(this) {} | |
| 96 | |
| 97 OfflinePageSuggestionsObserver::~OfflinePageSuggestionsObserver() = default; | |
| 98 | |
| 99 void OfflinePageSuggestionsObserver::OnNewSuggestions( | |
| 100 ntp_snippets::Category category) { | |
| 101 if (category != category_ || | |
| 102 category_status_ != ntp_snippets::CategoryStatus::AVAILABLE) { | |
| 103 return; | |
| 104 } | |
| 105 | |
| 106 // If we get suggestions while processing other suggestions, just cancel those | |
| 107 // operations and restart anew. | |
| 108 weak_ptr_factory_.InvalidateWeakPtrs(); | |
| 109 | |
| 110 std::vector<GURL> suggestion_urls = delegate_->GetSuggestionURLs(); | |
| 111 delegate_->GetPagesWithURLs( | |
| 112 suggestion_urls, | |
| 113 base::Bind(&OfflinePageSuggestionsObserver::GotPagesMatchingSuggestions, | |
| 114 weak_ptr_factory_.GetWeakPtr(), suggestion_urls)); | |
| 115 } | |
| 116 | |
| 117 void OfflinePageSuggestionsObserver::OnCategoryStatusChanged( | |
| 118 ntp_snippets::Category category, | |
| 119 ntp_snippets::CategoryStatus new_status) { | |
| 120 if (category != category_) | |
| 121 return; | |
| 122 | |
| 123 category_status_ = new_status; | |
| 124 | |
| 125 if (category_status_ == | |
| 126 ntp_snippets::CategoryStatus::CATEGORY_EXPLICITLY_DISABLED || | |
| 127 category_status_ == | |
| 128 ntp_snippets::CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED) { | |
| 129 PrefetchService* service = | |
| 130 PrefetchServiceFactory::GetForBrowserContext(browser_context_); | |
| 131 service->RemoveAllUnprocessedURLSuggestions(); | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 void OfflinePageSuggestionsObserver::OnSuggestionInvalidated( | |
| 136 const ntp_snippets::ContentSuggestion::ID& suggestion_id) { | |
| 137 // TODO(dewittj): Keep track of ContentSuggestion::IDs so we can invalidate | |
| 138 // suggestions as well. | |
| 139 NOTIMPLEMENTED(); | |
| 140 } | |
| 141 | |
| 142 void OfflinePageSuggestionsObserver::OnFullRefreshRequired() { | |
| 143 PrefetchService* service = | |
| 144 PrefetchServiceFactory::GetForBrowserContext(browser_context_); | |
| 145 service->RemoveAllUnprocessedURLSuggestions(); | |
|
carlosk
2017/04/11 17:31:35
From reading the doc on this observer method [1] i
dewittj
2017/04/11 21:25:48
Done.
| |
| 146 } | |
| 147 | |
| 148 void OfflinePageSuggestionsObserver::ContentSuggestionsServiceShutdown() { | |
| 149 // No need to do anything here, we will just stop getting events. | |
| 150 } | |
| 151 | |
| 152 void OfflinePageSuggestionsObserver::GotPagesMatchingSuggestions( | |
| 153 const std::vector<GURL>& suggestion_urls, | |
| 154 const MultipleOfflinePageItemResult& pages) { | |
| 155 std::set<GURL> result_gurls; | |
| 156 result_gurls.insert(suggestion_urls.begin(), suggestion_urls.end()); | |
| 157 for (const auto& page : pages) { | |
|
Dmitry Titov
2017/04/11 01:17:13
That seems too strict. What if a user manually dow
carlosk
2017/04/11 17:31:35
I think the main point here is not re-downloading
dewittj
2017/04/11 21:25:48
Maybe it is premature to do the offline page filte
| |
| 158 result_gurls.erase(page.url); | |
| 159 result_gurls.erase(page.original_url); | |
| 160 } | |
| 161 | |
| 162 PrefetchService* service = | |
| 163 PrefetchServiceFactory::GetForBrowserContext(browser_context_); | |
| 164 service->OnNewURLSuggestions( | |
| 165 std::vector<GURL>(result_gurls.begin(), result_gurls.end())); | |
| 166 } | |
| 167 | |
| 168 } // namespace offline_pages | |
| OLD | NEW |