Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(593)

Side by Side Diff: components/ntp_snippets/physical_web_pages/physical_web_page_suggestions_provider.cc

Issue 2669533002: [NTP::PhysicalWeb] In OnLost invalidate by |resolved_url|. (Closed)
Patch Set: treib@ comments. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/ntp_snippets/physical_web_pages/physical_web_page_suggestio ns_provider.h" 5 #include "components/ntp_snippets/physical_web_pages/physical_web_page_suggestio ns_provider.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 gfx::Image::CreateFrom1xPNGBytes( 145 gfx::Image::CreateFrom1xPNGBytes(
146 reinterpret_cast<const unsigned char*>(raw_data.data()), 146 reinterpret_cast<const unsigned char*>(raw_data.data()),
147 raw_data.size()))); 147 raw_data.size())));
148 } 148 }
149 149
150 void PhysicalWebPageSuggestionsProvider::Fetch( 150 void PhysicalWebPageSuggestionsProvider::Fetch(
151 const Category& category, 151 const Category& category,
152 const std::set<std::string>& known_suggestion_ids, 152 const std::set<std::string>& known_suggestion_ids,
153 const FetchDoneCallback& callback) { 153 const FetchDoneCallback& callback) {
154 DCHECK_EQ(category, provided_category_); 154 DCHECK_EQ(category, provided_category_);
155 std::vector<ContentSuggestion> suggestions =
156 GetMostRecentPhysicalWebPagesWithFilter(kMaxSuggestionsCount,
157 known_suggestion_ids);
158 AppendToShownScannedUrls(suggestions);
155 base::ThreadTaskRunnerHandle::Get()->PostTask( 159 base::ThreadTaskRunnerHandle::Get()->PostTask(
156 FROM_HERE, 160 FROM_HERE, base::Bind(callback, Status::Success(),
157 base::Bind(callback, Status::Success(), 161 base::Passed(std::move(suggestions))));
158 base::Passed(GetMostRecentPhysicalWebPagesWithFilter(
159 kMaxSuggestionsCount, known_suggestion_ids))));
160 } 162 }
161 163
162 void PhysicalWebPageSuggestionsProvider::ClearHistory( 164 void PhysicalWebPageSuggestionsProvider::ClearHistory(
163 base::Time begin, 165 base::Time begin,
164 base::Time end, 166 base::Time end,
165 const base::Callback<bool(const GURL& url)>& filter) { 167 const base::Callback<bool(const GURL& url)>& filter) {
166 ClearDismissedSuggestionsForDebugging(provided_category_); 168 ClearDismissedSuggestionsForDebugging(provided_category_);
167 } 169 }
168 170
169 void PhysicalWebPageSuggestionsProvider::ClearCachedSuggestions( 171 void PhysicalWebPageSuggestionsProvider::ClearCachedSuggestions(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 CategoryStatus new_status) { 210 CategoryStatus new_status) {
209 if (category_status_ == new_status) { 211 if (category_status_ == new_status) {
210 return; 212 return;
211 } 213 }
212 category_status_ = new_status; 214 category_status_ = new_status;
213 observer()->OnCategoryStatusChanged(this, provided_category_, new_status); 215 observer()->OnCategoryStatusChanged(this, provided_category_, new_status);
214 } 216 }
215 217
216 void PhysicalWebPageSuggestionsProvider::FetchPhysicalWebPages() { 218 void PhysicalWebPageSuggestionsProvider::FetchPhysicalWebPages() {
217 DCHECK_EQ(CategoryStatus::AVAILABLE, category_status_); 219 DCHECK_EQ(CategoryStatus::AVAILABLE, category_status_);
220 std::vector<ContentSuggestion> suggestions =
221 GetMostRecentPhysicalWebPagesWithFilter(
222 kMaxSuggestionsCount,
223 /*excluded_ids=*/std::set<std::string>());
224 shown_resolved_urls_by_scanned_url_.clear();
225 AppendToShownScannedUrls(suggestions);
218 observer()->OnNewSuggestions(this, provided_category_, 226 observer()->OnNewSuggestions(this, provided_category_,
219 GetMostRecentPhysicalWebPagesWithFilter( 227 std::move(suggestions));
220 kMaxSuggestionsCount,
221 /*excluded_ids=*/std::set<std::string>()));
222 } 228 }
223 229
224 std::vector<ContentSuggestion> 230 std::vector<ContentSuggestion>
225 PhysicalWebPageSuggestionsProvider::GetMostRecentPhysicalWebPagesWithFilter( 231 PhysicalWebPageSuggestionsProvider::GetMostRecentPhysicalWebPagesWithFilter(
226 int max_quantity, 232 int max_count,
227 const std::set<std::string>& excluded_ids) { 233 const std::set<std::string>& excluded_ids) {
228 std::unique_ptr<physical_web::MetadataList> page_metadata_list = 234 std::unique_ptr<physical_web::MetadataList> page_metadata_list =
229 physical_web_data_source_->GetMetadataList(); 235 physical_web_data_source_->GetMetadataList();
230 236
231 // These is to filter out dismissed suggestions and at the same time prune the 237 // These is to filter out dismissed suggestions and at the same time prune the
232 // dismissed IDs list removing nonavailable pages (this is need since some 238 // dismissed IDs list removing nonavailable pages (this is needed since some
233 // OnLost() calls may have been missed). 239 // OnLost() calls may have been missed).
234 const std::set<std::string> old_dismissed_ids = ReadDismissedIDsFromPrefs(); 240 const std::set<std::string> old_dismissed_ids = ReadDismissedIDsFromPrefs();
235 std::set<std::string> new_dismissed_ids; 241 std::set<std::string> new_dismissed_ids;
236 physical_web::MetadataList filtered_metadata_list; 242 physical_web::MetadataList filtered_metadata_list;
237 for (const auto& page_metadata : *page_metadata_list) { 243 for (const auto& page_metadata : *page_metadata_list) {
238 const std::string page_id = GetPageId(page_metadata); 244 const std::string page_id = GetPageId(page_metadata);
239 if (!excluded_ids.count(page_id) && !old_dismissed_ids.count(page_id)) { 245 if (!excluded_ids.count(page_id) && !old_dismissed_ids.count(page_id)) {
240 filtered_metadata_list.push_back(page_metadata); 246 filtered_metadata_list.push_back(page_metadata);
241 } 247 }
242 248
243 if (old_dismissed_ids.count(page_id)) { 249 if (old_dismissed_ids.count(page_id)) {
244 new_dismissed_ids.insert(page_id); 250 new_dismissed_ids.insert(page_id);
245 } 251 }
246 } 252 }
247 253
248 if (old_dismissed_ids.size() != new_dismissed_ids.size()) { 254 if (old_dismissed_ids.size() != new_dismissed_ids.size()) {
249 StoreDismissedIDsToPrefs(new_dismissed_ids); 255 StoreDismissedIDsToPrefs(new_dismissed_ids);
250 } 256 }
251 257
252 FilterOutByGroupId(filtered_metadata_list); 258 FilterOutByGroupId(filtered_metadata_list);
253 259
254 std::sort(filtered_metadata_list.begin(), filtered_metadata_list.end(), 260 std::sort(filtered_metadata_list.begin(), filtered_metadata_list.end(),
255 CompareByDistance); 261 CompareByDistance);
256 262
257 std::vector<ContentSuggestion> suggestions; 263 std::vector<ContentSuggestion> suggestions;
258 for (const auto& page_metadata : filtered_metadata_list) { 264 for (const auto& page_metadata : filtered_metadata_list) {
259 if (static_cast<int>(suggestions.size()) == max_quantity) { 265 if (static_cast<int>(suggestions.size()) == max_count) {
260 break; 266 break;
261 } 267 }
262 suggestions.push_back(ConvertPhysicalWebPage(page_metadata)); 268 suggestions.push_back(ConvertPhysicalWebPage(page_metadata));
263 } 269 }
264 270
265 return suggestions; 271 return suggestions;
266 } 272 }
267 273
268 ContentSuggestion PhysicalWebPageSuggestionsProvider::ConvertPhysicalWebPage( 274 ContentSuggestion PhysicalWebPageSuggestionsProvider::ConvertPhysicalWebPage(
269 const physical_web::Metadata& page) const { 275 const physical_web::Metadata& page) const {
270 ContentSuggestion suggestion(provided_category_, GetPageId(page), 276 ContentSuggestion suggestion(provided_category_, GetPageId(page),
271 page.resolved_url); 277 page.resolved_url);
272 DCHECK(base::IsStringUTF8(page.title)); 278 DCHECK(base::IsStringUTF8(page.title));
273 suggestion.set_title(base::UTF8ToUTF16(page.title)); 279 suggestion.set_title(base::UTF8ToUTF16(page.title));
274 suggestion.set_publisher_name(base::UTF8ToUTF16(page.resolved_url.host())); 280 suggestion.set_publisher_name(base::UTF8ToUTF16(page.resolved_url.host()));
275 DCHECK(base::IsStringUTF8(page.description)); 281 DCHECK(base::IsStringUTF8(page.description));
276 suggestion.set_snippet_text(base::UTF8ToUTF16(page.description)); 282 suggestion.set_snippet_text(base::UTF8ToUTF16(page.description));
277 return suggestion; 283 return suggestion;
278 } 284 }
279 285
280 // PhysicalWebListener implementation. 286 // PhysicalWebListener implementation.
281 void PhysicalWebPageSuggestionsProvider::OnFound(const GURL& url) { 287 void PhysicalWebPageSuggestionsProvider::OnFound(const GURL& url) {
282 FetchPhysicalWebPages(); 288 FetchPhysicalWebPages();
283 } 289 }
284 290
285 void PhysicalWebPageSuggestionsProvider::OnLost(const GURL& url) { 291 void PhysicalWebPageSuggestionsProvider::OnLost(const GURL& url) {
286 InvalidateSuggestion(url.spec()); 292 auto it = shown_resolved_urls_by_scanned_url_.find(url);
293 if (it == shown_resolved_urls_by_scanned_url_.end()) {
294 // The notification is propagated further in case the suggestion is shown on
295 // old NTPs (created before last |shown_resolved_urls_by_scanned_url_|
296 // update).
297
298 // TODO(vitaliii): Use |resolved_url| here when it is available. Currently
299 // there is no way to find out |resolved_url|, which corresponds to this
300 // |scanned_url| (the metadata has been already removed from the Physical
301 // Web list). We use |scanned_url| (it may be the same as |resolved_url|,
302 // otherwise nothing happens), however, we should use the latter once it is
303 // provided (e.g. as an argument).
304 InvalidateSuggestion(url.spec());
305 return;
306 }
307
308 // This is not a reference, because the multimap pair will be removed below.
309 const GURL lost_resolved_url = it->second;
310 shown_resolved_urls_by_scanned_url_.erase(it);
311 if (std::find_if(shown_resolved_urls_by_scanned_url_.begin(),
312 shown_resolved_urls_by_scanned_url_.end(),
313 [lost_resolved_url](const std::pair<GURL, GURL>& pair) {
314 return lost_resolved_url == pair.second;
315 }) == shown_resolved_urls_by_scanned_url_.end()) {
316 // There are no more beacons for this URL.
317 InvalidateSuggestion(lost_resolved_url.spec());
318 }
287 } 319 }
288 320
289 void PhysicalWebPageSuggestionsProvider::OnDistanceChanged( 321 void PhysicalWebPageSuggestionsProvider::OnDistanceChanged(
290 const GURL& url, 322 const GURL& url,
291 double distance_estimate) { 323 double distance_estimate) {
292 FetchPhysicalWebPages(); 324 FetchPhysicalWebPages();
293 } 325 }
294 326
295 void PhysicalWebPageSuggestionsProvider::InvalidateSuggestion( 327 void PhysicalWebPageSuggestionsProvider::InvalidateSuggestion(
296 const std::string& page_id) { 328 const std::string& page_id) {
297 observer()->OnSuggestionInvalidated( 329 observer()->OnSuggestionInvalidated(
298 this, ContentSuggestion::ID(provided_category_, page_id)); 330 this, ContentSuggestion::ID(provided_category_, page_id));
299 331
300 // Remove |page_id| from dismissed suggestions, if present. 332 // Remove |page_id| from dismissed suggestions, if present.
301 std::set<std::string> dismissed_ids = ReadDismissedIDsFromPrefs(); 333 std::set<std::string> dismissed_ids = ReadDismissedIDsFromPrefs();
302 auto it = dismissed_ids.find(page_id); 334 auto it = dismissed_ids.find(page_id);
303 if (it != dismissed_ids.end()) { 335 if (it != dismissed_ids.end()) {
304 dismissed_ids.erase(it); 336 dismissed_ids.erase(it);
305 StoreDismissedIDsToPrefs(dismissed_ids); 337 StoreDismissedIDsToPrefs(dismissed_ids);
306 } 338 }
307 } 339 }
308 340
341 void PhysicalWebPageSuggestionsProvider::AppendToShownScannedUrls(
342 const std::vector<ContentSuggestion>& suggestions) {
343 std::unique_ptr<physical_web::MetadataList> page_metadata_list =
344 physical_web_data_source_->GetMetadataList();
345 for (const auto& page_metadata : *page_metadata_list) {
346 if (std::find_if(suggestions.begin(), suggestions.end(),
347 [page_metadata](const ContentSuggestion& suggestion) {
348 return suggestion.url() == page_metadata.resolved_url;
349 }) != suggestions.end()) {
350 shown_resolved_urls_by_scanned_url_.insert(std::make_pair(
351 page_metadata.scanned_url, page_metadata.resolved_url));
352 }
353 }
354 }
355
309 std::set<std::string> 356 std::set<std::string>
310 PhysicalWebPageSuggestionsProvider::ReadDismissedIDsFromPrefs() const { 357 PhysicalWebPageSuggestionsProvider::ReadDismissedIDsFromPrefs() const {
311 return prefs::ReadDismissedIDsFromPrefs( 358 return prefs::ReadDismissedIDsFromPrefs(
312 *pref_service_, prefs::kDismissedPhysicalWebPageSuggestions); 359 *pref_service_, prefs::kDismissedPhysicalWebPageSuggestions);
313 } 360 }
314 361
315 void PhysicalWebPageSuggestionsProvider::StoreDismissedIDsToPrefs( 362 void PhysicalWebPageSuggestionsProvider::StoreDismissedIDsToPrefs(
316 const std::set<std::string>& dismissed_ids) { 363 const std::set<std::string>& dismissed_ids) {
317 prefs::StoreDismissedIDsToPrefs(pref_service_, 364 prefs::StoreDismissedIDsToPrefs(pref_service_,
318 prefs::kDismissedPhysicalWebPageSuggestions, 365 prefs::kDismissedPhysicalWebPageSuggestions,
319 dismissed_ids); 366 dismissed_ids);
320 } 367 }
321 368
322 } // namespace ntp_snippets 369 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698