172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 43345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/web_resource/web_resource_service.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h" 83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/file_path.h" 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_util.h" 1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/threading/thread_restrictions.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/values.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/prefs/pref_service.h" 1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 18201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/sync/sync_ui_util.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_switches.h" 20201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/common/extensions/extension.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/net/url_fetcher.h" 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/common/web_resource/web_resource_unpacker.h" 23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/load_flags.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_status.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass WebResourceService::WebResourceFetcher 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : public URLFetcher::Delegate { 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit WebResourceFetcher(WebResourceService* web_resource_service) : 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ALLOW_THIS_IN_INITIALIZER_LIST(fetcher_factory_(this)), 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch web_resource_service_(web_resource_service) { 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Delay initial load of resource data into cache so as not to interfere 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // with startup time. 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void StartAfterDelay(int64 delay_ms) { 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->PostDelayedTask(FROM_HERE, 41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen fetcher_factory_.NewRunnableMethod(&WebResourceFetcher::StartFetch), 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delay_ms); 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Initializes the fetching of data from the resource server. Data 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // load calls OnURLFetchComplete. 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void StartFetch() { 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Balanced in OnURLFetchComplete. 493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick web_resource_service_->AddRef(); 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First, put our next cache load on the MessageLoop. 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->PostDelayedTask(FROM_HERE, 52201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch fetcher_factory_.NewRunnableMethod(&WebResourceFetcher::StartFetch), 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen web_resource_service_->cache_update_delay_); 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we are still fetching data, exit. 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (web_resource_service_->in_fetch_) 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch web_resource_service_->in_fetch_ = true; 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string web_resource_server = 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen web_resource_service_->web_resource_server_; 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (web_resource_service_->apply_locale_to_url_) { 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string locale = g_browser_process->GetApplicationLocale(); 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen web_resource_server.append(locale); 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetcher_.reset(new URLFetcher(GURL( 6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_resource_server), 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLFetcher::GET, this)); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Do not let url fetcher affect existing state in profile (by setting 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // cookies, for example. 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetcher_->set_load_flags(net::LOAD_DISABLE_CACHE | 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen net::LOAD_DO_NOT_SAVE_COOKIES); 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net::URLRequestContextGetter* url_request_context_getter = 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen web_resource_service_->profile_->GetRequestContext(); 7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen url_fetcher_->set_request_context(url_request_context_getter); 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetcher_->Start(); 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // From URLFetcher::Delegate. 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnURLFetchComplete(const URLFetcher* source, 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const net::URLRequestStatus& status, 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int response_code, 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ResponseCookies& cookies, 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& data) { 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Delete the URLFetcher when this function exits. 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<URLFetcher> clean_up_fetcher(url_fetcher_.release()); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't parse data if attempt to download was unsuccessful. 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Stop loading new web resource data, and silently exit. 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!status.is_success() || (response_code != 200)) 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch web_resource_service_->UpdateResourceCache(data); 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick web_resource_service_->Release(); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // So that we can delay our start so as not to affect start-up time; also, 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // so that we can schedule future cache updates. 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScopedRunnableMethodFactory<WebResourceFetcher> fetcher_factory_; 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The tool that fetches the url data from the server. 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<URLFetcher> url_fetcher_; 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Our owner and creator. Ref counted. 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick WebResourceService* web_resource_service_; 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This class coordinates a web resource unpack and parse task which is run in 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a separate process. Results are sent back to this class and routed to 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the WebResourceService. 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass WebResourceService::UnpackerClient 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : public UtilityProcessHost::Client { 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UnpackerClient(WebResourceService* web_resource_service, 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& json_data) 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : web_resource_service_(web_resource_service), 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch json_data_(json_data), got_response_(false) { 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Start() { 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddRef(); // balanced in Cleanup. 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(willchan): Look for a better signal of whether we're in a unit test 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // or not. Using |resource_dispatcher_host_| for this is pretty lame. 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we don't have a resource_dispatcher_host_, assume we're in 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a test and run the unpacker directly in-process. 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool use_utility_process = 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch web_resource_service_->resource_dispatcher_host_ != NULL && 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess); 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (use_utility_process) { 134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::ID thread_id; 135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_id)); 136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::IO, FROM_HERE, 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(this, &UnpackerClient::StartProcessOnIOThread, 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch thread_id)); 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebResourceUnpacker unpacker(json_data_); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (unpacker.Run()) { 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnUnpackWebResourceSucceeded(*unpacker.parsed_json()); 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnUnpackWebResourceFailed(unpacker.error_message()); 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~UnpackerClient() {} 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // UtilityProcessHost::Client 15421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual void OnProcessCrashed(int exit_code) { 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (got_response_) 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnUnpackWebResourceFailed( 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Chrome crashed while trying to retrieve web resources."); 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnUnpackWebResourceSucceeded( 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const DictionaryValue& parsed_json) { 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch web_resource_service_->OnWebResourceUnpacked(parsed_json); 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Cleanup(); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnUnpackWebResourceFailed(const std::string& error_message) { 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch web_resource_service_->EndFetch(); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Cleanup(); 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Release reference and set got_response_. 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Cleanup() { 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (got_response_) 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch got_response_ = true; 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Release(); 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void StartProcessOnIOThread(BrowserThread::ID thread_id) { 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UtilityProcessHost* host = new UtilityProcessHost(this, thread_id); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(mrc): get proper file path when we start using web resources 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that need to be unpacked. 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch host->StartWebResourceUnpacker(json_data_); 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<WebResourceService> web_resource_service_; 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Holds raw JSON string. 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& json_data_; 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // True if we got a response from the utility process and have cleaned up 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // already. 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool got_response_; 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 199dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenWebResourceService::WebResourceService( 200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Profile* profile, 201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PrefService* prefs, 202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const char* web_resource_server, 203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool apply_locale_to_url, 204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NotificationType::Type notification_type, 205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const char* last_update_time_pref_name, 206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int start_fetch_delay, 207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int cache_update_delay) 208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : prefs_(prefs), 209201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch profile_(profile), 210201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ALLOW_THIS_IN_INITIALIZER_LIST(service_factory_(this)), 211201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch in_fetch_(false), 212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen web_resource_server_(web_resource_server), 213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen apply_locale_to_url_(apply_locale_to_url), 214dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen notification_type_(notification_type), 215dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen last_update_time_pref_name_(last_update_time_pref_name), 216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen start_fetch_delay_(start_fetch_delay), 217dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen cache_update_delay_(cache_update_delay), 218201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch web_resource_update_scheduled_(false) { 219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(prefs); 220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(profile); 221dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->RegisterStringPref(last_update_time_pref_name, "0"); 222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen resource_dispatcher_host_ = g_browser_process->resource_dispatcher_host(); 223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen web_resource_fetcher_.reset(new WebResourceFetcher(this)); 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebResourceService::~WebResourceService() { } 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid WebResourceService::PostNotification(int64 delay_ms) { 229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (web_resource_update_scheduled_) 230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (delay_ms > 0) { 232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen web_resource_update_scheduled_ = true; 233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MessageLoop::current()->PostDelayedTask(FROM_HERE, 234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen service_factory_.NewRunnableMethod( 235dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen &WebResourceService::WebResourceStateChange), delay_ms); 236dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else if (delay_ms == 0) { 237dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WebResourceStateChange(); 238dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebResourceService::EndFetch() { 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch in_fetch_ = false; 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebResourceService::OnWebResourceUnpacked( 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const DictionaryValue& parsed_json) { 247dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Unpack(parsed_json); 2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EndFetch(); 2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 251201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid WebResourceService::WebResourceStateChange() { 252201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch web_resource_update_scheduled_ = false; 253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (notification_type_ == NotificationType::NOTIFICATION_TYPE_COUNT) 254dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 255201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NotificationService* service = NotificationService::current(); 256dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen service->Notify(notification_type_, 257201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch Source<WebResourceService>(this), 258201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NotificationService::NoDetails()); 259201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 260201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid WebResourceService::StartAfterDelay() { 262dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int64 delay = start_fetch_delay_; 2633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Check whether we have ever put a value in the web resource cache; 2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // if so, pull it out and see if it's time to update again. 265dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (prefs_->HasPrefPath(last_update_time_pref_name_)) { 2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string last_update_pref = 267dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->GetString(last_update_time_pref_name_); 2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!last_update_pref.empty()) { 2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick double last_update_value; 2703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringToDouble(last_update_pref, &last_update_value); 27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int64 ms_until_update = cache_update_delay_ - 27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static_cast<int64>((base::Time::Now() - base::Time::FromDoubleT( 2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick last_update_value)).InMilliseconds()); 274201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch delay = ms_until_update > cache_update_delay_ ? 275dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen cache_update_delay_ : (ms_until_update < start_fetch_delay_ ? 276dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen start_fetch_delay_ : ms_until_update); 2773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Start fetch and wait for UpdateResourceCache. 28072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_resource_fetcher_->StartAfterDelay(delay); 2813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid WebResourceService::UpdateResourceCache(const std::string& json_data) { 2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UnpackerClient* client = new UnpackerClient(this, json_data); 2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick client->Start(); 2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 287201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Set cache update time in preferences. 288dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->SetString(last_update_time_pref_name_, 2893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::DoubleToString(base::Time::Now().ToDoubleT())); 2903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 291