• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 "chrome/browser/web_resource/web_resource_service.h"
6 
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h"
14 #include "base/values.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/google/google_util.h"
17 #include "net/base/load_flags.h"
18 #include "net/url_request/url_fetcher.h"
19 #include "net/url_request/url_request_status.h"
20 #include "url/gurl.h"
21 
WebResourceService(PrefService * prefs,const GURL & web_resource_server,bool apply_locale_to_url,const char * last_update_time_pref_name,int start_fetch_delay_ms,int cache_update_delay_ms)22 WebResourceService::WebResourceService(
23     PrefService* prefs,
24     const GURL& web_resource_server,
25     bool apply_locale_to_url,
26     const char* last_update_time_pref_name,
27     int start_fetch_delay_ms,
28     int cache_update_delay_ms)
29     : prefs_(prefs),
30       json_unpacker_(NULL),
31       in_fetch_(false),
32       web_resource_server_(web_resource_server),
33       apply_locale_to_url_(apply_locale_to_url),
34       last_update_time_pref_name_(last_update_time_pref_name),
35       start_fetch_delay_ms_(start_fetch_delay_ms),
36       cache_update_delay_ms_(cache_update_delay_ms),
37       weak_ptr_factory_(this) {
38   resource_request_allowed_notifier_.Init(this);
39   DCHECK(prefs);
40 }
41 
~WebResourceService()42 WebResourceService::~WebResourceService() {
43   if (in_fetch_)
44     EndFetch();
45 }
46 
OnUnpackFinished(const DictionaryValue & parsed_json)47 void WebResourceService::OnUnpackFinished(const DictionaryValue& parsed_json) {
48   Unpack(parsed_json);
49   EndFetch();
50 }
51 
OnUnpackError(const std::string & error_message)52 void WebResourceService::OnUnpackError(const std::string& error_message) {
53   LOG(ERROR) << error_message;
54   EndFetch();
55 }
56 
EndFetch()57 void WebResourceService::EndFetch() {
58   if (json_unpacker_) {
59     json_unpacker_->ClearDelegate();
60     json_unpacker_ = NULL;
61   }
62   in_fetch_ = false;
63 }
64 
StartAfterDelay()65 void WebResourceService::StartAfterDelay() {
66   // If resource requests are not allowed, we'll get a callback when they are.
67   if (resource_request_allowed_notifier_.ResourceRequestsAllowed())
68     OnResourceRequestsAllowed();
69 }
70 
OnResourceRequestsAllowed()71 void WebResourceService::OnResourceRequestsAllowed() {
72   int64 delay = start_fetch_delay_ms_;
73   // Check whether we have ever put a value in the web resource cache;
74   // if so, pull it out and see if it's time to update again.
75   if (prefs_->HasPrefPath(last_update_time_pref_name_)) {
76     std::string last_update_pref =
77         prefs_->GetString(last_update_time_pref_name_);
78     if (!last_update_pref.empty()) {
79       double last_update_value;
80       base::StringToDouble(last_update_pref, &last_update_value);
81       int64 ms_until_update = cache_update_delay_ms_ -
82           static_cast<int64>((base::Time::Now() - base::Time::FromDoubleT(
83           last_update_value)).InMilliseconds());
84       // Wait at least |start_fetch_delay_ms_|.
85       if (ms_until_update > start_fetch_delay_ms_)
86         delay = ms_until_update;
87     }
88   }
89   // Start fetch and wait for UpdateResourceCache.
90   ScheduleFetch(delay);
91 }
92 
93 // Delay initial load of resource data into cache so as not to interfere
94 // with startup time.
ScheduleFetch(int64 delay_ms)95 void WebResourceService::ScheduleFetch(int64 delay_ms) {
96   base::MessageLoop::current()->PostDelayedTask(
97       FROM_HERE,
98       base::Bind(&WebResourceService::StartFetch,
99                  weak_ptr_factory_.GetWeakPtr()),
100       base::TimeDelta::FromMilliseconds(delay_ms));
101 }
102 
103 // Initializes the fetching of data from the resource server.  Data
104 // load calls OnURLFetchComplete.
StartFetch()105 void WebResourceService::StartFetch() {
106   // First, put our next cache load on the MessageLoop.
107   ScheduleFetch(cache_update_delay_ms_);
108 
109   // Set cache update time in preferences.
110   prefs_->SetString(last_update_time_pref_name_,
111       base::DoubleToString(base::Time::Now().ToDoubleT()));
112 
113   // If we are still fetching data, exit.
114   if (in_fetch_)
115     return;
116   in_fetch_ = true;
117 
118   // Balanced in OnURLFetchComplete.
119   AddRef();
120 
121   GURL web_resource_server = apply_locale_to_url_ ?
122       google_util::AppendGoogleLocaleParam(web_resource_server_) :
123       web_resource_server_;
124 
125   DVLOG(1) << "WebResourceService StartFetch " << web_resource_server;
126   url_fetcher_.reset(net::URLFetcher::Create(
127       web_resource_server, net::URLFetcher::GET, this));
128   // Do not let url fetcher affect existing state in system context
129   // (by setting cookies, for example).
130   url_fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE |
131                              net::LOAD_DO_NOT_SEND_COOKIES |
132                              net::LOAD_DO_NOT_SAVE_COOKIES);
133   net::URLRequestContextGetter* url_request_context_getter =
134       g_browser_process->system_request_context();
135   url_fetcher_->SetRequestContext(url_request_context_getter);
136   url_fetcher_->Start();
137 }
138 
OnURLFetchComplete(const net::URLFetcher * source)139 void WebResourceService::OnURLFetchComplete(const net::URLFetcher* source) {
140   // Delete the URLFetcher when this function exits.
141   scoped_ptr<net::URLFetcher> clean_up_fetcher(url_fetcher_.release());
142 
143   if (source->GetStatus().is_success() && source->GetResponseCode() == 200) {
144     std::string data;
145     source->GetResponseAsString(&data);
146 
147     // UnpackerClient calls EndFetch and releases itself on completion.
148     json_unpacker_ = JSONAsynchronousUnpacker::Create(this);
149     json_unpacker_->Start(data);
150   } else {
151     // Don't parse data if attempt to download was unsuccessful.
152     // Stop loading new web resource data, and silently exit.
153     // We do not call UnpackerClient, so we need to call EndFetch ourselves.
154     EndFetch();
155   }
156 
157   Release();
158 }
159