Disable signin-to-Chrome when using Guest profile.
[chromium-blink-merge.git] / content / child / appcache / web_application_cache_host_impl.cc
blob7d5f47b92fca08af60bbb154b968ccd4e6bd9261
1 // Copyright 2013 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 "content/child/appcache/web_application_cache_host_impl.h"
7 #include "base/compiler_specific.h"
8 #include "base/id_map.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/stringprintf.h"
11 #include "third_party/WebKit/public/platform/WebURL.h"
12 #include "third_party/WebKit/public/platform/WebURLRequest.h"
13 #include "third_party/WebKit/public/platform/WebURLResponse.h"
15 using blink::WebApplicationCacheHost;
16 using blink::WebApplicationCacheHostClient;
17 using blink::WebURLRequest;
18 using blink::WebURL;
19 using blink::WebURLResponse;
20 using blink::WebVector;
21 using appcache::AppCacheBackend;
22 using appcache::AppCacheResourceInfo;
24 namespace content {
26 namespace {
28 // Note: the order of the elements in this array must match those
29 // of the EventID enum in appcache_interfaces.h.
30 const char* kEventNames[] = {
31 "Checking", "Error", "NoUpdate", "Downloading", "Progress",
32 "UpdateReady", "Cached", "Obsolete"
35 typedef IDMap<WebApplicationCacheHostImpl> HostsMap;
37 HostsMap* all_hosts() {
38 static HostsMap* map = new HostsMap;
39 return map;
42 GURL ClearUrlRef(const GURL& url) {
43 if (!url.has_ref())
44 return url;
45 GURL::Replacements replacements;
46 replacements.ClearRef();
47 return url.ReplaceComponents(replacements);
50 } // anon namespace
52 WebApplicationCacheHostImpl* WebApplicationCacheHostImpl::FromId(int id) {
53 return all_hosts()->Lookup(id);
56 WebApplicationCacheHostImpl::WebApplicationCacheHostImpl(
57 WebApplicationCacheHostClient* client,
58 AppCacheBackend* backend)
59 : client_(client),
60 backend_(backend),
61 host_id_(all_hosts()->Add(this)),
62 status_(appcache::UNCACHED),
63 is_scheme_supported_(false),
64 is_get_method_(false),
65 is_new_master_entry_(MAYBE),
66 was_select_cache_called_(false) {
67 DCHECK(client && backend && (host_id_ != appcache::kNoHostId));
69 backend_->RegisterHost(host_id_);
72 WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() {
73 backend_->UnregisterHost(host_id_);
74 all_hosts()->Remove(host_id_);
77 void WebApplicationCacheHostImpl::OnCacheSelected(
78 const appcache::AppCacheInfo& info) {
79 cache_info_ = info;
80 client_->didChangeCacheAssociation();
83 void WebApplicationCacheHostImpl::OnStatusChanged(appcache::Status status) {
84 // TODO(michaeln): delete me, not used
87 void WebApplicationCacheHostImpl::OnEventRaised(appcache::EventID event_id) {
88 DCHECK(event_id != appcache::PROGRESS_EVENT); // See OnProgressEventRaised.
89 DCHECK(event_id != appcache::ERROR_EVENT); // See OnErrorEventRaised.
91 // Emit logging output prior to calling out to script as we can get
92 // deleted within the script event handler.
93 const char* kFormatString = "Application Cache %s event";
94 std::string message = base::StringPrintf(kFormatString,
95 kEventNames[event_id]);
96 OnLogMessage(appcache::LOG_INFO, message);
98 switch (event_id) {
99 case appcache::CHECKING_EVENT:
100 status_ = appcache::CHECKING;
101 break;
102 case appcache::DOWNLOADING_EVENT:
103 status_ = appcache::DOWNLOADING;
104 break;
105 case appcache::UPDATE_READY_EVENT:
106 status_ = appcache::UPDATE_READY;
107 break;
108 case appcache::CACHED_EVENT:
109 case appcache::NO_UPDATE_EVENT:
110 status_ = appcache::IDLE;
111 break;
112 case appcache::OBSOLETE_EVENT:
113 status_ = appcache::OBSOLETE;
114 break;
115 default:
116 NOTREACHED();
117 break;
120 client_->notifyEventListener(static_cast<EventID>(event_id));
123 void WebApplicationCacheHostImpl::OnProgressEventRaised(
124 const GURL& url, int num_total, int num_complete) {
125 // Emit logging output prior to calling out to script as we can get
126 // deleted within the script event handler.
127 const char* kFormatString = "Application Cache Progress event (%d of %d) %s";
128 std::string message = base::StringPrintf(kFormatString, num_complete,
129 num_total, url.spec().c_str());
130 OnLogMessage(appcache::LOG_INFO, message);
131 status_ = appcache::DOWNLOADING;
132 client_->notifyProgressEventListener(url, num_total, num_complete);
135 void WebApplicationCacheHostImpl::OnErrorEventRaised(
136 const std::string& message) {
137 // Emit logging output prior to calling out to script as we can get
138 // deleted within the script event handler.
139 const char* kFormatString = "Application Cache Error event: %s";
140 std::string full_message = base::StringPrintf(kFormatString,
141 message.c_str());
142 OnLogMessage(appcache::LOG_ERROR, full_message);
144 status_ = cache_info_.is_complete ? appcache::IDLE : appcache::UNCACHED;
145 client_->notifyEventListener(static_cast<EventID>(appcache::ERROR_EVENT));
148 void WebApplicationCacheHostImpl::willStartMainResourceRequest(
149 WebURLRequest& request, const WebApplicationCacheHost* spawning_host) {
150 request.setAppCacheHostID(host_id_);
152 original_main_resource_url_ = ClearUrlRef(request.url());
154 std::string method = request.httpMethod().utf8();
155 is_get_method_ = (method == appcache::kHttpGETMethod);
156 DCHECK(method == StringToUpperASCII(method));
158 const WebApplicationCacheHostImpl* spawning_host_impl =
159 static_cast<const WebApplicationCacheHostImpl*>(spawning_host);
160 if (spawning_host_impl && (spawning_host_impl != this) &&
161 (spawning_host_impl->status_ != appcache::UNCACHED)) {
162 backend_->SetSpawningHostId(host_id_, spawning_host_impl->host_id());
166 void WebApplicationCacheHostImpl::willStartSubResourceRequest(
167 WebURLRequest& request) {
168 request.setAppCacheHostID(host_id_);
171 void WebApplicationCacheHostImpl::selectCacheWithoutManifest() {
172 if (was_select_cache_called_)
173 return;
174 was_select_cache_called_ = true;
176 status_ = (document_response_.appCacheID() == appcache::kNoCacheId) ?
177 appcache::UNCACHED : appcache::CHECKING;
178 is_new_master_entry_ = NO;
179 backend_->SelectCache(host_id_, document_url_,
180 document_response_.appCacheID(),
181 GURL());
184 bool WebApplicationCacheHostImpl::selectCacheWithManifest(
185 const WebURL& manifest_url) {
186 if (was_select_cache_called_)
187 return true;
188 was_select_cache_called_ = true;
190 GURL manifest_gurl(ClearUrlRef(manifest_url));
192 // 6.9.6 The application cache selection algorithm
193 // Check for new 'master' entries.
194 if (document_response_.appCacheID() == appcache::kNoCacheId) {
195 if (is_scheme_supported_ && is_get_method_ &&
196 (manifest_gurl.GetOrigin() == document_url_.GetOrigin())) {
197 status_ = appcache::CHECKING;
198 is_new_master_entry_ = YES;
199 } else {
200 status_ = appcache::UNCACHED;
201 is_new_master_entry_ = NO;
202 manifest_gurl = GURL();
204 backend_->SelectCache(
205 host_id_, document_url_, appcache::kNoCacheId, manifest_gurl);
206 return true;
209 DCHECK_EQ(NO, is_new_master_entry_);
211 // 6.9.6 The application cache selection algorithm
212 // Check for 'foreign' entries.
213 GURL document_manifest_gurl(document_response_.appCacheManifestURL());
214 if (document_manifest_gurl != manifest_gurl) {
215 backend_->MarkAsForeignEntry(host_id_, document_url_,
216 document_response_.appCacheID());
217 status_ = appcache::UNCACHED;
218 return false; // the navigation will be restarted
221 status_ = appcache::CHECKING;
223 // Its a 'master' entry thats already in the cache.
224 backend_->SelectCache(host_id_, document_url_,
225 document_response_.appCacheID(),
226 manifest_gurl);
227 return true;
230 void WebApplicationCacheHostImpl::didReceiveResponseForMainResource(
231 const WebURLResponse& response) {
232 document_response_ = response;
233 document_url_ = ClearUrlRef(document_response_.url());
234 if (document_url_ != original_main_resource_url_)
235 is_get_method_ = true; // A redirect was involved.
236 original_main_resource_url_ = GURL();
238 is_scheme_supported_ = appcache::IsSchemeSupported(document_url_);
239 if ((document_response_.appCacheID() != appcache::kNoCacheId) ||
240 !is_scheme_supported_ || !is_get_method_)
241 is_new_master_entry_ = NO;
244 void WebApplicationCacheHostImpl::didReceiveDataForMainResource(
245 const char* data, int len) {
246 if (is_new_master_entry_ == NO)
247 return;
248 // TODO(michaeln): write me
251 void WebApplicationCacheHostImpl::didFinishLoadingMainResource(bool success) {
252 if (is_new_master_entry_ == NO)
253 return;
254 // TODO(michaeln): write me
257 WebApplicationCacheHost::Status WebApplicationCacheHostImpl::status() {
258 return static_cast<WebApplicationCacheHost::Status>(status_);
261 bool WebApplicationCacheHostImpl::startUpdate() {
262 if (!backend_->StartUpdate(host_id_))
263 return false;
264 if (status_ == appcache::IDLE || status_ == appcache::UPDATE_READY)
265 status_ = appcache::CHECKING;
266 else
267 status_ = backend_->GetStatus(host_id_);
268 return true;
271 bool WebApplicationCacheHostImpl::swapCache() {
272 if (!backend_->SwapCache(host_id_))
273 return false;
274 status_ = backend_->GetStatus(host_id_);
275 return true;
278 void WebApplicationCacheHostImpl::getAssociatedCacheInfo(
279 WebApplicationCacheHost::CacheInfo* info) {
280 info->manifestURL = cache_info_.manifest_url;
281 if (!cache_info_.is_complete)
282 return;
283 info->creationTime = cache_info_.creation_time.ToDoubleT();
284 info->updateTime = cache_info_.last_update_time.ToDoubleT();
285 info->totalSize = cache_info_.size;
288 void WebApplicationCacheHostImpl::getResourceList(
289 WebVector<ResourceInfo>* resources) {
290 if (!cache_info_.is_complete)
291 return;
292 std::vector<AppCacheResourceInfo> resource_infos;
293 backend_->GetResourceList(host_id_, &resource_infos);
295 WebVector<ResourceInfo> web_resources(resource_infos.size());
296 for (size_t i = 0; i < resource_infos.size(); ++i) {
297 web_resources[i].size = resource_infos[i].size;
298 web_resources[i].isMaster = resource_infos[i].is_master;
299 web_resources[i].isExplicit = resource_infos[i].is_explicit;
300 web_resources[i].isManifest = resource_infos[i].is_manifest;
301 web_resources[i].isForeign = resource_infos[i].is_foreign;
302 web_resources[i].isFallback = resource_infos[i].is_fallback;
303 web_resources[i].url = resource_infos[i].url;
305 resources->swap(web_resources);
308 } // namespace content