Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/remote/remote_suggestions_provider.h" | 5 #include "components/ntp_snippets/remote/remote_suggestions_provider.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #include "base/task_runner_util.h" | 21 #include "base/task_runner_util.h" |
| 22 #include "base/time/time.h" | 22 #include "base/time/time.h" |
| 23 #include "base/values.h" | 23 #include "base/values.h" |
| 24 #include "components/data_use_measurement/core/data_use_user_data.h" | 24 #include "components/data_use_measurement/core/data_use_user_data.h" |
| 25 #include "components/history/core/browser/history_service.h" | 25 #include "components/history/core/browser/history_service.h" |
| 26 #include "components/image_fetcher/image_decoder.h" | 26 #include "components/image_fetcher/image_decoder.h" |
| 27 #include "components/image_fetcher/image_fetcher.h" | 27 #include "components/image_fetcher/image_fetcher.h" |
| 28 #include "components/ntp_snippets/features.h" | 28 #include "components/ntp_snippets/features.h" |
| 29 #include "components/ntp_snippets/pref_names.h" | 29 #include "components/ntp_snippets/pref_names.h" |
| 30 #include "components/ntp_snippets/remote/remote_suggestions_database.h" | 30 #include "components/ntp_snippets/remote/remote_suggestions_database.h" |
| 31 #include "components/ntp_snippets/remote/remote_suggestions_scheduler.h" | |
| 31 #include "components/ntp_snippets/switches.h" | 32 #include "components/ntp_snippets/switches.h" |
| 32 #include "components/ntp_snippets/user_classifier.h" | 33 #include "components/ntp_snippets/user_classifier.h" |
| 33 #include "components/prefs/pref_registry_simple.h" | 34 #include "components/prefs/pref_registry_simple.h" |
| 34 #include "components/prefs/pref_service.h" | 35 #include "components/prefs/pref_service.h" |
| 35 #include "components/variations/variations_associated_data.h" | 36 #include "components/variations/variations_associated_data.h" |
| 36 #include "grit/components_strings.h" | 37 #include "grit/components_strings.h" |
| 37 #include "ui/base/l10n/l10n_util.h" | 38 #include "ui/base/l10n/l10n_util.h" |
| 38 #include "ui/gfx/image/image.h" | 39 #include "ui/gfx/image/image.h" |
| 39 | 40 |
| 40 namespace ntp_snippets { | 41 namespace ntp_snippets { |
| 41 | 42 |
| 42 namespace { | 43 namespace { |
| 43 | 44 |
| 44 // Number of snippets requested to the server. Consider replacing sparse UMA | 45 // Number of snippets requested to the server. Consider replacing sparse UMA |
| 45 // histograms with COUNTS() if this number increases beyond 50. | 46 // histograms with COUNTS() if this number increases beyond 50. |
| 46 const int kMaxSnippetCount = 10; | 47 const int kMaxSnippetCount = 10; |
| 47 | 48 |
| 48 // Number of archived snippets we keep around in memory. | 49 // Number of archived snippets we keep around in memory. |
| 49 const int kMaxArchivedSnippetCount = 200; | 50 const int kMaxArchivedSnippetCount = 200; |
| 50 | 51 |
| 51 // Default values for fetching intervals, fallback and wifi. | |
| 52 const double kDefaultFetchingIntervalRareNtpUser[] = {48.0, 24.0}; | |
| 53 const double kDefaultFetchingIntervalActiveNtpUser[] = {24.0, 6.0}; | |
| 54 const double kDefaultFetchingIntervalActiveSuggestionsConsumer[] = {24.0, 6.0}; | |
| 55 | |
| 56 // Variation parameters than can override the default fetching intervals. | |
| 57 const char* kFetchingIntervalParamNameRareNtpUser[] = { | |
| 58 "fetching_interval_hours-fallback-rare_ntp_user", | |
| 59 "fetching_interval_hours-wifi-rare_ntp_user"}; | |
| 60 const char* kFetchingIntervalParamNameActiveNtpUser[] = { | |
| 61 "fetching_interval_hours-fallback-active_ntp_user", | |
| 62 "fetching_interval_hours-wifi-active_ntp_user"}; | |
| 63 const char* kFetchingIntervalParamNameActiveSuggestionsConsumer[] = { | |
| 64 "fetching_interval_hours-fallback-active_suggestions_consumer", | |
| 65 "fetching_interval_hours-wifi-active_suggestions_consumer"}; | |
| 66 | |
| 67 // Keys for storing CategoryContent info in prefs. | 52 // Keys for storing CategoryContent info in prefs. |
| 68 const char kCategoryContentId[] = "id"; | 53 const char kCategoryContentId[] = "id"; |
| 69 const char kCategoryContentTitle[] = "title"; | 54 const char kCategoryContentTitle[] = "title"; |
| 70 const char kCategoryContentProvidedByServer[] = "provided_by_server"; | 55 const char kCategoryContentProvidedByServer[] = "provided_by_server"; |
| 71 const char kCategoryContentAllowFetchingMore[] = "allow_fetching_more"; | 56 const char kCategoryContentAllowFetchingMore[] = "allow_fetching_more"; |
| 72 | 57 |
| 73 // TODO(treib): Remove after M57. | 58 // TODO(treib): Remove after M57. |
| 74 const char kDeprecatedSnippetHostsPref[] = "ntp_snippets.hosts"; | 59 const char kDeprecatedSnippetHostsPref[] = "ntp_snippets.hosts"; |
| 75 | 60 |
| 76 base::TimeDelta GetFetchingInterval(bool is_wifi, | |
| 77 UserClassifier::UserClass user_class) { | |
| 78 double value_hours = 0.0; | |
| 79 | |
| 80 const int index = is_wifi ? 1 : 0; | |
| 81 const char* param_name = ""; | |
| 82 switch (user_class) { | |
| 83 case UserClassifier::UserClass::RARE_NTP_USER: | |
| 84 value_hours = kDefaultFetchingIntervalRareNtpUser[index]; | |
| 85 param_name = kFetchingIntervalParamNameRareNtpUser[index]; | |
| 86 break; | |
| 87 case UserClassifier::UserClass::ACTIVE_NTP_USER: | |
| 88 value_hours = kDefaultFetchingIntervalActiveNtpUser[index]; | |
| 89 param_name = kFetchingIntervalParamNameActiveNtpUser[index]; | |
| 90 break; | |
| 91 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER: | |
| 92 value_hours = kDefaultFetchingIntervalActiveSuggestionsConsumer[index]; | |
| 93 param_name = kFetchingIntervalParamNameActiveSuggestionsConsumer[index]; | |
| 94 break; | |
| 95 } | |
| 96 | |
| 97 // The default value can be overridden by a variation parameter. | |
| 98 std::string param_value_str = variations::GetVariationParamValueByFeature( | |
| 99 ntp_snippets::kArticleSuggestionsFeature, param_name); | |
| 100 if (!param_value_str.empty()) { | |
| 101 double param_value_hours = 0.0; | |
| 102 if (base::StringToDouble(param_value_str, ¶m_value_hours)) { | |
| 103 value_hours = param_value_hours; | |
| 104 } else { | |
| 105 LOG(WARNING) << "Invalid value for variation parameter " << param_name; | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 return base::TimeDelta::FromSecondsD(value_hours * 3600.0); | |
| 110 } | |
| 111 | |
| 112 std::unique_ptr<std::vector<std::string>> GetSnippetIDVector( | 61 std::unique_ptr<std::vector<std::string>> GetSnippetIDVector( |
| 113 const NTPSnippet::PtrVector& snippets) { | 62 const NTPSnippet::PtrVector& snippets) { |
| 114 auto result = base::MakeUnique<std::vector<std::string>>(); | 63 auto result = base::MakeUnique<std::vector<std::string>>(); |
| 115 for (const auto& snippet : snippets) { | 64 for (const auto& snippet : snippets) { |
| 116 result->push_back(snippet->id()); | 65 result->push_back(snippet->id()); |
| 117 } | 66 } |
| 118 return result; | 67 return result; |
| 119 } | 68 } |
| 120 | 69 |
| 121 bool HasIntersection(const std::vector<std::string>& a, | 70 bool HasIntersection(const std::vector<std::string>& a, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 } | 168 } |
| 220 | 169 |
| 221 } // namespace | 170 } // namespace |
| 222 | 171 |
| 223 RemoteSuggestionsProvider::RemoteSuggestionsProvider( | 172 RemoteSuggestionsProvider::RemoteSuggestionsProvider( |
| 224 Observer* observer, | 173 Observer* observer, |
| 225 CategoryFactory* category_factory, | 174 CategoryFactory* category_factory, |
| 226 PrefService* pref_service, | 175 PrefService* pref_service, |
| 227 const std::string& application_language_code, | 176 const std::string& application_language_code, |
| 228 const UserClassifier* user_classifier, | 177 const UserClassifier* user_classifier, |
| 229 NTPSnippetsScheduler* scheduler, | 178 RemoteSuggestionsHardScheduler* hard_scheduler, |
| 230 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, | 179 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, |
| 231 std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher, | 180 std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher, |
| 232 std::unique_ptr<image_fetcher::ImageDecoder> image_decoder, | 181 std::unique_ptr<image_fetcher::ImageDecoder> image_decoder, |
| 233 std::unique_ptr<RemoteSuggestionsDatabase> database, | 182 std::unique_ptr<RemoteSuggestionsDatabase> database, |
| 234 std::unique_ptr<RemoteSuggestionsStatusService> status_service) | 183 std::unique_ptr<RemoteSuggestionsStatusService> status_service) |
| 235 : ContentSuggestionsProvider(observer, category_factory), | 184 : ContentSuggestionsProvider(observer, category_factory), |
| 236 state_(State::NOT_INITED), | 185 state_(State::NOT_INITED), |
| 237 pref_service_(pref_service), | 186 pref_service_(pref_service), |
| 238 articles_category_( | 187 articles_category_( |
| 239 category_factory->FromKnownCategory(KnownCategories::ARTICLES)), | 188 category_factory->FromKnownCategory(KnownCategories::ARTICLES)), |
| 240 application_language_code_(application_language_code), | 189 application_language_code_(application_language_code), |
| 241 user_classifier_(user_classifier), | 190 user_classifier_(user_classifier), |
| 242 scheduler_(scheduler), | 191 scheduler_(hard_scheduler, |
| 192 this /* scheduler_updater */, | |
|
Marc Treib
2016/12/08 16:14:58
/*scheduler_updater=*/this
That said, it's a bit
jkrcal
2016/12/09 09:20:38
Fair enough. Removed it from the constructor and a
| |
| 193 user_classifier, | |
| 194 pref_service), | |
| 243 snippets_fetcher_(std::move(snippets_fetcher)), | 195 snippets_fetcher_(std::move(snippets_fetcher)), |
| 244 image_fetcher_(std::move(image_fetcher)), | 196 image_fetcher_(std::move(image_fetcher)), |
| 245 image_decoder_(std::move(image_decoder)), | 197 image_decoder_(std::move(image_decoder)), |
| 246 database_(std::move(database)), | 198 database_(std::move(database)), |
| 247 status_service_(std::move(status_service)), | 199 status_service_(std::move(status_service)), |
| 248 fetch_when_ready_(false), | 200 fetch_when_ready_(false), |
| 249 nuke_when_initialized_(false), | 201 nuke_when_initialized_(false), |
| 250 thumbnail_requests_throttler_( | 202 thumbnail_requests_throttler_( |
| 251 pref_service, | 203 pref_service, |
| 252 RequestThrottler::RequestType::CONTENT_SUGGESTION_THUMBNAIL) { | 204 RequestThrottler::RequestType::CONTENT_SUGGESTION_THUMBNAIL) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 280 } | 232 } |
| 281 | 233 |
| 282 RemoteSuggestionsProvider::~RemoteSuggestionsProvider() = default; | 234 RemoteSuggestionsProvider::~RemoteSuggestionsProvider() = default; |
| 283 | 235 |
| 284 // static | 236 // static |
| 285 void RemoteSuggestionsProvider::RegisterProfilePrefs( | 237 void RemoteSuggestionsProvider::RegisterProfilePrefs( |
| 286 PrefRegistrySimple* registry) { | 238 PrefRegistrySimple* registry) { |
| 287 // TODO(treib): Remove after M57. | 239 // TODO(treib): Remove after M57. |
| 288 registry->RegisterListPref(kDeprecatedSnippetHostsPref); | 240 registry->RegisterListPref(kDeprecatedSnippetHostsPref); |
| 289 registry->RegisterListPref(prefs::kRemoteSuggestionCategories); | 241 registry->RegisterListPref(prefs::kRemoteSuggestionCategories); |
| 290 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalWifi, 0); | |
| 291 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalFallback, | |
| 292 0); | |
| 293 | 242 |
| 243 RemoteSuggestionsScheduler::RegisterProfilePrefs(registry); | |
| 294 RemoteSuggestionsStatusService::RegisterProfilePrefs(registry); | 244 RemoteSuggestionsStatusService::RegisterProfilePrefs(registry); |
| 295 } | 245 } |
| 296 | 246 |
| 297 void RemoteSuggestionsProvider::FetchSnippetsInTheBackground() { | 247 void RemoteSuggestionsProvider::UpdateRemoteSuggestionsBySchedule() { |
| 298 FetchSnippets(/*interactive_request=*/false); | 248 FetchSnippets(/*interactive_request=*/false); |
| 299 } | 249 } |
| 300 | 250 |
| 301 void RemoteSuggestionsProvider::FetchSnippetsForAllCategories() { | 251 void RemoteSuggestionsProvider::FetchSnippetsForAllCategories() { |
| 302 // TODO(markusheintz): Investigate whether we can call the Fetch method | 252 // TODO(markusheintz): Investigate whether we can call the Fetch method |
| 303 // instead of the FetchSnippets. | 253 // instead of the FetchSnippets. |
| 304 FetchSnippets(/*interactive_request=*/true); | 254 FetchSnippets(/*interactive_request=*/true); |
| 305 } | 255 } |
| 306 | 256 |
| 307 void RemoteSuggestionsProvider::FetchSnippets(bool interactive_request) { | 257 void RemoteSuggestionsProvider::FetchSnippets(bool interactive_request) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 void RemoteSuggestionsProvider::MarkEmptyCategoriesAsLoading() { | 325 void RemoteSuggestionsProvider::MarkEmptyCategoriesAsLoading() { |
| 376 for (const auto& item : category_contents_) { | 326 for (const auto& item : category_contents_) { |
| 377 Category category = item.first; | 327 Category category = item.first; |
| 378 const CategoryContent& content = item.second; | 328 const CategoryContent& content = item.second; |
| 379 if (content.snippets.empty()) { | 329 if (content.snippets.empty()) { |
| 380 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE_LOADING); | 330 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE_LOADING); |
| 381 } | 331 } |
| 382 } | 332 } |
| 383 } | 333 } |
| 384 | 334 |
| 385 void RemoteSuggestionsProvider::RescheduleFetching(bool force) { | |
| 386 // The scheduler only exists on Android so far, it's null on other platforms. | |
| 387 if (!scheduler_) { | |
| 388 return; | |
| 389 } | |
| 390 | |
| 391 if (ready()) { | |
| 392 base::TimeDelta old_interval_wifi = base::TimeDelta::FromInternalValue( | |
| 393 pref_service_->GetInt64(prefs::kSnippetBackgroundFetchingIntervalWifi)); | |
| 394 base::TimeDelta old_interval_fallback = | |
| 395 base::TimeDelta::FromInternalValue(pref_service_->GetInt64( | |
| 396 prefs::kSnippetBackgroundFetchingIntervalFallback)); | |
| 397 UserClassifier::UserClass user_class = user_classifier_->GetUserClass(); | |
| 398 base::TimeDelta interval_wifi = | |
| 399 GetFetchingInterval(/*is_wifi=*/true, user_class); | |
| 400 base::TimeDelta interval_fallback = | |
| 401 GetFetchingInterval(/*is_wifi=*/false, user_class); | |
| 402 if (force || interval_wifi != old_interval_wifi || | |
| 403 interval_fallback != old_interval_fallback) { | |
| 404 scheduler_->Schedule(interval_wifi, interval_fallback); | |
| 405 pref_service_->SetInt64(prefs::kSnippetBackgroundFetchingIntervalWifi, | |
| 406 interval_wifi.ToInternalValue()); | |
| 407 pref_service_->SetInt64(prefs::kSnippetBackgroundFetchingIntervalFallback, | |
| 408 interval_fallback.ToInternalValue()); | |
| 409 } | |
| 410 } else { | |
| 411 // If we're NOT_INITED, we don't know whether to schedule or unschedule. | |
| 412 // If |force| is false, all is well: We'll reschedule on the next state | |
| 413 // change anyway. If it's true, then unschedule here, to make sure that the | |
| 414 // next reschedule actually happens. | |
| 415 if (state_ != State::NOT_INITED || force) { | |
| 416 scheduler_->Unschedule(); | |
| 417 pref_service_->ClearPref(prefs::kSnippetBackgroundFetchingIntervalWifi); | |
| 418 pref_service_->ClearPref( | |
| 419 prefs::kSnippetBackgroundFetchingIntervalFallback); | |
| 420 } | |
| 421 } | |
| 422 } | |
| 423 | |
| 424 CategoryStatus RemoteSuggestionsProvider::GetCategoryStatus(Category category) { | 335 CategoryStatus RemoteSuggestionsProvider::GetCategoryStatus(Category category) { |
| 425 auto content_it = category_contents_.find(category); | 336 auto content_it = category_contents_.find(category); |
| 426 DCHECK(content_it != category_contents_.end()); | 337 DCHECK(content_it != category_contents_.end()); |
| 427 return content_it->second.status; | 338 return content_it->second.status; |
| 428 } | 339 } |
| 429 | 340 |
| 430 CategoryInfo RemoteSuggestionsProvider::GetCategoryInfo(Category category) { | 341 CategoryInfo RemoteSuggestionsProvider::GetCategoryInfo(Category category) { |
| 431 auto content_it = category_contents_.find(category); | 342 auto content_it = category_contents_.find(category); |
| 432 DCHECK(content_it != category_contents_.end()); | 343 DCHECK(content_it != category_contents_.end()); |
| 433 return content_it->second.info; | 344 return content_it->second.info; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 766 if (content.snippets.empty() && !content.dismissed.empty()) { | 677 if (content.snippets.empty() && !content.dismissed.empty()) { |
| 767 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", | 678 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", |
| 768 content.dismissed.size()); | 679 content.dismissed.size()); |
| 769 } | 680 } |
| 770 | 681 |
| 771 // Reschedule after a successful fetch. This resets all currently scheduled | 682 // Reschedule after a successful fetch. This resets all currently scheduled |
| 772 // fetches, to make sure the fallback interval triggers only if no wifi fetch | 683 // fetches, to make sure the fallback interval triggers only if no wifi fetch |
| 773 // succeeded, and also that we don't do a background fetch immediately after | 684 // succeeded, and also that we don't do a background fetch immediately after |
| 774 // a user-initiated one. | 685 // a user-initiated one. |
| 775 if (fetched_categories) { | 686 if (fetched_categories) { |
| 776 RescheduleFetching(true); | 687 scheduler_.OnSuccessfulUpdate(); |
| 777 } | 688 } |
| 778 } | 689 } |
| 779 | 690 |
| 780 void RemoteSuggestionsProvider::ArchiveSnippets( | 691 void RemoteSuggestionsProvider::ArchiveSnippets( |
| 781 CategoryContent* content, | 692 CategoryContent* content, |
| 782 NTPSnippet::PtrVector* to_archive) { | 693 NTPSnippet::PtrVector* to_archive) { |
| 783 // Archive previous snippets - move them at the beginning of the list. | 694 // Archive previous snippets - move them at the beginning of the list. |
| 784 content->archived.insert(content->archived.begin(), | 695 content->archived.insert(content->archived.begin(), |
| 785 std::make_move_iterator(to_archive->begin()), | 696 std::make_move_iterator(to_archive->begin()), |
| 786 std::make_move_iterator(to_archive->end())); | 697 std::make_move_iterator(to_archive->end())); |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1127 // Initial state, it should not be possible to get back there. | 1038 // Initial state, it should not be possible to get back there. |
| 1128 NOTREACHED(); | 1039 NOTREACHED(); |
| 1129 break; | 1040 break; |
| 1130 | 1041 |
| 1131 case State::READY: | 1042 case State::READY: |
| 1132 DCHECK(state_ == State::NOT_INITED || state_ == State::DISABLED); | 1043 DCHECK(state_ == State::NOT_INITED || state_ == State::DISABLED); |
| 1133 | 1044 |
| 1134 DVLOG(1) << "Entering state: READY"; | 1045 DVLOG(1) << "Entering state: READY"; |
| 1135 state_ = State::READY; | 1046 state_ = State::READY; |
| 1136 EnterStateReady(); | 1047 EnterStateReady(); |
| 1048 scheduler_.Schedule(); | |
| 1137 break; | 1049 break; |
| 1138 | 1050 |
| 1139 case State::DISABLED: | 1051 case State::DISABLED: |
| 1140 DCHECK(state_ == State::NOT_INITED || state_ == State::READY); | 1052 DCHECK(state_ == State::NOT_INITED || state_ == State::READY); |
| 1141 | 1053 |
| 1142 DVLOG(1) << "Entering state: DISABLED"; | 1054 DVLOG(1) << "Entering state: DISABLED"; |
| 1143 state_ = State::DISABLED; | 1055 state_ = State::DISABLED; |
| 1144 EnterStateDisabled(); | 1056 EnterStateDisabled(); |
| 1057 scheduler_.Unschedule(); | |
| 1145 break; | 1058 break; |
| 1146 | 1059 |
| 1147 case State::ERROR_OCCURRED: | 1060 case State::ERROR_OCCURRED: |
| 1148 DVLOG(1) << "Entering state: ERROR_OCCURRED"; | 1061 DVLOG(1) << "Entering state: ERROR_OCCURRED"; |
| 1149 state_ = State::ERROR_OCCURRED; | 1062 state_ = State::ERROR_OCCURRED; |
| 1150 EnterStateError(); | 1063 EnterStateError(); |
| 1064 scheduler_.Unschedule(); | |
| 1151 break; | 1065 break; |
| 1152 | 1066 |
| 1153 case State::COUNT: | 1067 case State::COUNT: |
| 1154 NOTREACHED(); | 1068 NOTREACHED(); |
| 1155 break; | 1069 break; |
| 1156 } | 1070 } |
| 1157 | |
| 1158 // Schedule or un-schedule background fetching after each state change. | |
| 1159 RescheduleFetching(false); | |
| 1160 } | 1071 } |
| 1161 | 1072 |
| 1162 void RemoteSuggestionsProvider::NotifyNewSuggestions( | 1073 void RemoteSuggestionsProvider::NotifyNewSuggestions( |
| 1163 Category category, | 1074 Category category, |
| 1164 const CategoryContent& content) { | 1075 const CategoryContent& content) { |
| 1165 DCHECK(IsCategoryStatusAvailable(content.status)); | 1076 DCHECK(IsCategoryStatusAvailable(content.status)); |
| 1166 | 1077 |
| 1167 std::vector<ContentSuggestion> result = | 1078 std::vector<ContentSuggestion> result = |
| 1168 ConvertToContentSuggestions(category, content.snippets); | 1079 ConvertToContentSuggestions(category, content.snippets); |
| 1169 | 1080 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1332 RemoteSuggestionsProvider::CategoryContent::CategoryContent(CategoryContent&&) = | 1243 RemoteSuggestionsProvider::CategoryContent::CategoryContent(CategoryContent&&) = |
| 1333 default; | 1244 default; |
| 1334 | 1245 |
| 1335 RemoteSuggestionsProvider::CategoryContent::~CategoryContent() = default; | 1246 RemoteSuggestionsProvider::CategoryContent::~CategoryContent() = default; |
| 1336 | 1247 |
| 1337 RemoteSuggestionsProvider::CategoryContent& | 1248 RemoteSuggestionsProvider::CategoryContent& |
| 1338 RemoteSuggestionsProvider::CategoryContent::operator=(CategoryContent&&) = | 1249 RemoteSuggestionsProvider::CategoryContent::operator=(CategoryContent&&) = |
| 1339 default; | 1250 default; |
| 1340 | 1251 |
| 1341 } // namespace ntp_snippets | 1252 } // namespace ntp_snippets |
| OLD | NEW |