15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef COMPONENTS_SUGGESTIONS_SUGGESTIONS_SERVICE_H_ 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define COMPONENTS_SUGGESTIONS_SUGGESTIONS_SERVICE_H_ 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <string> 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <vector> 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/callback.h" 13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/cancelable_callback.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/gtest_prod_util.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/memory/weak_ptr.h" 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/threading/thread_checker.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/time/time.h" 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/core/keyed_service.h" 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/suggestions/image_manager.h" 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/suggestions/proto/suggestions.pb.h" 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/suggestions/suggestions_utils.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h" 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/gfx/image/image_skia.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "url/gurl.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace net { 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass URLRequestContextGetter; 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace net 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace user_prefs { 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class PrefRegistrySyncable; 33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace user_prefs 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace suggestions { 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass BlacklistStore; 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class SuggestionsStore; 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)extern const char kSuggestionsFieldTrialName[]; 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)extern const char kSuggestionsFieldTrialURLParam[]; 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdochextern const char kSuggestionsFieldTrialCommonParamsParam[]; 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdochextern const char kSuggestionsFieldTrialBlacklistPathParam[]; 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdochextern const char kSuggestionsFieldTrialBlacklistUrlParam[]; 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)extern const char kSuggestionsFieldTrialStateParam[]; 466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)extern const char kSuggestionsFieldTrialControlParam[]; 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)extern const char kSuggestionsFieldTrialStateEnabled[]; 486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)extern const int64 kDefaultExpiryUsec; 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// An interface to fetch server suggestions asynchronously. 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class SuggestionsService : public KeyedService, public net::URLFetcherDelegate { 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef base::Callback<void(const SuggestionsProfile&)> ResponseCallback; 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SuggestionsService( 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net::URLRequestContextGetter* url_request_context, 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<SuggestionsStore> suggestions_store, 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<ImageManager> thumbnail_manager, 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<BlacklistStore> blacklist_store); 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~SuggestionsService(); 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Whether this service is enabled. 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static bool IsEnabled(); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Whether the user is part of a control group. 666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) static bool IsControlGroup(); 676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Request suggestions data, which will be passed to |callback|. |sync_state| 6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // will influence the behavior of this function (see SyncState definition). 7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // |sync_state| must be specified based on the current state of the system 7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // (see suggestions::GetSyncState). Callers should call this function again if 7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // sync state changes. 7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // 7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If state allows for a network request, it is initiated unless a pending one 7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // exists. To prevent multiple requests, all |callback|s are placed in a queue 7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // and are updated simultaneously when the fetch completes. Also posts a task 7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // to execute OnRequestTimeout if the request hasn't completed in a given 7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // amount of time. 8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void FetchSuggestionsData(SyncState sync_state, 8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ResponseCallback callback); 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Retrieves stored thumbnail for website |url| asynchronously. Calls 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |callback| with Bitmap pointer if found, and NULL otherwise. 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void GetPageThumbnail( 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& url, 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Callback<void(const GURL&, const SkBitmap*)> callback); 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Issue a blacklist request. If there is already a blacklist request 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // in flight, the new blacklist request is ignored. 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void BlacklistURL(const GURL& candidate_url, 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ResponseCallback& callback); 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Determines which URL a blacklist request was for, irrespective of the 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // request's status. Returns false if |request| is not a blacklist request. 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static bool GetBlacklistedUrl(const net::URLFetcher& request, GURL* url); 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Register SuggestionsService related prefs in the Profile prefs. 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); 10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Sets default timestamp for suggestions which do not have expiry timestamp. 1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void SetDefaultExpiryTimestamp(SuggestionsProfile* suggestions, 1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int64 timestamp_usec); 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) friend class SuggestionsServiceTest; 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, BlacklistURLFails); 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, FetchSuggestionsData); 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, UpdateBlacklistDelay); 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Similar to FetchSuggestionsData but doesn't post a task to execute 11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // OnDelaySinceFetch. 11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void FetchSuggestionsDataNoTimeout(ResponseCallback callback); 11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Issue a request. 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void IssueRequest(const GURL& url); 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Creates a request to the suggestions service, properly setting headers. 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch net::URLFetcher* CreateSuggestionsRequest(const GURL& url); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Called to service the requestors if the issued suggestions request has 121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // not completed in a given amount of time. 122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual void OnRequestTimeout(); 123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // net::URLFetcherDelegate implementation. 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Called when fetch request completes. Parses the received suggestions data, 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // and dispatches them to callbacks stored in queue. 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // KeyedService implementation. 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void Shutdown() OVERRIDE; 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Load the cached suggestions and service the requestors with them. 133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void ServeFromCache(); 134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Apply the local blacklist to |suggestions|, then serve the requestors. 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void FilterAndServe(SuggestionsProfile* suggestions); 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Schedule a blacklisting request if the local blacklist isn't empty. 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // |last_request_successful| is used for exponentially backing off when 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // requests fail. 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void ScheduleBlacklistUpload(bool last_request_successful); 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If the local blacklist isn't empty, pick a URL from it and issue a 144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // blacklist request for it. 145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void UploadOneFromBlacklist(); 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Updates |blacklist_delay_sec_| based on the success of the last request. 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void UpdateBlacklistDelay(bool last_request_successful); 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Test seams. 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int blacklist_delay() const { return blacklist_delay_sec_; } 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void set_blacklist_delay(int delay) { blacklist_delay_sec_ = delay; } 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::ThreadChecker thread_checker_; 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // The cache for the suggestions. 157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SuggestionsStore> suggestions_store_; 158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The local cache for temporary blacklist, until uploaded to the server. 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<BlacklistStore> blacklist_store_; 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Contains the current suggestions fetch request. Will only have a value 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // while a request is pending, and will be reset by |OnURLFetchComplete|. 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<net::URLFetcher> pending_request_; 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // A closure that is run on a timeout from issuing the suggestions fetch 167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // request, if the request hasn't completed. 168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<base::CancelableClosure> pending_timeout_closure_; 169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The start time of the previous suggestions request. This is used to measure 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // the latency of requests. Initially zero. 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeTicks last_request_started_time_; 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The URL to fetch suggestions data from. 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL suggestions_url_; 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Prefix for building the blacklisting URL. 17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string blacklist_url_prefix_; 17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Queue of callbacks. These are flushed when fetch request completes. 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<ResponseCallback> waiting_requestors_; 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Used to obtain server thumbnails, if available. 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<ImageManager> thumbnail_manager_; 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch net::URLRequestContextGetter* url_request_context_; 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Delay used when scheduling a blacklisting task. 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int blacklist_delay_sec_; 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Timeout (in ms) before serving requestors after a fetch suggestions request 192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // has been issued. 193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int request_timeout_ms_; 194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // For callbacks may be run after destruction. 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtrFactory<SuggestionsService> weak_ptr_factory_; 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SuggestionsService); 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace suggestions 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif // COMPONENTS_SUGGESTIONS_SUGGESTIONS_SERVICE_H_ 204