Infobar material design refresh: bg color
[chromium-blink-merge.git] / components / web_resource / web_resource_service.cc
blob1afd22eef4ead5c51edbd832b065d600cb0439dc
1 // Copyright 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.
5 #include "components/web_resource/web_resource_service.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "base/time/time.h"
16 #include "base/values.h"
17 #include "components/google/core/browser/google_util.h"
18 #include "net/base/load_flags.h"
19 #include "net/url_request/url_fetcher.h"
20 #include "net/url_request/url_request_context_getter.h"
21 #include "net/url_request/url_request_status.h"
22 #include "url/gurl.h"
24 // No anonymous namespace, because const variables automatically get internal
25 // linkage.
26 const char kInvalidDataTypeError[] =
27 "Data from web resource server is missing or not valid JSON.";
29 const char kUnexpectedJSONFormatError[] =
30 "Data from web resource server does not have expected format.";
32 namespace web_resource {
34 WebResourceService::WebResourceService(
35 PrefService* prefs,
36 const GURL& web_resource_server,
37 const std::string& application_locale,
38 const char* last_update_time_pref_name,
39 int start_fetch_delay_ms,
40 int cache_update_delay_ms,
41 net::URLRequestContextGetter* request_context,
42 const char* disable_network_switch,
43 const ParseJSONCallback& parse_json_callback)
44 : prefs_(prefs),
45 resource_request_allowed_notifier_(prefs, disable_network_switch),
46 in_fetch_(false),
47 web_resource_server_(web_resource_server),
48 application_locale_(application_locale),
49 last_update_time_pref_name_(last_update_time_pref_name),
50 start_fetch_delay_ms_(start_fetch_delay_ms),
51 cache_update_delay_ms_(cache_update_delay_ms),
52 request_context_(request_context),
53 parse_json_callback_(parse_json_callback),
54 weak_ptr_factory_(this) {
55 resource_request_allowed_notifier_.Init(this);
56 DCHECK(prefs);
59 void WebResourceService::StartAfterDelay() {
60 // If resource requests are not allowed, we'll get a callback when they are.
61 if (resource_request_allowed_notifier_.ResourceRequestsAllowed())
62 OnResourceRequestsAllowed();
65 WebResourceService::~WebResourceService() {
68 void WebResourceService::OnURLFetchComplete(const net::URLFetcher* source) {
69 // Delete the URLFetcher when this function exits.
70 scoped_ptr<net::URLFetcher> clean_up_fetcher(url_fetcher_.release());
72 if (source->GetStatus().is_success() && source->GetResponseCode() == 200) {
73 std::string data;
74 source->GetResponseAsString(&data);
75 // Calls EndFetch() on completion.
76 // Full JSON parsing might spawn a utility process (for security).
77 // To limit the the number of simultaneously active processes
78 // (on Android in particular) we short-cut the full parsing in the case of
79 // trivially "empty" JSONs.
80 if (data.empty() || data == "{}") {
81 OnUnpackFinished(make_scoped_ptr(new base::DictionaryValue()).Pass());
82 } else {
83 parse_json_callback_.Run(data,
84 base::Bind(&WebResourceService::OnUnpackFinished,
85 weak_ptr_factory_.GetWeakPtr()),
86 base::Bind(&WebResourceService::OnUnpackError,
87 weak_ptr_factory_.GetWeakPtr()));
89 } else {
90 // Don't parse data if attempt to download was unsuccessful.
91 // Stop loading new web resource data, and silently exit.
92 // We do not call parse_json_callback_, so we need to call EndFetch()
93 // ourselves.
94 EndFetch();
98 // Delay initial load of resource data into cache so as not to interfere
99 // with startup time.
100 void WebResourceService::ScheduleFetch(int64 delay_ms) {
101 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
102 FROM_HERE, base::Bind(&WebResourceService::StartFetch,
103 weak_ptr_factory_.GetWeakPtr()),
104 base::TimeDelta::FromMilliseconds(delay_ms));
107 // Initializes the fetching of data from the resource server. Data
108 // load calls OnURLFetchComplete.
109 void WebResourceService::StartFetch() {
110 // First, put our next cache load on the MessageLoop.
111 ScheduleFetch(cache_update_delay_ms_);
113 // Set cache update time in preferences.
114 prefs_->SetString(last_update_time_pref_name_,
115 base::DoubleToString(base::Time::Now().ToDoubleT()));
117 // If we are still fetching data, exit.
118 if (in_fetch_)
119 return;
120 in_fetch_ = true;
122 GURL web_resource_server =
123 application_locale_.empty()
124 ? web_resource_server_
125 : google_util::AppendGoogleLocaleParam(web_resource_server_,
126 application_locale_);
128 DVLOG(1) << "WebResourceService StartFetch " << web_resource_server;
129 url_fetcher_ =
130 net::URLFetcher::Create(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 url_fetcher_->SetRequestContext(request_context_.get());
137 url_fetcher_->Start();
140 void WebResourceService::EndFetch() {
141 in_fetch_ = false;
144 void WebResourceService::OnUnpackFinished(scoped_ptr<base::Value> value) {
145 if (!value) {
146 // Page information not properly read, or corrupted.
147 OnUnpackError(kInvalidDataTypeError);
148 return;
150 const base::DictionaryValue* dict = nullptr;
151 if (!value->GetAsDictionary(&dict)) {
152 OnUnpackError(kUnexpectedJSONFormatError);
153 return;
155 Unpack(*dict);
157 EndFetch();
160 void WebResourceService::OnUnpackError(const std::string& error_message) {
161 LOG(ERROR) << error_message;
162 EndFetch();
165 void WebResourceService::OnResourceRequestsAllowed() {
166 int64 delay = start_fetch_delay_ms_;
167 // Check whether we have ever put a value in the web resource cache;
168 // if so, pull it out and see if it's time to update again.
169 if (prefs_->HasPrefPath(last_update_time_pref_name_)) {
170 std::string last_update_pref =
171 prefs_->GetString(last_update_time_pref_name_);
172 if (!last_update_pref.empty()) {
173 double last_update_value;
174 base::StringToDouble(last_update_pref, &last_update_value);
175 int64 ms_until_update =
176 cache_update_delay_ms_ -
177 static_cast<int64>(
178 (base::Time::Now() - base::Time::FromDoubleT(last_update_value))
179 .InMilliseconds());
180 // Wait at least |start_fetch_delay_ms_|.
181 if (ms_until_update > start_fetch_delay_ms_)
182 delay = ms_until_update;
185 // Start fetch and wait for UpdateResourceCache.
186 ScheduleFetch(delay);
189 } // namespace web_resource