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 |