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

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: Fixing the last changes :) 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/status.h"
14 #include "components/ntp_snippets/user_classifier.h"
15 #include "components/prefs/pref_registry_simple.h"
16 #include "components/prefs/pref_service.h"
17 #include "components/variations/variations_associated_data.h"
18
19 namespace ntp_snippets {
20
21 namespace {
22
23 // Default values for fetching intervals, fallback and wifi.
24 const double kDefaultFetchingIntervalRareNtpUser[] = {48.0, 24.0};
25 const double kDefaultFetchingIntervalActiveNtpUser[] = {24.0, 6.0};
26 const double kDefaultFetchingIntervalActiveSuggestionsConsumer[] = {24.0, 6.0};
27
28 // Variation parameters than can the default fetching intervals.
29 const char* kFetchingIntervalParamNameRareNtpUser[] = {
30 "fetching_interval_hours-fallback-rare_ntp_user",
31 "fetching_interval_hours-wifi-rare_ntp_user"};
32 const char* kFetchingIntervalParamNameActiveNtpUser[] = {
33 "fetching_interval_hours-fallback-active_ntp_user",
34 "fetching_interval_hours-wifi-active_ntp_user"};
35 const char* kFetchingIntervalParamNameActiveSuggestionsConsumer[] = {
36 "fetching_interval_hours-fallback-active_suggestions_consumer",
37 "fetching_interval_hours-wifi-active_suggestions_consumer"};
38
39 base::TimeDelta GetDesiredUpdateInterval(
40 bool is_wifi,
41 UserClassifier::UserClass user_class) {
42 double default_value_hours = 0.0;
43
44 const int index = is_wifi ? 1 : 0;
45 const char* param_name = nullptr;
46 switch (user_class) {
47 case UserClassifier::UserClass::RARE_NTP_USER:
48 default_value_hours = kDefaultFetchingIntervalRareNtpUser[index];
49 param_name = kFetchingIntervalParamNameRareNtpUser[index];
50 break;
51 case UserClassifier::UserClass::ACTIVE_NTP_USER:
52 default_value_hours = kDefaultFetchingIntervalActiveNtpUser[index];
53 param_name = kFetchingIntervalParamNameActiveNtpUser[index];
54 break;
55 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER:
56 default_value_hours =
57 kDefaultFetchingIntervalActiveSuggestionsConsumer[index];
58 param_name = kFetchingIntervalParamNameActiveSuggestionsConsumer[index];
59 break;
60 }
61
62 double value_hours = variations::GetVariationParamByFeatureAsDouble(
63 ntp_snippets::kArticleSuggestionsFeature, param_name,
64 default_value_hours);
65
66 return base::TimeDelta::FromSecondsD(value_hours * 3600.0);
67 }
68
69 } // namespace
70
71 struct SchedulingRemoteSuggestionsProvider::FetchingSchedule {
72 base::TimeDelta interval_wifi;
73 base::TimeDelta interval_fallback;
74
75 static FetchingSchedule Empty() {
76 return FetchingSchedule{base::TimeDelta(),
77 base::TimeDelta()};
78 }
79
80 bool operator==(const FetchingSchedule& other) const {
81 return interval_wifi == other.interval_wifi &&
82 interval_fallback == other.interval_fallback;
83 }
84
85 bool operator!=(const FetchingSchedule& other) const {
86 return !operator==(other);
87 }
88
89 bool is_empty() const {
90 return interval_wifi.is_zero() && interval_fallback.is_zero();
91 }
92 };
93
94 SchedulingRemoteSuggestionsProvider::SchedulingRemoteSuggestionsProvider(
95 Observer* observer,
96 std::unique_ptr<RemoteSuggestionsProvider> provider,
97 PersistentScheduler* persistent_scheduler,
98 const UserClassifier* user_classifier,
99 PrefService* pref_service)
100 : RemoteSuggestionsProvider(observer),
101 RemoteSuggestionsScheduler(),
102 provider_(std::move(provider)),
103 persistent_scheduler_(persistent_scheduler),
104 user_classifier_(user_classifier),
105 pref_service_(pref_service) {
106 DCHECK(user_classifier);
107 DCHECK(pref_service);
108
109 provider_->SetProviderStatusCallback(
110 base::MakeUnique<RemoteSuggestionsProvider::ProviderStatusCallback>(
111 base::BindRepeating(
112 &SchedulingRemoteSuggestionsProvider::OnProviderStatusChanged,
113 base::Unretained(this))));
114 }
115
116 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() =
117 default;
118
119 // static
120 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs(
121 PrefRegistrySimple* registry) {
122 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalWifi, 0);
123 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalFallback,
124 0);
125 }
126
127 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() {
128 // Force the reschedule by stopping and starting it again.
129 StopScheduling();
130 StartScheduling();
131 }
132
133 void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() {
134 provider_->RefetchInTheBackground(
135 base::MakeUnique<RemoteSuggestionsProvider::FetchStatusCallback>(
136 base::Bind(&SchedulingRemoteSuggestionsProvider::OnFetchCompleted,
137 base::Unretained(this))));
138 }
139
140 void SchedulingRemoteSuggestionsProvider::SetProviderStatusCallback(
141 std::unique_ptr<ProviderStatusCallback> callback) {
142 provider_->SetProviderStatusCallback(std::move(callback));
143 }
144
145 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackground(
146 std::unique_ptr<FetchStatusCallback> callback) {
147 provider_->RefetchInTheBackground(std::move(callback));
148 }
149
150 const NTPSnippetsFetcher* SchedulingRemoteSuggestionsProvider::
151 snippets_fetcher_for_testing_and_debugging() const {
152 return provider_->snippets_fetcher_for_testing_and_debugging();
153 }
154
155 CategoryStatus SchedulingRemoteSuggestionsProvider::GetCategoryStatus(
156 Category category) {
157 return provider_->GetCategoryStatus(category);
158 }
159
160 CategoryInfo SchedulingRemoteSuggestionsProvider::GetCategoryInfo(
161 Category category) {
162 return provider_->GetCategoryInfo(category);
163 }
164
165 void SchedulingRemoteSuggestionsProvider::DismissSuggestion(
166 const ContentSuggestion::ID& suggestion_id) {
167 provider_->DismissSuggestion(suggestion_id);
168 }
169
170 void SchedulingRemoteSuggestionsProvider::FetchSuggestionImage(
171 const ContentSuggestion::ID& suggestion_id,
172 const ImageFetchedCallback& callback) {
173 provider_->FetchSuggestionImage(suggestion_id, callback);
174 }
175
176 void SchedulingRemoteSuggestionsProvider::Fetch(
177 const Category& category,
178 const std::set<std::string>& known_suggestion_ids,
179 const FetchDoneCallback& callback) {
180 provider_->Fetch(
181 category, known_suggestion_ids,
182 base::Bind(&SchedulingRemoteSuggestionsProvider::FetchFinished,
183 base::Unretained(this), callback));
184 }
185
186 void SchedulingRemoteSuggestionsProvider::ReloadSuggestions() {
187 provider_->ReloadSuggestions();
188 }
189
190 void SchedulingRemoteSuggestionsProvider::ClearHistory(
191 base::Time begin,
192 base::Time end,
193 const base::Callback<bool(const GURL& url)>& filter) {
194 provider_->ClearHistory(begin, end, filter);
195 }
196
197 void SchedulingRemoteSuggestionsProvider::ClearCachedSuggestions(
198 Category category) {
199 provider_->ClearCachedSuggestions(category);
200 }
201
202 void SchedulingRemoteSuggestionsProvider::OnSignInStateChanged() {
203 provider_->OnSignInStateChanged();
204 }
205
206 void SchedulingRemoteSuggestionsProvider::GetDismissedSuggestionsForDebugging(
207 Category category,
208 const DismissedSuggestionsCallback& callback) {
209 provider_->GetDismissedSuggestionsForDebugging(category, callback);
210 }
211
212 void SchedulingRemoteSuggestionsProvider::ClearDismissedSuggestionsForDebugging(
213 Category category) {
214 provider_->ClearDismissedSuggestionsForDebugging(category);
215 }
216
217 void SchedulingRemoteSuggestionsProvider::OnProviderStatusChanged(
218 RemoteSuggestionsProvider::ProviderStatus status) {
219 switch (status) {
220 case RemoteSuggestionsProvider::ProviderStatus::ACTIVE:
221 StartScheduling();
222 return;
223 case RemoteSuggestionsProvider::ProviderStatus::INACTIVE:
224 StopScheduling();
225 return;
226 }
227 NOTREACHED();
228 }
229
230 void SchedulingRemoteSuggestionsProvider::StartScheduling() {
231 // The scheduler only exists on Android so far, it's null on other platforms.
232 if (!persistent_scheduler_) {
233 return;
234 }
235
236 FetchingSchedule last_schedule = GetLastFetchingSchedule();
237 FetchingSchedule schedule = GetDesiredFetchingSchedule();
238
239 // Reset the schedule only if the parameters have changed.
240 if (last_schedule != schedule) {
241 ApplyFetchingSchedule(schedule);
242 }
243 }
244
245 void SchedulingRemoteSuggestionsProvider::StopScheduling() {
246 // The scheduler only exists on Android so far, it's null on other platforms.
247 if (!persistent_scheduler_) {
248 return;
249 }
250
251 // Do not unschedule if already switched off
252 FetchingSchedule last_schedule = GetLastFetchingSchedule();
253 if (last_schedule.is_empty()) {
254 return;
255 }
256
257 persistent_scheduler_->Unschedule();
258
259 StoreLastFetchingSchedule(FetchingSchedule::Empty());
260 }
261
262 void SchedulingRemoteSuggestionsProvider::ApplyFetchingSchedule(
263 const FetchingSchedule& schedule) {
264 persistent_scheduler_->Schedule(schedule.interval_wifi,
265 schedule.interval_fallback);
266
267 StoreLastFetchingSchedule(schedule);
268 }
269
270 SchedulingRemoteSuggestionsProvider::FetchingSchedule
271 SchedulingRemoteSuggestionsProvider::GetDesiredFetchingSchedule() const {
272 UserClassifier::UserClass user_class = user_classifier_->GetUserClass();
273
274 FetchingSchedule schedule;
275 schedule.interval_wifi =
276 GetDesiredUpdateInterval(/*is_wifi=*/true, user_class);
277 schedule.interval_fallback =
278 GetDesiredUpdateInterval(/*is_wifi=*/false, user_class);
279 return schedule;
280 }
281
282 SchedulingRemoteSuggestionsProvider::FetchingSchedule
283 SchedulingRemoteSuggestionsProvider::GetLastFetchingSchedule() const {
284 FetchingSchedule schedule;
285 schedule.interval_wifi = base::TimeDelta::FromInternalValue(
286 pref_service_->GetInt64(prefs::kSnippetBackgroundFetchingIntervalWifi));
287 schedule.interval_fallback =
288 base::TimeDelta::FromInternalValue(pref_service_->GetInt64(
289 prefs::kSnippetBackgroundFetchingIntervalFallback));
290 return schedule;
291 }
292
293 void SchedulingRemoteSuggestionsProvider::StoreLastFetchingSchedule(
294 const FetchingSchedule& schedule) {
295 pref_service_->SetInt64(
296 prefs::kSnippetBackgroundFetchingIntervalWifi,
297 schedule.interval_wifi.ToInternalValue());
298 pref_service_->SetInt64(
299 prefs::kSnippetBackgroundFetchingIntervalFallback,
300 schedule.interval_fallback.ToInternalValue());
301 }
302
303 void SchedulingRemoteSuggestionsProvider::FetchFinished(
304 const FetchDoneCallback& callback,
305 Status status_code,
306 std::vector<ContentSuggestion> suggestions) {
307 OnFetchCompleted(status_code);
308 callback.Run(status_code, std::move(suggestions));
309 }
310
311 void SchedulingRemoteSuggestionsProvider::OnFetchCompleted(
312 Status fetch_status) {
313 // The scheduler only exists on Android so far, it's null on other platforms.
314 if (!persistent_scheduler_) {
315 return;
316 }
317
318 if (fetch_status.code != StatusCode::SUCCESS) {
319 return;
320 }
321
322 // Reschedule after a successful fetch. This resets all currently scheduled
323 // fetches, to make sure the fallback interval triggers only if no wifi fetch
324 // succeeded, and also that we don't do a background fetch immediately after
325 // a user-initiated one.
326 ApplyFetchingSchedule(GetLastFetchingSchedule());
327 }
328
329 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698