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.
5 #include "chrome/browser/web_resource/web_resource_service.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/common/chrome_switches.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_status.h"
23 WebResourceService::WebResourceService(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
)
30 resource_request_allowed_notifier_(
32 switches::kDisableBackgroundNetworking
),
35 web_resource_server_(web_resource_server
),
36 apply_locale_to_url_(apply_locale_to_url
),
37 last_update_time_pref_name_(last_update_time_pref_name
),
38 start_fetch_delay_ms_(start_fetch_delay_ms
),
39 cache_update_delay_ms_(cache_update_delay_ms
),
40 weak_ptr_factory_(this) {
41 resource_request_allowed_notifier_
.Init(this);
45 WebResourceService::~WebResourceService() {
50 void WebResourceService::OnUnpackFinished(
51 const base::DictionaryValue
& parsed_json
) {
56 void WebResourceService::OnUnpackError(const std::string
& error_message
) {
57 LOG(ERROR
) << error_message
;
61 void WebResourceService::EndFetch() {
63 json_unpacker_
->ClearDelegate();
64 json_unpacker_
= NULL
;
69 void WebResourceService::StartAfterDelay() {
70 // If resource requests are not allowed, we'll get a callback when they are.
71 if (resource_request_allowed_notifier_
.ResourceRequestsAllowed())
72 OnResourceRequestsAllowed();
75 void WebResourceService::OnResourceRequestsAllowed() {
76 int64 delay
= start_fetch_delay_ms_
;
77 // Check whether we have ever put a value in the web resource cache;
78 // if so, pull it out and see if it's time to update again.
79 if (prefs_
->HasPrefPath(last_update_time_pref_name_
)) {
80 std::string last_update_pref
=
81 prefs_
->GetString(last_update_time_pref_name_
);
82 if (!last_update_pref
.empty()) {
83 double last_update_value
;
84 base::StringToDouble(last_update_pref
, &last_update_value
);
85 int64 ms_until_update
= cache_update_delay_ms_
-
86 static_cast<int64
>((base::Time::Now() - base::Time::FromDoubleT(
87 last_update_value
)).InMilliseconds());
88 // Wait at least |start_fetch_delay_ms_|.
89 if (ms_until_update
> start_fetch_delay_ms_
)
90 delay
= ms_until_update
;
93 // Start fetch and wait for UpdateResourceCache.
97 // Delay initial load of resource data into cache so as not to interfere
99 void WebResourceService::ScheduleFetch(int64 delay_ms
) {
100 base::MessageLoop::current()->PostDelayedTask(
102 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.
122 // Balanced in OnURLFetchComplete.
125 GURL web_resource_server
=
127 ? google_util::AppendGoogleLocaleParam(
128 web_resource_server_
, g_browser_process
->GetApplicationLocale())
129 : web_resource_server_
;
131 DVLOG(1) << "WebResourceService StartFetch " << web_resource_server
;
132 url_fetcher_
.reset(net::URLFetcher::Create(
133 web_resource_server
, net::URLFetcher::GET
, this));
134 // Do not let url fetcher affect existing state in system context
135 // (by setting cookies, for example).
136 url_fetcher_
->SetLoadFlags(net::LOAD_DISABLE_CACHE
|
137 net::LOAD_DO_NOT_SEND_COOKIES
|
138 net::LOAD_DO_NOT_SAVE_COOKIES
);
139 net::URLRequestContextGetter
* url_request_context_getter
=
140 g_browser_process
->system_request_context();
141 url_fetcher_
->SetRequestContext(url_request_context_getter
);
142 url_fetcher_
->Start();
145 void WebResourceService::OnURLFetchComplete(const net::URLFetcher
* source
) {
146 // Delete the URLFetcher when this function exits.
147 scoped_ptr
<net::URLFetcher
> clean_up_fetcher(url_fetcher_
.release());
149 if (source
->GetStatus().is_success() && source
->GetResponseCode() == 200) {
151 source
->GetResponseAsString(&data
);
153 // UnpackerClient calls EndFetch and releases itself on completion.
154 json_unpacker_
= JSONAsynchronousUnpacker::Create(this);
155 json_unpacker_
->Start(data
);
157 // Don't parse data if attempt to download was unsuccessful.
158 // Stop loading new web resource data, and silently exit.
159 // We do not call UnpackerClient, so we need to call EndFetch ourselves.