Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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_scanned_urls_.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 const auto& it = shown_scanned_urls_.find(url); |
|
Marc Treib
2017/01/31 11:02:41
nit: just "auto it", no need for reference to an i
vitaliii
2017/01/31 12:33:49
Done.
| |
| 293 if (it == shown_scanned_urls_.end()) { | |
| 294 // The suggestion may be shown on old NTPs. | |
| 295 // TODO(vitaliii): Use |resolved_url| here when it is available. | |
|
Marc Treib
2017/01/31 11:02:41
What does this mean? It looks like sometimes we in
vitaliii
2017/01/31 12:33:49
We should invalidate by resolved URL, because the
Marc Treib
2017/01/31 13:31:04
But that generally won't do anything, right? (Exce
vitaliii
2017/01/31 13:57:03
True.
Marc Treib
2017/01/31 14:25:58
Then I'd say, rather than doing this half-fix, we
vitaliii
2017/01/31 15:10:57
Please see below why I think that this is 99% fix.
Marc Treib
2017/01/31 15:38:31
The (presumed) 99% fix is the thing below - invali
vitaliii
2017/01/31 16:15:02
That was my assumption that it is better than not
| |
| 296 InvalidateSuggestion(url.spec()); | |
| 297 return; | |
| 298 } | |
| 299 | |
| 300 const GURL lost_resolved_url = it->second; | |
|
Marc Treib
2017/01/31 11:02:41
nit: ref?
vitaliii
2017/01/31 12:33:49
the multimap pair is removed in the next line.
Marc Treib
2017/01/31 13:31:04
Ah, good point. Worth a comment maybe :)
vitaliii
2017/01/31 13:57:03
Acknowledged.
Marc Treib
2017/01/31 14:25:58
...but not done? :P
vitaliii
2017/01/31 15:10:57
Done.
"Maybe" suggested that you did not insist a
Marc Treib
2017/01/31 15:38:31
Thanks!
I wouldn't have insisted, but if you choos
vitaliii
2017/01/31 16:15:02
I see, fair enough. My understanding of "ack" is "
| |
| 301 shown_scanned_urls_.erase(it); | |
| 302 for (const auto& pair : shown_scanned_urls_) { | |
|
Marc Treib
2017/01/31 11:02:41
optional: Could probably be a find_if, since you a
vitaliii
2017/01/31 12:33:49
Done.
| |
| 303 const GURL& resolved_url = pair.second; | |
| 304 if (resolved_url == lost_resolved_url) { | |
| 305 // There are remaining beacons transmiting this URL. | |
| 306 return; | |
| 307 } | |
| 308 } | |
| 309 InvalidateSuggestion(lost_resolved_url.spec()); | |
| 287 } | 310 } |
| 288 | 311 |
| 289 void PhysicalWebPageSuggestionsProvider::OnDistanceChanged( | 312 void PhysicalWebPageSuggestionsProvider::OnDistanceChanged( |
| 290 const GURL& url, | 313 const GURL& url, |
| 291 double distance_estimate) { | 314 double distance_estimate) { |
| 292 FetchPhysicalWebPages(); | 315 FetchPhysicalWebPages(); |
| 293 } | 316 } |
| 294 | 317 |
| 295 void PhysicalWebPageSuggestionsProvider::InvalidateSuggestion( | 318 void PhysicalWebPageSuggestionsProvider::InvalidateSuggestion( |
| 296 const std::string& page_id) { | 319 const std::string& page_id) { |
| 297 observer()->OnSuggestionInvalidated( | 320 observer()->OnSuggestionInvalidated( |
| 298 this, ContentSuggestion::ID(provided_category_, page_id)); | 321 this, ContentSuggestion::ID(provided_category_, page_id)); |
| 299 | 322 |
| 300 // Remove |page_id| from dismissed suggestions, if present. | 323 // Remove |page_id| from dismissed suggestions, if present. |
| 301 std::set<std::string> dismissed_ids = ReadDismissedIDsFromPrefs(); | 324 std::set<std::string> dismissed_ids = ReadDismissedIDsFromPrefs(); |
| 302 auto it = dismissed_ids.find(page_id); | 325 auto it = dismissed_ids.find(page_id); |
| 303 if (it != dismissed_ids.end()) { | 326 if (it != dismissed_ids.end()) { |
| 304 dismissed_ids.erase(it); | 327 dismissed_ids.erase(it); |
| 305 StoreDismissedIDsToPrefs(dismissed_ids); | 328 StoreDismissedIDsToPrefs(dismissed_ids); |
| 306 } | 329 } |
| 307 } | 330 } |
| 308 | 331 |
| 332 void PhysicalWebPageSuggestionsProvider::AppendToShownScannedUrls( | |
| 333 const std::vector<ContentSuggestion>& suggestions) { | |
| 334 std::unique_ptr<physical_web::MetadataList> page_metadata_list = | |
| 335 physical_web_data_source_->GetMetadataList(); | |
| 336 for (const auto& page_metadata : *page_metadata_list) { | |
|
Marc Treib
2017/01/31 11:02:41
This seems quite convoluted. Isn't there a way to
vitaliii
2017/01/31 12:33:49
There may a way. However, if there are multiple sc
Marc Treib
2017/01/31 13:31:04
I'm not sure I follow. It seems to me that GetMost
vitaliii
2017/01/31 13:57:03
GetMostRecentPhysicalWebPagesWithFilter was create
Marc Treib
2017/01/31 14:25:58
The different treatment of the cache is easy to re
vitaliii
2017/01/31 15:10:57
I see, fair enough.
Marc Treib
2017/01/31 15:38:31
Ah, so the problem is that we filter out duplicate
vitaliii
2017/01/31 16:15:02
Yes, indeed.
| |
| 337 if (std::find_if(suggestions.begin(), suggestions.end(), | |
| 338 [page_metadata](const ContentSuggestion& suggestion) { | |
| 339 return suggestion.url() == page_metadata.resolved_url; | |
| 340 }) != suggestions.end()) { | |
| 341 shown_scanned_urls_.insert(std::make_pair(page_metadata.scanned_url, | |
| 342 page_metadata.resolved_url)); | |
| 343 } | |
| 344 } | |
| 345 } | |
| 346 | |
| 309 std::set<std::string> | 347 std::set<std::string> |
| 310 PhysicalWebPageSuggestionsProvider::ReadDismissedIDsFromPrefs() const { | 348 PhysicalWebPageSuggestionsProvider::ReadDismissedIDsFromPrefs() const { |
| 311 return prefs::ReadDismissedIDsFromPrefs( | 349 return prefs::ReadDismissedIDsFromPrefs( |
| 312 *pref_service_, prefs::kDismissedPhysicalWebPageSuggestions); | 350 *pref_service_, prefs::kDismissedPhysicalWebPageSuggestions); |
| 313 } | 351 } |
| 314 | 352 |
| 315 void PhysicalWebPageSuggestionsProvider::StoreDismissedIDsToPrefs( | 353 void PhysicalWebPageSuggestionsProvider::StoreDismissedIDsToPrefs( |
| 316 const std::set<std::string>& dismissed_ids) { | 354 const std::set<std::string>& dismissed_ids) { |
| 317 prefs::StoreDismissedIDsToPrefs(pref_service_, | 355 prefs::StoreDismissedIDsToPrefs(pref_service_, |
| 318 prefs::kDismissedPhysicalWebPageSuggestions, | 356 prefs::kDismissedPhysicalWebPageSuggestions, |
| 319 dismissed_ids); | 357 dismissed_ids); |
| 320 } | 358 } |
| 321 | 359 |
| 322 } // namespace ntp_snippets | 360 } // namespace ntp_snippets |
| OLD | NEW |