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

Side by Side Diff: components/ntp_snippets/remote/remote_suggestions_provider_impl.h

Issue 2557363002: [NTP Snippets] Refactor background scheduling for remote suggestions (Closed)
Patch Set: Fixing the last changes :) Created 3 years, 12 months 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
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 #ifndef COMPONENTS_NTP_SNIPPETS_REMOTE_REMOTE_SUGGESTIONS_PROVIDER_H_ 5 #ifndef COMPONENTS_NTP_SNIPPETS_REMOTE_REMOTE_SUGGESTIONS_PROVIDER_IMPL_H_
6 #define COMPONENTS_NTP_SNIPPETS_REMOTE_REMOTE_SUGGESTIONS_PROVIDER_H_ 6 #define COMPONENTS_NTP_SNIPPETS_REMOTE_REMOTE_SUGGESTIONS_PROVIDER_IMPL_H_
7 7
8 #include <cstddef> 8 #include <cstddef>
9 #include <deque> 9 #include <deque>
10 #include <map> 10 #include <map>
11 #include <memory> 11 #include <memory>
12 #include <set> 12 #include <set>
13 #include <string> 13 #include <string>
14 #include <utility> 14 #include <utility>
15 #include <vector> 15 #include <vector>
16 16
17 #include "base/callback_forward.h" 17 #include "base/callback_forward.h"
18 #include "base/gtest_prod_util.h" 18 #include "base/gtest_prod_util.h"
19 #include "base/macros.h" 19 #include "base/macros.h"
20 #include "base/time/clock.h" 20 #include "base/time/clock.h"
21 #include "base/time/time.h" 21 #include "base/time/time.h"
22 #include "components/image_fetcher/image_fetcher_delegate.h" 22 #include "components/image_fetcher/image_fetcher_delegate.h"
23 #include "components/ntp_snippets/category.h" 23 #include "components/ntp_snippets/category.h"
24 #include "components/ntp_snippets/category_status.h" 24 #include "components/ntp_snippets/category_status.h"
25 #include "components/ntp_snippets/content_suggestion.h" 25 #include "components/ntp_snippets/content_suggestion.h"
26 #include "components/ntp_snippets/content_suggestions_provider.h" 26 #include "components/ntp_snippets/content_suggestions_provider.h"
27 #include "components/ntp_snippets/remote/ntp_snippet.h" 27 #include "components/ntp_snippets/remote/ntp_snippet.h"
28 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h" 28 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h"
29 #include "components/ntp_snippets/remote/ntp_snippets_request_params.h" 29 #include "components/ntp_snippets/remote/ntp_snippets_request_params.h"
30 #include "components/ntp_snippets/remote/ntp_snippets_scheduler.h" 30 #include "components/ntp_snippets/remote/remote_suggestions_provider.h"
31 #include "components/ntp_snippets/remote/remote_suggestions_status_service.h" 31 #include "components/ntp_snippets/remote/remote_suggestions_status_service.h"
32 #include "components/ntp_snippets/remote/request_throttler.h" 32 #include "components/ntp_snippets/remote/request_throttler.h"
33 33
34 class PrefRegistrySimple; 34 class PrefRegistrySimple;
35 class PrefService; 35 class PrefService;
36 36
37 namespace gfx { 37 namespace gfx {
38 class Image; 38 class Image;
39 } // namespace gfx 39 } // namespace gfx
40 40
41 namespace image_fetcher { 41 namespace image_fetcher {
42 class ImageDecoder; 42 class ImageDecoder;
43 class ImageFetcher; 43 class ImageFetcher;
44 } // namespace image_fetcher 44 } // namespace image_fetcher
45 45
46 namespace ntp_snippets { 46 namespace ntp_snippets {
47 47
48 class CategoryRanker;
48 class RemoteSuggestionsDatabase; 49 class RemoteSuggestionsDatabase;
49 class CategoryRanker;
50 class UserClassifier;
51 50
52 // CachedImageFetcher takes care of fetching images from the network and caching 51 // CachedImageFetcher takes care of fetching images from the network and caching
53 // them in the database. 52 // them in the database.
54 // TODO(tschumann): Move into a separate library and inject the 53 // TODO(tschumann): Move into a separate library and inject the
55 // CachedImageFetcher into the RemoteSuggestionsProvider. This allows us to get 54 // CachedImageFetcher into the RemoteSuggestionsProvider. This allows us to get
56 // rid of exposing this member for testing and lets us test the caching logic 55 // rid of exposing this member for testing and lets us test the caching logic
57 // separately. 56 // separately.
58 class CachedImageFetcher : public image_fetcher::ImageFetcherDelegate { 57 class CachedImageFetcher : public image_fetcher::ImageFetcherDelegate {
59 public: 58 public:
60 // |pref_service| and |database| need to outlive the created image fetcher 59 // |pref_service| and |database| need to outlive the created image fetcher
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 RequestThrottler thumbnail_requests_throttler_; 99 RequestThrottler thumbnail_requests_throttler_;
101 100
102 DISALLOW_COPY_AND_ASSIGN(CachedImageFetcher); 101 DISALLOW_COPY_AND_ASSIGN(CachedImageFetcher);
103 }; 102 };
104 103
105 // Retrieves fresh content data (articles) from the server, stores them and 104 // Retrieves fresh content data (articles) from the server, stores them and
106 // provides them as content suggestions. 105 // provides them as content suggestions.
107 // This class is final because it does things in its constructor which make it 106 // This class is final because it does things in its constructor which make it
108 // unsafe to derive from it. 107 // unsafe to derive from it.
109 // TODO(treib): Introduce two-phase initialization and make the class not final? 108 // TODO(treib): Introduce two-phase initialization and make the class not final?
110 class RemoteSuggestionsProvider final : public ContentSuggestionsProvider { 109 class RemoteSuggestionsProviderImpl final : public RemoteSuggestionsProvider {
111 public: 110 public:
112 // |application_language_code| should be a ISO 639-1 compliant string, e.g. 111 // |application_language_code| should be a ISO 639-1 compliant string, e.g.
113 // 'en' or 'en-US'. Note that this code should only specify the language, not 112 // 'en' or 'en-US'. Note that this code should only specify the language, not
114 // the locale, so 'en_US' (English language with US locale) and 'en-GB_US' 113 // the locale, so 'en_US' (English language with US locale) and 'en-GB_US'
115 // (British English person in the US) are not language codes. 114 // (British English person in the US) are not language codes.
116 RemoteSuggestionsProvider( 115 RemoteSuggestionsProviderImpl(
117 Observer* observer, 116 Observer* observer,
118 PrefService* pref_service, 117 PrefService* pref_service,
119 const std::string& application_language_code, 118 const std::string& application_language_code,
120 CategoryRanker* category_ranker, 119 CategoryRanker* category_ranker,
121 const UserClassifier* user_classifier,
122 NTPSnippetsScheduler* scheduler,
123 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, 120 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher,
124 std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher, 121 std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher,
125 std::unique_ptr<image_fetcher::ImageDecoder> image_decoder, 122 std::unique_ptr<image_fetcher::ImageDecoder> image_decoder,
126 std::unique_ptr<RemoteSuggestionsDatabase> database, 123 std::unique_ptr<RemoteSuggestionsDatabase> database,
127 std::unique_ptr<RemoteSuggestionsStatusService> status_service); 124 std::unique_ptr<RemoteSuggestionsStatusService> status_service);
128 125
129 ~RemoteSuggestionsProvider() override; 126 ~RemoteSuggestionsProviderImpl() override;
130 127
131 static void RegisterProfilePrefs(PrefRegistrySimple* registry); 128 static void RegisterProfilePrefs(PrefRegistrySimple* registry);
132 129
133 // Returns whether the service is ready. While this is false, the list of 130 // Returns whether the service is ready. While this is false, the list of
134 // snippets will be empty, and all modifications to it (fetch, dismiss, etc) 131 // snippets will be empty, and all modifications to it (fetch, dismiss, etc)
135 // will be ignored. 132 // will be ignored.
136 bool ready() const { return state_ == State::READY; } 133 bool ready() const { return state_ == State::READY; }
137 134
138 // Returns whether the service is initialized. While this is false, some 135 // Returns whether the service is successfully initialized. While this is
139 // calls may trigger DCHECKs. 136 // false, some calls may trigger DCHECKs.
140 bool initialized() const { return ready() || state_ == State::DISABLED; } 137 bool initialized() const { return ready() || state_ == State::DISABLED; }
141 138
142 // Fetchs content suggestions from the Content Suggestions server for all 139 // RemoteSuggestionsProvider implementation.
143 // remote categories in the background. 140 void SetProviderStatusCallback(
144 void FetchSnippetsInTheBackground(); 141 std::unique_ptr<ProviderStatusCallback> callback) override;
142 void RefetchInTheBackground(
143 std::unique_ptr<FetchStatusCallback> callback) override;
145 144
146 // Fetchs content suggestions from the Content Suggestions server for all
147 // remote categories. The request to the server is performed as an interactive
148 // request. Interactive requests are used for actions triggered by the user
149 // and request lower latency processing.
150 void FetchSnippetsForAllCategories();
151
152 // Only used in tests and for debugging in snippets-internal/.
153 // TODO(fhorschig): Remove this getter when there is an interface for the 145 // TODO(fhorschig): Remove this getter when there is an interface for the
154 // fetcher that allows better mocks. 146 // fetcher that allows better mocks.
155 const NTPSnippetsFetcher* snippets_fetcher() const { 147 const NTPSnippetsFetcher* snippets_fetcher_for_testing_and_debugging()
156 return snippets_fetcher_.get(); 148 const override;
157 }
158 149
159 // (Re)schedules the periodic fetching of snippets. If |force| is true, the 150 // ContentSuggestionsProvider implementation.
160 // tasks will be re-scheduled even if they already exist and have the correct
161 // periods.
162 void RescheduleFetching(bool force);
163
164 // ContentSuggestionsProvider implementation
165 CategoryStatus GetCategoryStatus(Category category) override; 151 CategoryStatus GetCategoryStatus(Category category) override;
166 CategoryInfo GetCategoryInfo(Category category) override; 152 CategoryInfo GetCategoryInfo(Category category) override;
167 void DismissSuggestion(const ContentSuggestion::ID& suggestion_id) override; 153 void DismissSuggestion(const ContentSuggestion::ID& suggestion_id) override;
168 void FetchSuggestionImage(const ContentSuggestion::ID& suggestion_id, 154 void FetchSuggestionImage(const ContentSuggestion::ID& suggestion_id,
169 const ImageFetchedCallback& callback) override; 155 const ImageFetchedCallback& callback) override;
170 void Fetch(const Category& category, 156 void Fetch(const Category& category,
171 const std::set<std::string>& known_suggestion_ids, 157 const std::set<std::string>& known_suggestion_ids,
172 const FetchDoneCallback& callback) override; 158 const FetchDoneCallback& callback) override;
159 void ReloadSuggestions() override;
173 void ClearHistory( 160 void ClearHistory(
174 base::Time begin, 161 base::Time begin,
175 base::Time end, 162 base::Time end,
176 const base::Callback<bool(const GURL& url)>& filter) override; 163 const base::Callback<bool(const GURL& url)>& filter) override;
177 void ClearCachedSuggestions(Category category) override; 164 void ClearCachedSuggestions(Category category) override;
178 void OnSignInStateChanged() override; 165 void OnSignInStateChanged() override;
179 void GetDismissedSuggestionsForDebugging( 166 void GetDismissedSuggestionsForDebugging(
180 Category category, 167 Category category,
181 const DismissedSuggestionsCallback& callback) override; 168 const DismissedSuggestionsCallback& callback) override;
182 void ClearDismissedSuggestionsForDebugging(Category category) override; 169 void ClearDismissedSuggestionsForDebugging(Category category) override;
(...skipping 16 matching lines...) Expand all
199 // Overrides internal clock for testing purposes. 186 // Overrides internal clock for testing purposes.
200 void SetClockForTesting(std::unique_ptr<base::Clock> clock) { 187 void SetClockForTesting(std::unique_ptr<base::Clock> clock) {
201 clock_ = std::move(clock); 188 clock_ = std::move(clock);
202 } 189 }
203 190
204 // TODO(tschumann): remove this method as soon as we inject the fetcher into 191 // TODO(tschumann): remove this method as soon as we inject the fetcher into
205 // the constructor. 192 // the constructor.
206 CachedImageFetcher& GetImageFetcherForTesting() { return image_fetcher_; } 193 CachedImageFetcher& GetImageFetcherForTesting() { return image_fetcher_; }
207 194
208 private: 195 private:
209 friend class RemoteSuggestionsProviderTest; 196 friend class RemoteSuggestionsProviderImplTest;
210 197
211 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderTest, 198 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderImplTest,
199 CallsProviderStatusCallbackWhenReady);
200 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderImplTest,
201 CallsProviderStatusCallbackOnError);
202 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderImplTest,
203 CallsProviderStatusCallbackWhenDisabled);
204 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderImplTest,
205 ShouldNotCrashWhenCallingEmptyCallback);
206 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderImplTest,
212 DontNotifyIfNotAvailable); 207 DontNotifyIfNotAvailable);
213 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderTest, 208 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderImplTest,
214 RemoveExpiredDismissedContent); 209 RemoveExpiredDismissedContent);
215 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderTest, 210 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderImplTest, StatusChanges);
216 RescheduleOnStateChange); 211 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderImplTest,
217 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderTest, StatusChanges);
218 FRIEND_TEST_ALL_PREFIXES(RemoteSuggestionsProviderTest,
219 SuggestionsFetchedOnSignInAndSignOut); 212 SuggestionsFetchedOnSignInAndSignOut);
220 213
221 // Possible state transitions: 214 // Possible state transitions:
222 // NOT_INITED --------+ 215 // NOT_INITED --------+
223 // / \ | 216 // / \ |
224 // v v | 217 // v v |
225 // READY <--> DISABLED | 218 // READY <--> DISABLED |
226 // \ / | 219 // \ / |
227 // v v | 220 // v v |
228 // ERROR_OCCURRED <-----+ 221 // ERROR_OCCURRED <-----+
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 282
290 explicit CategoryContent(const CategoryInfo& info); 283 explicit CategoryContent(const CategoryInfo& info);
291 CategoryContent(CategoryContent&&); 284 CategoryContent(CategoryContent&&);
292 ~CategoryContent(); 285 ~CategoryContent();
293 CategoryContent& operator=(CategoryContent&&); 286 CategoryContent& operator=(CategoryContent&&);
294 }; 287 };
295 288
296 // Fetches snippets from the server and replaces old snippets by the new ones. 289 // Fetches snippets from the server and replaces old snippets by the new ones.
297 // Requests can be marked more important by setting |interactive_request| to 290 // Requests can be marked more important by setting |interactive_request| to
298 // true (such request might circumvent the daily quota for requests, etc.) 291 // true (such request might circumvent the daily quota for requests, etc.)
299 // Useful for requests triggered by the user. 292 // Useful for requests triggered by the user. After the fetch finished, the
300 void FetchSnippets(bool interactive_request); 293 // provided |callback| will be triggered with the status of the fetch.
294 void FetchSnippets(bool interactive_request,
295 std::unique_ptr<FetchStatusCallback> callback);
301 296
302 // Returns the URL of the image of a snippet if it is among the current or 297 // Returns the URL of the image of a snippet if it is among the current or
303 // among the archived snippets in the matching category. Returns an empty URL 298 // among the archived snippets in the matching category. Returns an empty URL
304 // otherwise. 299 // otherwise.
305 GURL FindSnippetImageUrl(const ContentSuggestion::ID& suggestion_id) const; 300 GURL FindSnippetImageUrl(const ContentSuggestion::ID& suggestion_id) const;
306 301
307 // Callbacks for the RemoteSuggestionsDatabase. 302 // Callbacks for the RemoteSuggestionsDatabase.
308 void OnDatabaseLoaded(NTPSnippet::PtrVector snippets); 303 void OnDatabaseLoaded(NTPSnippet::PtrVector snippets);
309 void OnDatabaseError(); 304 void OnDatabaseError();
310 305
311 // Callback for fetch-more requests with the NTPSnippetsFetcher. 306 // Callback for fetch-more requests with the NTPSnippetsFetcher.
312 void OnFetchMoreFinished( 307 void OnFetchMoreFinished(
313 const FetchDoneCallback& fetching_callback, 308 const FetchDoneCallback& fetching_callback,
314 Status status, 309 Status status,
315 NTPSnippetsFetcher::OptionalFetchedCategories fetched_categories); 310 NTPSnippetsFetcher::OptionalFetchedCategories fetched_categories);
316 311
317 // Callback for regular fetch requests with the NTPSnippetsFetcher. 312 // Callback for regular fetch requests with the NTPSnippetsFetcher.
318 void OnFetchFinished( 313 void OnFetchFinished(
314 std::unique_ptr<FetchStatusCallback> callback,
319 bool interactive_request, 315 bool interactive_request,
320 Status status, 316 Status status,
321 NTPSnippetsFetcher::OptionalFetchedCategories fetched_categories); 317 NTPSnippetsFetcher::OptionalFetchedCategories fetched_categories);
322 318
323 // Moves all snippets from |to_archive| into the archive of the |content|. 319 // Moves all snippets from |to_archive| into the archive of the |content|.
324 // Clears |to_archive|. As the archive is a FIFO buffer of limited size, this 320 // Clears |to_archive|. As the archive is a FIFO buffer of limited size, this
325 // function will also delete images from the database in case the associated 321 // function will also delete images from the database in case the associated
326 // snippet gets evicted from the archive. 322 // snippet gets evicted from the archive.
327 void ArchiveSnippets(CategoryContent* content, 323 void ArchiveSnippets(CategoryContent* content,
328 NTPSnippet::PtrVector* to_archive); 324 NTPSnippet::PtrVector* to_archive);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 // Triggers a state transition depending on the provided status. This method 357 // Triggers a state transition depending on the provided status. This method
362 // is called when a change is detected by |status_service_|. 358 // is called when a change is detected by |status_service_|.
363 void OnStatusChanged(RemoteSuggestionsStatus old_status, 359 void OnStatusChanged(RemoteSuggestionsStatus old_status,
364 RemoteSuggestionsStatus new_status); 360 RemoteSuggestionsStatus new_status);
365 361
366 // Verifies state transitions (see |State|'s documentation) and applies them. 362 // Verifies state transitions (see |State|'s documentation) and applies them.
367 // Also updates the provider status. Does nothing except updating the provider 363 // Also updates the provider status. Does nothing except updating the provider
368 // status if called with the current state. 364 // status if called with the current state.
369 void EnterState(State state); 365 void EnterState(State state);
370 366
367 // Notifies the state change to ProviderStatusCallback specified by
368 // SetProviderStatusCallback().
369 void NotifyStateChanged();
370
371 // Enables the service. Do not call directly, use |EnterState| instead. 371 // Enables the service. Do not call directly, use |EnterState| instead.
372 void EnterStateReady(); 372 void EnterStateReady();
373 373
374 // Disables the service. Do not call directly, use |EnterState| instead. 374 // Disables the service. Do not call directly, use |EnterState| instead.
375 void EnterStateDisabled(); 375 void EnterStateDisabled();
376 376
377 // Disables the service permanently because an unrecoverable error occurred. 377 // Disables the service permanently because an unrecoverable error occurred.
378 // Do not call directly, use |EnterState| instead. 378 // Do not call directly, use |EnterState| instead.
379 void EnterStateError(); 379 void EnterStateError();
380 380
(...skipping 27 matching lines...) Expand all
408 const Category articles_category_; 408 const Category articles_category_;
409 409
410 std::map<Category, CategoryContent, Category::CompareByID> category_contents_; 410 std::map<Category, CategoryContent, Category::CompareByID> category_contents_;
411 411
412 // The ISO 639-1 code of the language used by the application. 412 // The ISO 639-1 code of the language used by the application.
413 const std::string application_language_code_; 413 const std::string application_language_code_;
414 414
415 // Ranker that orders the categories. Not owned. 415 // Ranker that orders the categories. Not owned.
416 CategoryRanker* category_ranker_; 416 CategoryRanker* category_ranker_;
417 417
418 // Classifier that tells us how active the user is. Not owned.
419 const UserClassifier* user_classifier_;
420
421 // Scheduler for fetching snippets. Not owned.
422 NTPSnippetsScheduler* scheduler_;
423
424 // The snippets fetcher. 418 // The snippets fetcher.
425 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher_; 419 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher_;
426 420
427 // The database for persisting snippets. 421 // The database for persisting snippets.
428 std::unique_ptr<RemoteSuggestionsDatabase> database_; 422 std::unique_ptr<RemoteSuggestionsDatabase> database_;
429 base::TimeTicks database_load_start_; 423 base::TimeTicks database_load_start_;
430 424
431 // The image fetcher. 425 // The image fetcher.
432 CachedImageFetcher image_fetcher_; 426 CachedImageFetcher image_fetcher_;
433 427
434 // The service that provides events and data about the signin and sync state. 428 // The service that provides events and data about the signin and sync state.
435 std::unique_ptr<RemoteSuggestionsStatusService> status_service_; 429 std::unique_ptr<RemoteSuggestionsStatusService> status_service_;
436 430
437 // Set to true if FetchSnippets is called while the service isn't ready. 431 // Set to true if FetchSnippets is called while the service isn't ready.
438 // The fetch will be executed once the service enters the READY state. 432 // The fetch will be executed once the service enters the READY state.
433 // TODO(jkrcal): create a struct and have here just one base::Optional<>?
439 bool fetch_when_ready_; 434 bool fetch_when_ready_;
440 435
436 // The parameters for the fetch to perform later.
437 bool fetch_when_ready_interactive_;
438 std::unique_ptr<FetchStatusCallback> fetch_when_ready_callback_;
439
440 std::unique_ptr<ProviderStatusCallback> provider_status_callback_;
441
441 // Set to true if NukeAllSnippets is called while the service isn't ready. 442 // Set to true if NukeAllSnippets is called while the service isn't ready.
442 // The nuke will be executed once the service finishes initialization or 443 // The nuke will be executed once the service finishes initialization or
443 // enters the READY state. 444 // enters the READY state.
444 bool nuke_when_initialized_; 445 bool nuke_when_initialized_;
445 446
446 // A clock for getting the time. This allows to inject a clock in tests. 447 // A clock for getting the time. This allows to inject a clock in tests.
447 std::unique_ptr<base::Clock> clock_; 448 std::unique_ptr<base::Clock> clock_;
448 449
449 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsProvider); 450 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsProviderImpl);
450 }; 451 };
451 452
452 } // namespace ntp_snippets 453 } // namespace ntp_snippets
453 454
454 #endif // COMPONENTS_NTP_SNIPPETS_REMOTE_REMOTE_SUGGESTIONS_PROVIDER_H_ 455 #endif // COMPONENTS_NTP_SNIPPETS_REMOTE_REMOTE_SUGGESTIONS_PROVIDER_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698