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 "components/google/core/browser/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 base::DictionaryValue & parsed_json)47 void WebResourceService::OnUnpackFinished(
48 const base::DictionaryValue& parsed_json) {
49 Unpack(parsed_json);
50 EndFetch();
51 }
52
OnUnpackError(const std::string & error_message)53 void WebResourceService::OnUnpackError(const std::string& error_message) {
54 LOG(ERROR) << error_message;
55 EndFetch();
56 }
57
EndFetch()58 void WebResourceService::EndFetch() {
59 if (json_unpacker_) {
60 json_unpacker_->ClearDelegate();
61 json_unpacker_ = NULL;
62 }
63 in_fetch_ = false;
64 }
65
StartAfterDelay()66 void WebResourceService::StartAfterDelay() {
67 // If resource requests are not allowed, we'll get a callback when they are.
68 if (resource_request_allowed_notifier_.ResourceRequestsAllowed())
69 OnResourceRequestsAllowed();
70 }
71
OnResourceRequestsAllowed()72 void WebResourceService::OnResourceRequestsAllowed() {
73 int64 delay = start_fetch_delay_ms_;
74 // Check whether we have ever put a value in the web resource cache;
75 // if so, pull it out and see if it's time to update again.
76 if (prefs_->HasPrefPath(last_update_time_pref_name_)) {
77 std::string last_update_pref =
78 prefs_->GetString(last_update_time_pref_name_);
79 if (!last_update_pref.empty()) {
80 double last_update_value;
81 base::StringToDouble(last_update_pref, &last_update_value);
82 int64 ms_until_update = cache_update_delay_ms_ -
83 static_cast<int64>((base::Time::Now() - base::Time::FromDoubleT(
84 last_update_value)).InMilliseconds());
85 // Wait at least |start_fetch_delay_ms_|.
86 if (ms_until_update > start_fetch_delay_ms_)
87 delay = ms_until_update;
88 }
89 }
90 // Start fetch and wait for UpdateResourceCache.
91 ScheduleFetch(delay);
92 }
93
94 // Delay initial load of resource data into cache so as not to interfere
95 // with startup time.
ScheduleFetch(int64 delay_ms)96 void WebResourceService::ScheduleFetch(int64 delay_ms) {
97 base::MessageLoop::current()->PostDelayedTask(
98 FROM_HERE,
99 base::Bind(&WebResourceService::StartFetch,
100 weak_ptr_factory_.GetWeakPtr()),
101 base::TimeDelta::FromMilliseconds(delay_ms));
102 }
103
104 // Initializes the fetching of data from the resource server. Data
105 // load calls OnURLFetchComplete.
StartFetch()106 void WebResourceService::StartFetch() {
107 // First, put our next cache load on the MessageLoop.
108 ScheduleFetch(cache_update_delay_ms_);
109
110 // Set cache update time in preferences.
111 prefs_->SetString(last_update_time_pref_name_,
112 base::DoubleToString(base::Time::Now().ToDoubleT()));
113
114 // If we are still fetching data, exit.
115 if (in_fetch_)
116 return;
117 in_fetch_ = true;
118
119 // Balanced in OnURLFetchComplete.
120 AddRef();
121
122 GURL web_resource_server =
123 apply_locale_to_url_
124 ? google_util::AppendGoogleLocaleParam(
125 web_resource_server_, g_browser_process->GetApplicationLocale())
126 : web_resource_server_;
127
128 DVLOG(1) << "WebResourceService StartFetch " << web_resource_server;
129 url_fetcher_.reset(net::URLFetcher::Create(
130 web_resource_server, net::URLFetcher::GET, this));
131 // Do not let url fetcher affect existing state in system context
132 // (by setting cookies, for example).
133 url_fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE |
134 net::LOAD_DO_NOT_SEND_COOKIES |
135 net::LOAD_DO_NOT_SAVE_COOKIES);
136 net::URLRequestContextGetter* url_request_context_getter =
137 g_browser_process->system_request_context();
138 url_fetcher_->SetRequestContext(url_request_context_getter);
139 url_fetcher_->Start();
140 }
141
OnURLFetchComplete(const net::URLFetcher * source)142 void WebResourceService::OnURLFetchComplete(const net::URLFetcher* source) {
143 // Delete the URLFetcher when this function exits.
144 scoped_ptr<net::URLFetcher> clean_up_fetcher(url_fetcher_.release());
145
146 if (source->GetStatus().is_success() && source->GetResponseCode() == 200) {
147 std::string data;
148 source->GetResponseAsString(&data);
149
150 // UnpackerClient calls EndFetch and releases itself on completion.
151 json_unpacker_ = JSONAsynchronousUnpacker::Create(this);
152 json_unpacker_->Start(data);
153 } else {
154 // Don't parse data if attempt to download was unsuccessful.
155 // Stop loading new web resource data, and silently exit.
156 // We do not call UnpackerClient, so we need to call EndFetch ourselves.
157 EndFetch();
158 }
159
160 Release();
161 }
162