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> |
| 11 #include <utility> | 11 #include <utility> |
| 12 | 12 |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/string_piece.h" | 15 #include "base/strings/string_piece.h" |
| 16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 17 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 18 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 19 #include "components/grit/components_scaled_resources.h" | 19 #include "components/grit/components_scaled_resources.h" |
| 20 #include "components/ntp_snippets/pref_names.h" | 20 #include "components/ntp_snippets/pref_names.h" |
| 21 #include "components/ntp_snippets/pref_util.h" | 21 #include "components/ntp_snippets/pref_util.h" |
| 22 #include "components/physical_web/data_source/physical_web_data_source.h" | |
| 22 #include "components/prefs/pref_registry_simple.h" | 23 #include "components/prefs/pref_registry_simple.h" |
| 23 #include "components/prefs/pref_service.h" | 24 #include "components/prefs/pref_service.h" |
| 24 #include "grit/components_strings.h" | 25 #include "grit/components_strings.h" |
| 25 #include "ui/base/l10n/l10n_util.h" | 26 #include "ui/base/l10n/l10n_util.h" |
| 26 #include "ui/base/resource/resource_bundle.h" | 27 #include "ui/base/resource/resource_bundle.h" |
| 27 #include "ui/gfx/image/image.h" | 28 #include "ui/gfx/image/image.h" |
| 28 #include "url/gurl.h" | 29 #include "url/gurl.h" |
| 29 | 30 |
| 30 using base::DictionaryValue; | |
| 31 using base::ListValue; | |
| 32 using base::Value; | |
| 33 | |
| 34 namespace ntp_snippets { | 31 namespace ntp_snippets { |
| 35 | 32 |
| 36 namespace { | 33 namespace { |
| 37 | 34 |
| 38 const size_t kMaxSuggestionsCount = 10; | 35 const size_t kMaxSuggestionsCount = 10; |
| 39 | 36 |
| 40 std::string GetPageId(const DictionaryValue& page_dictionary) { | 37 std::string GetPageId(const physical_web::Metadata& page_metadata) { |
| 41 std::string raw_resolved_url; | 38 return page_metadata.resolved_url.spec(); |
|
vitaliii
2017/01/18 08:03:34
This looks so much better now, thank you for the n
mattreynolds
2017/01/18 22:26:12
No problem!
| |
| 42 if (!page_dictionary.GetString(physical_web::kResolvedUrlKey, | |
| 43 &raw_resolved_url)) { | |
| 44 LOG(DFATAL) << physical_web::kResolvedUrlKey << " field is missing."; | |
| 45 } | |
| 46 return raw_resolved_url; | |
| 47 } | 39 } |
| 48 | 40 |
| 49 } // namespace | 41 } // namespace |
| 50 | 42 |
| 51 PhysicalWebPageSuggestionsProvider::PhysicalWebPageSuggestionsProvider( | 43 PhysicalWebPageSuggestionsProvider::PhysicalWebPageSuggestionsProvider( |
| 52 ContentSuggestionsProvider::Observer* observer, | 44 ContentSuggestionsProvider::Observer* observer, |
| 53 physical_web::PhysicalWebDataSource* physical_web_data_source, | 45 physical_web::PhysicalWebDataSource* physical_web_data_source, |
| 54 PrefService* pref_service) | 46 PrefService* pref_service) |
| 55 : ContentSuggestionsProvider(observer), | 47 : ContentSuggestionsProvider(observer), |
| 56 category_status_(CategoryStatus::AVAILABLE), | 48 category_status_(CategoryStatus::AVAILABLE), |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 | 121 |
| 130 void PhysicalWebPageSuggestionsProvider::ClearCachedSuggestions( | 122 void PhysicalWebPageSuggestionsProvider::ClearCachedSuggestions( |
| 131 Category category) { | 123 Category category) { |
| 132 // Ignored | 124 // Ignored |
| 133 } | 125 } |
| 134 | 126 |
| 135 void PhysicalWebPageSuggestionsProvider::GetDismissedSuggestionsForDebugging( | 127 void PhysicalWebPageSuggestionsProvider::GetDismissedSuggestionsForDebugging( |
| 136 Category category, | 128 Category category, |
| 137 const DismissedSuggestionsCallback& callback) { | 129 const DismissedSuggestionsCallback& callback) { |
| 138 DCHECK_EQ(provided_category_, category); | 130 DCHECK_EQ(provided_category_, category); |
| 139 std::unique_ptr<ListValue> page_values = | 131 std::unique_ptr<physical_web::MetadataList> page_metadata_list = |
| 140 physical_web_data_source_->GetMetadata(); | 132 physical_web_data_source_->GetMetadataList(); |
| 141 const std::set<std::string> dismissed_ids = ReadDismissedIDsFromPrefs(); | 133 const std::set<std::string> dismissed_ids = ReadDismissedIDsFromPrefs(); |
| 142 std::vector<ContentSuggestion> suggestions; | 134 std::vector<ContentSuggestion> suggestions; |
| 143 for (const std::unique_ptr<Value>& page_value : *page_values) { | 135 for (const auto& page_metadata : *page_metadata_list) { |
| 144 const DictionaryValue* page_dictionary; | 136 if (dismissed_ids.count(GetPageId(page_metadata))) { |
| 145 if (!page_value->GetAsDictionary(&page_dictionary)) { | 137 suggestions.push_back(ConvertPhysicalWebPage(page_metadata)); |
| 146 LOG(DFATAL) << "Physical Web page is not a dictionary."; | |
| 147 continue; | |
| 148 } | |
| 149 | |
| 150 if (dismissed_ids.count(GetPageId(*page_dictionary))) { | |
| 151 suggestions.push_back(ConvertPhysicalWebPage(*page_dictionary)); | |
| 152 } | 138 } |
| 153 } | 139 } |
| 154 | 140 |
| 155 callback.Run(std::move(suggestions)); | 141 callback.Run(std::move(suggestions)); |
| 156 } | 142 } |
| 157 | 143 |
| 158 void PhysicalWebPageSuggestionsProvider::ClearDismissedSuggestionsForDebugging( | 144 void PhysicalWebPageSuggestionsProvider::ClearDismissedSuggestionsForDebugging( |
| 159 Category category) { | 145 Category category) { |
| 160 DCHECK_EQ(provided_category_, category); | 146 DCHECK_EQ(provided_category_, category); |
| 161 StoreDismissedIDsToPrefs(std::set<std::string>()); | 147 StoreDismissedIDsToPrefs(std::set<std::string>()); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 185 observer()->OnNewSuggestions(this, provided_category_, | 171 observer()->OnNewSuggestions(this, provided_category_, |
| 186 GetMostRecentPhysicalWebPagesWithFilter( | 172 GetMostRecentPhysicalWebPagesWithFilter( |
| 187 kMaxSuggestionsCount, | 173 kMaxSuggestionsCount, |
| 188 /*excluded_ids=*/std::set<std::string>())); | 174 /*excluded_ids=*/std::set<std::string>())); |
| 189 } | 175 } |
| 190 | 176 |
| 191 std::vector<ContentSuggestion> | 177 std::vector<ContentSuggestion> |
| 192 PhysicalWebPageSuggestionsProvider::GetMostRecentPhysicalWebPagesWithFilter( | 178 PhysicalWebPageSuggestionsProvider::GetMostRecentPhysicalWebPagesWithFilter( |
| 193 int max_quantity, | 179 int max_quantity, |
| 194 const std::set<std::string>& excluded_ids) { | 180 const std::set<std::string>& excluded_ids) { |
| 195 std::unique_ptr<ListValue> page_values = | 181 std::unique_ptr<physical_web::MetadataList> page_metadata_list = |
| 196 physical_web_data_source_->GetMetadata(); | 182 physical_web_data_source_->GetMetadataList(); |
| 197 | 183 |
| 198 // These is to filter out dismissed suggestions and at the same time prune the | 184 // These is to filter out dismissed suggestions and at the same time prune the |
| 199 // dismissed IDs list removing nonavailable pages (this is need since some | 185 // dismissed IDs list removing nonavailable pages (this is need since some |
| 200 // OnLost() calls may have been missed). | 186 // OnLost() calls may have been missed). |
| 201 const std::set<std::string> old_dismissed_ids = ReadDismissedIDsFromPrefs(); | 187 const std::set<std::string> old_dismissed_ids = ReadDismissedIDsFromPrefs(); |
| 202 std::set<std::string> new_dismissed_ids; | 188 std::set<std::string> new_dismissed_ids; |
| 203 std::vector<const DictionaryValue*> page_dictionaries; | 189 physical_web::MetadataList filtered_metadata_list; |
| 204 for (const std::unique_ptr<Value>& page_value : *page_values) { | 190 for (const auto& page_metadata : *page_metadata_list) { |
| 205 const DictionaryValue* page_dictionary; | 191 const std::string page_id = GetPageId(page_metadata); |
| 206 if (!page_value->GetAsDictionary(&page_dictionary)) { | |
| 207 LOG(DFATAL) << "Physical Web page is not a dictionary."; | |
| 208 continue; | |
| 209 } | |
| 210 | |
| 211 const std::string page_id = GetPageId(*page_dictionary); | |
| 212 if (!excluded_ids.count(page_id) && !old_dismissed_ids.count(page_id)) { | 192 if (!excluded_ids.count(page_id) && !old_dismissed_ids.count(page_id)) { |
| 213 page_dictionaries.push_back(page_dictionary); | 193 filtered_metadata_list.push_back(page_metadata); |
| 214 } | 194 } |
| 215 | 195 |
| 216 if (old_dismissed_ids.count(page_id)) { | 196 if (old_dismissed_ids.count(page_id)) { |
| 217 new_dismissed_ids.insert(page_id); | 197 new_dismissed_ids.insert(page_id); |
| 218 } | 198 } |
| 219 } | 199 } |
| 220 | 200 |
| 221 if (old_dismissed_ids.size() != new_dismissed_ids.size()) { | 201 if (old_dismissed_ids.size() != new_dismissed_ids.size()) { |
| 222 StoreDismissedIDsToPrefs(new_dismissed_ids); | 202 StoreDismissedIDsToPrefs(new_dismissed_ids); |
| 223 } | 203 } |
| 224 | 204 |
| 225 std::sort(page_dictionaries.begin(), page_dictionaries.end(), | 205 std::sort(filtered_metadata_list.begin(), filtered_metadata_list.end(), |
| 226 [](const DictionaryValue* left, const DictionaryValue* right) { | 206 [](const physical_web::Metadata& left, |
| 227 double left_distance, right_distance; | 207 const physical_web::Metadata& right) { |
| 228 bool success = left->GetDouble(physical_web::kDistanceEstimateKey, | 208 return left.distance_estimate < right.distance_estimate; |
|
vitaliii
2017/01/18 08:03:34
Since now it is known that distance_estimate may b
vitaliii
2017/01/18 11:50:50
I am actually addressing this in https://coderevie
mattreynolds
2017/01/18 22:26:12
Thanks for the heads up. Looks like yours has land
| |
| 229 &left_distance); | |
| 230 success = right->GetDouble(physical_web::kDistanceEstimateKey, | |
| 231 &right_distance) && | |
| 232 success; | |
| 233 if (!success) { | |
| 234 LOG(DFATAL) << "Distance field is missing."; | |
| 235 } | |
| 236 return left_distance < right_distance; | |
| 237 }); | 209 }); |
| 238 | 210 |
| 239 std::vector<ContentSuggestion> suggestions; | 211 std::vector<ContentSuggestion> suggestions; |
| 240 for (const DictionaryValue* page_dictionary : page_dictionaries) { | 212 for (const auto& page_metadata : filtered_metadata_list) { |
| 241 if (static_cast<int>(suggestions.size()) == max_quantity) { | 213 if (static_cast<int>(suggestions.size()) == max_quantity) { |
| 242 break; | 214 break; |
| 243 } | 215 } |
| 244 suggestions.push_back(ConvertPhysicalWebPage(*page_dictionary)); | 216 suggestions.push_back(ConvertPhysicalWebPage(page_metadata)); |
| 245 } | 217 } |
| 246 | 218 |
| 247 return suggestions; | 219 return suggestions; |
| 248 } | 220 } |
| 249 | 221 |
| 250 ContentSuggestion PhysicalWebPageSuggestionsProvider::ConvertPhysicalWebPage( | 222 ContentSuggestion PhysicalWebPageSuggestionsProvider::ConvertPhysicalWebPage( |
| 251 const DictionaryValue& page) const { | 223 const physical_web::Metadata& page) const { |
| 252 std::string scanned_url, raw_resolved_url, title, description; | |
| 253 bool success = page.GetString(physical_web::kScannedUrlKey, &scanned_url); | |
| 254 success = page.GetString(physical_web::kResolvedUrlKey, &raw_resolved_url) && | |
| 255 success; | |
| 256 success = page.GetString(physical_web::kTitleKey, &title) && success; | |
| 257 success = | |
| 258 page.GetString(physical_web::kDescriptionKey, &description) && success; | |
| 259 if (!success) { | |
| 260 LOG(DFATAL) << "Expected field is missing."; | |
| 261 } | |
| 262 | |
| 263 const GURL resolved_url(raw_resolved_url); | |
| 264 ContentSuggestion suggestion(provided_category_, GetPageId(page), | 224 ContentSuggestion suggestion(provided_category_, GetPageId(page), |
| 265 resolved_url); | 225 page.resolved_url); |
| 266 DCHECK(base::IsStringUTF8(title)); | 226 DCHECK(base::IsStringUTF8(page.title)); |
| 267 suggestion.set_title(base::UTF8ToUTF16(title)); | 227 suggestion.set_title(base::UTF8ToUTF16(page.title)); |
| 268 suggestion.set_publisher_name(base::UTF8ToUTF16(resolved_url.host())); | 228 suggestion.set_publisher_name(base::UTF8ToUTF16(page.resolved_url.host())); |
| 269 DCHECK(base::IsStringUTF8(description)); | 229 DCHECK(base::IsStringUTF8(page.description)); |
| 270 suggestion.set_snippet_text(base::UTF8ToUTF16(description)); | 230 suggestion.set_snippet_text(base::UTF8ToUTF16(page.description)); |
| 271 return suggestion; | 231 return suggestion; |
| 272 } | 232 } |
| 273 | 233 |
| 274 // PhysicalWebListener implementation. | 234 // PhysicalWebListener implementation. |
| 275 void PhysicalWebPageSuggestionsProvider::OnFound(const GURL& url) { | 235 void PhysicalWebPageSuggestionsProvider::OnFound(const GURL& url) { |
| 276 FetchPhysicalWebPages(); | 236 FetchPhysicalWebPages(); |
| 277 } | 237 } |
| 278 | 238 |
| 279 void PhysicalWebPageSuggestionsProvider::OnLost(const GURL& url) { | 239 void PhysicalWebPageSuggestionsProvider::OnLost(const GURL& url) { |
| 280 InvalidateSuggestion(url.spec()); | 240 InvalidateSuggestion(url.spec()); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 307 } | 267 } |
| 308 | 268 |
| 309 void PhysicalWebPageSuggestionsProvider::StoreDismissedIDsToPrefs( | 269 void PhysicalWebPageSuggestionsProvider::StoreDismissedIDsToPrefs( |
| 310 const std::set<std::string>& dismissed_ids) { | 270 const std::set<std::string>& dismissed_ids) { |
| 311 prefs::StoreDismissedIDsToPrefs(pref_service_, | 271 prefs::StoreDismissedIDsToPrefs(pref_service_, |
| 312 prefs::kDismissedPhysicalWebPageSuggestions, | 272 prefs::kDismissedPhysicalWebPageSuggestions, |
| 313 dismissed_ids); | 273 dismissed_ids); |
| 314 } | 274 } |
| 315 | 275 |
| 316 } // namespace ntp_snippets | 276 } // namespace ntp_snippets |
| OLD | NEW |