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

Side by Side Diff: components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc

Issue 2557363002: [NTP Snippets] Refactor background scheduling for remote suggestions (Closed)
Patch Set: Rebase Created 4 years 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "components/ntp_snippets/remote/scheduling_remote_suggestions_provider. h"
6
7 #include <string>
8 #include <utility>
9
10 #include "components/ntp_snippets/features.h"
11 #include "components/ntp_snippets/pref_names.h"
12 #include "components/ntp_snippets/remote/persistent_scheduler.h"
13 #include "components/ntp_snippets/user_classifier.h"
14 #include "components/prefs/pref_registry_simple.h"
15 #include "components/prefs/pref_service.h"
16 #include "components/variations/variations_associated_data.h"
17
18 namespace ntp_snippets {
19
20 namespace {
21
22 // Default values for fetching intervals, fallback and wifi.
23 const double kDefaultFetchingIntervalRareNtpUser[] = {48.0, 24.0};
24 const double kDefaultFetchingIntervalActiveNtpUser[] = {24.0, 6.0};
25 const double kDefaultFetchingIntervalActiveSuggestionsConsumer[] = {24.0, 6.0};
26
27 // Variation parameters than can the default fetching intervals.
28 const char* kFetchingIntervalParamNameRareNtpUser[] = {
29 "fetching_interval_hours-fallback-rare_ntp_user",
30 "fetching_interval_hours-wifi-rare_ntp_user"};
31 const char* kFetchingIntervalParamNameActiveNtpUser[] = {
32 "fetching_interval_hours-fallback-active_ntp_user",
33 "fetching_interval_hours-wifi-active_ntp_user"};
34 const char* kFetchingIntervalParamNameActiveSuggestionsConsumer[] = {
35 "fetching_interval_hours-fallback-active_suggestions_consumer",
36 "fetching_interval_hours-wifi-active_suggestions_consumer"};
37
38 base::TimeDelta GetCurrentUpdateInterval(
39 bool is_wifi,
40 UserClassifier::UserClass user_class) {
41 double default_value_hours = 0.0;
42
43 const int index = is_wifi ? 1 : 0;
44 const char* param_name = nullptr;
45 switch (user_class) {
46 case UserClassifier::UserClass::RARE_NTP_USER:
47 default_value_hours = kDefaultFetchingIntervalRareNtpUser[index];
48 param_name = kFetchingIntervalParamNameRareNtpUser[index];
49 break;
50 case UserClassifier::UserClass::ACTIVE_NTP_USER:
51 default_value_hours = kDefaultFetchingIntervalActiveNtpUser[index];
52 param_name = kFetchingIntervalParamNameActiveNtpUser[index];
53 break;
54 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER:
55 default_value_hours =
56 kDefaultFetchingIntervalActiveSuggestionsConsumer[index];
57 param_name = kFetchingIntervalParamNameActiveSuggestionsConsumer[index];
58 break;
59 }
60
61 double value_hours = variations::GetVariationParamByFeatureAsDouble(
62 ntp_snippets::kArticleSuggestionsFeature, param_name,
63 default_value_hours);
64
65 return base::TimeDelta::FromSecondsD(value_hours * 3600.0);
66 }
67
68 } // namespace
69
70 SchedulingRemoteSuggestionsProvider::SchedulingRemoteSuggestionsProvider(
71 Observer* observer,
72 CategoryFactory* category_factory,
73 std::unique_ptr<RemoteSuggestionsProvider> provider,
74 PersistentScheduler* persistent_scheduler,
75 const UserClassifier* user_classifier,
76 PrefService* pref_service)
77 : ContentSuggestionsProvider(observer, category_factory),
78 provider_(std::move(provider)),
79 persistent_scheduler_(persistent_scheduler),
80 user_classifier_(user_classifier),
81 pref_service_(pref_service) {
82 DCHECK(user_classifier) << "non-null UserClassifier must be provided";
83 DCHECK(pref_service) << "non-null pref service is needed";
84
85 provider->RegisterActivenessObserver(base::BindRepeating(
tschumann 2016/12/15 19:27:00 doing this in the constructor is tricky -- we migh
jkrcal 2016/12/19 09:40:24 Added the TODO.
86 &SchedulingRemoteSuggestionsProvider::OnProviderActivenessChanged,
87 base::Unretained(this)));
88 }
89
90 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() =
91 default;
92
93 // static
94 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs(
95 PrefRegistrySimple* registry) {
96 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalWifi, 0);
97 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalFallback,
98 0);
99 }
100
101 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() {
102 // Force the reschedule by stopping and starting it again.
103 StopScheduling();
104 StartScheduling();
105 }
106
107 void SchedulingRemoteSuggestionsProvider::OnFetchDue() {
108 provider_->RefetchInTheBackground(
109 base::Bind(&SchedulingRemoteSuggestionsProvider::OnFetchCompleted,
110 base::Unretained(this)));
111 }
112
113
114 CategoryStatus SchedulingRemoteSuggestionsProvider::GetCategoryStatus(
115 Category category) {
116 return provider_->GetCategoryStatus(category);
117 }
118
119 CategoryInfo SchedulingRemoteSuggestionsProvider::GetCategoryInfo(
120 Category category) {
121 return provider_->GetCategoryInfo(category);
122 }
123
124 void SchedulingRemoteSuggestionsProvider::DismissSuggestion(
125 const ContentSuggestion::ID& suggestion_id) {
126 provider_->DismissSuggestion(suggestion_id);
127 }
128
129 void SchedulingRemoteSuggestionsProvider::FetchSuggestionImage(
130 const ContentSuggestion::ID& suggestion_id,
131 const ImageFetchedCallback& callback) {
132 provider_->FetchSuggestionImage(suggestion_id, callback);
133 }
134
135 void SchedulingRemoteSuggestionsProvider::Fetch(
136 const Category& category,
137 const std::set<std::string>& known_suggestion_ids,
138 const FetchDoneCallback& callback) {
139 provider_->Fetch(
140 category, known_suggestion_ids,
141 base::Bind(&SchedulingRemoteSuggestionsProvider::FetchFinished,
142 base::Unretained(this), callback));
143 }
144
145 void SchedulingRemoteSuggestionsProvider::ReloadSuggestions() {
146 provider_->ReloadSuggestions();
147 }
148
149 void SchedulingRemoteSuggestionsProvider::ClearHistory(
150 base::Time begin,
151 base::Time end,
152 const base::Callback<bool(const GURL& url)>& filter) {
153 provider_->ClearHistory(begin, end, filter);
154 }
155
156 void SchedulingRemoteSuggestionsProvider::ClearCachedSuggestions(
157 Category category) {
158 provider_->ClearCachedSuggestions(category);
159 }
160
161 void SchedulingRemoteSuggestionsProvider::OnSignInStateChanged() {
162 provider_->OnSignInStateChanged();
163 }
164
165 void SchedulingRemoteSuggestionsProvider::GetDismissedSuggestionsForDebugging(
166 Category category,
167 const DismissedSuggestionsCallback& callback) {
168 provider_->GetDismissedSuggestionsForDebugging(category, callback);
169 }
170
171 void SchedulingRemoteSuggestionsProvider::ClearDismissedSuggestionsForDebugging(
172 Category category) {
173 provider_->ClearDismissedSuggestionsForDebugging(category);
174 }
175
176 void SchedulingRemoteSuggestionsProvider::OnProviderActivenessChanged(
177 bool active) {
178 if (active) {
179 StartScheduling();
180 } else {
181 StopScheduling();
182 }
183 }
184
185 void SchedulingRemoteSuggestionsProvider::StartScheduling() {
186 // The scheduler only exists on Android so far, it's null on other platforms.
187 if (!persistent_scheduler_) {
188 return;
189 }
190
191 FetchingSchedule last_schedule = GetLastFetchingSchedule();
192 FetchingSchedule schedule = GetDesiredFetchingSchedule();
193
194 // Reset the schedule only if the parameters have changed.
195 if (last_schedule != schedule) {
196 ApplyFetchingSchedule(schedule);
197 }
198 }
199
200 void SchedulingRemoteSuggestionsProvider::StopScheduling() {
201 // The scheduler only exists on Android so far, it's null on other platforms.
202 if (!persistent_scheduler_) {
203 return;
204 }
205
206 // Do not unschedule if already switched off
207 FetchingSchedule last_schedule = GetLastFetchingSchedule();
208 if (last_schedule.is_empty()) {
209 return;
210 }
211
212 persistent_scheduler_->Unschedule();
213
214 StoreLastFetchingSchedule(FetchingSchedule::Empty());
215 }
216
217 void SchedulingRemoteSuggestionsProvider::ApplyFetchingSchedule(
218 FetchingSchedule schedule) {
219 persistent_scheduler_->Schedule(schedule.interval_wifi,
220 schedule.interval_fallback);
221
222 StoreLastFetchingSchedule(schedule);
223 }
224
225 SchedulingRemoteSuggestionsProvider::FetchingSchedule
226 SchedulingRemoteSuggestionsProvider::GetDesiredFetchingSchedule() {
227 UserClassifier::UserClass user_class = user_classifier_->GetUserClass();
228
229 FetchingSchedule schedule;
230 schedule.interval_wifi =
231 GetCurrentUpdateInterval(/*is_wifi=*/true, user_class);
232 schedule.interval_fallback =
233 GetCurrentUpdateInterval(/*is_wifi=*/false, user_class);
234 return schedule;
235 }
236
237 SchedulingRemoteSuggestionsProvider::FetchingSchedule
238 SchedulingRemoteSuggestionsProvider::GetLastFetchingSchedule() const {
239 FetchingSchedule schedule;
240 schedule.interval_wifi = base::TimeDelta::FromInternalValue(
241 pref_service_->GetInt64(prefs::kSnippetBackgroundFetchingIntervalWifi));
242 schedule.interval_fallback =
243 base::TimeDelta::FromInternalValue(pref_service_->GetInt64(
244 prefs::kSnippetBackgroundFetchingIntervalFallback));
245 return schedule;
246 }
247
248 void SchedulingRemoteSuggestionsProvider::StoreLastFetchingSchedule(
249 FetchingSchedule schedule) {
250 pref_service_->SetInt64(
251 prefs::kSnippetBackgroundFetchingIntervalWifi,
252 schedule.interval_wifi.ToInternalValue());
253 pref_service_->SetInt64(
254 prefs::kSnippetBackgroundFetchingIntervalFallback,
255 schedule.interval_fallback.ToInternalValue());
256 }
257
258 void SchedulingRemoteSuggestionsProvider::FetchFinished(
259 const FetchDoneCallback& callback,
260 Status status_code,
261 std::vector<ContentSuggestion> suggestions) {
262 // Intercept |status_code| before calling the provided |callback|.
tschumann 2016/12/15 19:27:00 no need for the comment -- it's quite obvious :-)
jkrcal 2016/12/19 09:40:24 Done.
263 OnFetchCompleted(status_code);
264 callback.Run(status_code, std::move(suggestions));
265 }
266
267 void SchedulingRemoteSuggestionsProvider::OnFetchCompleted(Status status_code) {
268 // The scheduler only exists on Android so far, it's null on other platforms.
269 if (!persistent_scheduler_) {
270 return;
271 }
272
273 if (status_code.status != StatusCode::SUCCESS) {
274 return;
275 }
276
277 // Reschedule after a successful fetch. This resets all currently scheduled
278 // fetches, to make sure the fallback interval triggers only if no wifi fetch
279 // succeeded, and also that we don't do a background fetch immediately after
280 // a user-initiated one.
281 ApplyFetchingSchedule(GetLastFetchingSchedule());
282 }
283
284 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698