Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(433)

Side by Side Diff: content/browser/service_worker/service_worker_storage.cc

Issue 380093002: Update installed ServiceWorkers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/service_worker/service_worker_storage.h" 5 #include "content/browser/service_worker/service_worker_storage.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind_helpers.h" 9 #include "base/bind_helpers.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/sequenced_task_runner.h" 12 #include "base/sequenced_task_runner.h"
13 #include "base/task_runner_util.h" 13 #include "base/task_runner_util.h"
14 #include "content/browser/service_worker/service_worker_context_core.h" 14 #include "content/browser/service_worker/service_worker_context_core.h"
15 #include "content/browser/service_worker/service_worker_disk_cache.h" 15 #include "content/browser/service_worker/service_worker_disk_cache.h"
16 #include "content/browser/service_worker/service_worker_info.h" 16 #include "content/browser/service_worker/service_worker_info.h"
17 #include "content/browser/service_worker/service_worker_metrics.h" 17 #include "content/browser/service_worker/service_worker_metrics.h"
18 #include "content/browser/service_worker/service_worker_registration.h" 18 #include "content/browser/service_worker/service_worker_registration.h"
19 #include "content/browser/service_worker/service_worker_utils.h" 19 #include "content/browser/service_worker/service_worker_utils.h"
20 #include "content/browser/service_worker/service_worker_version.h" 20 #include "content/browser/service_worker/service_worker_version.h"
21 #include "content/common/service_worker/service_worker_types.h" 21 #include "content/common/service_worker/service_worker_types.h"
22 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
23 #include "net/base/io_buffer.h"
23 #include "net/base/net_errors.h" 24 #include "net/base/net_errors.h"
24 #include "webkit/browser/quota/quota_manager_proxy.h" 25 #include "webkit/browser/quota/quota_manager_proxy.h"
25 26
26 namespace content { 27 namespace content {
27 28
28 namespace { 29 namespace {
29 30
30 void RunSoon(const tracked_objects::Location& from_here, 31 void RunSoon(const tracked_objects::Location& from_here,
31 const base::Closure& closure) { 32 const base::Closure& closure) {
32 base::MessageLoop::current()->PostTask(from_here, closure); 33 base::MessageLoop::current()->PostTask(from_here, closure);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 return SERVICE_WORKER_OK; 67 return SERVICE_WORKER_OK;
67 case ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND: 68 case ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND:
68 return SERVICE_WORKER_ERROR_NOT_FOUND; 69 return SERVICE_WORKER_ERROR_NOT_FOUND;
69 case ServiceWorkerDatabase::STATUS_ERROR_MAX: 70 case ServiceWorkerDatabase::STATUS_ERROR_MAX:
70 NOTREACHED(); 71 NOTREACHED();
71 default: 72 default:
72 return SERVICE_WORKER_ERROR_FAILED; 73 return SERVICE_WORKER_ERROR_FAILED;
73 } 74 }
74 } 75 }
75 76
77 class ResponseComparer : public base::RefCounted<ResponseComparer> {
78 public:
79 ResponseComparer(
80 base::WeakPtr<ServiceWorkerStorage> owner,
81 scoped_ptr<ServiceWorkerResponseReader> lhs,
82 scoped_ptr<ServiceWorkerResponseReader> rhs,
83 const ServiceWorkerStorage::CompareCallback& callback)
84 : owner_(owner),
85 completion_callback_(callback),
86 lhs_reader_(lhs.release()),
87 rhs_reader_(rhs.release()),
88 completion_count_(0),
89 previous_result_(0) {
90 }
91
92 void Start();
93
94 private:
95 friend class base::RefCounted<ResponseComparer>;
96
97 static const int kBufferSize = 16 * 1024;
98
99 ~ResponseComparer() {}
100 void ReadInfos();
101 void OnReadInfoComplete(int result);
102 void ReadSomeData();
103 void OnReadDataComplete(int result);
104
105 base::WeakPtr<ServiceWorkerStorage> owner_;
106 ServiceWorkerStorage::CompareCallback completion_callback_;
107 scoped_ptr<ServiceWorkerResponseReader> lhs_reader_;
108 scoped_refptr<HttpResponseInfoIOBuffer> lhs_info_;
109 scoped_refptr<net::IOBuffer> lhs_buffer_;
110 scoped_ptr<ServiceWorkerResponseReader> rhs_reader_;
111 scoped_refptr<HttpResponseInfoIOBuffer> rhs_info_;
112 scoped_refptr<net::IOBuffer> rhs_buffer_;
113 int completion_count_;
114 int previous_result_;
115 DISALLOW_COPY_AND_ASSIGN(ResponseComparer);
116 };
117
118 void ResponseComparer::Start() {
119 lhs_buffer_ = new net::IOBuffer(kBufferSize);
120 lhs_info_ = new HttpResponseInfoIOBuffer();
121 rhs_buffer_ = new net::IOBuffer(kBufferSize);
122 rhs_info_ = new HttpResponseInfoIOBuffer();
123
124 ReadInfos();
125 }
126
127 void ResponseComparer::ReadInfos() {
128 lhs_reader_->ReadInfo(
129 lhs_info_,
130 base::Bind(&ResponseComparer::OnReadInfoComplete,
131 this));
132 rhs_reader_->ReadInfo(
133 rhs_info_,
134 base::Bind(&ResponseComparer::OnReadInfoComplete,
135 this));
136 }
137
138 void ResponseComparer::OnReadInfoComplete(int result) {
139 if (completion_callback_.is_null() || !owner_)
140 return;
141 if (result < 0) {
142 completion_callback_.Run(SERVICE_WORKER_ERROR_FAILED, false);
143 completion_callback_.Reset();
144 return;
145 }
146 if (++completion_count_ != 2)
147 return;
148
149 if (lhs_info_->response_data_size != rhs_info_->response_data_size) {
150 completion_callback_.Run(SERVICE_WORKER_OK, false);
151 return;
152 }
153 ReadSomeData();
154 }
155
156 void ResponseComparer::ReadSomeData() {
157 completion_count_ = 0;
158 lhs_reader_->ReadData(
159 lhs_buffer_,
160 kBufferSize,
161 base::Bind(&ResponseComparer::OnReadDataComplete, this));
162 rhs_reader_->ReadData(
163 rhs_buffer_,
164 kBufferSize,
165 base::Bind(&ResponseComparer::OnReadDataComplete, this));
166 }
167
168 void ResponseComparer::OnReadDataComplete(int result) {
169 if (completion_callback_.is_null() || !owner_)
170 return;
171 if (result < 0) {
172 completion_callback_.Run(SERVICE_WORKER_ERROR_FAILED, false);
173 completion_callback_.Reset();
174 return;
175 }
176 if (++completion_count_ != 2) {
177 previous_result_ = result;
178 return;
179 }
180
181 // TODO(michaeln): Probably shouldn't assume that the amounts read from
182 // each reader will always be the same. This would wrongly signal false
183 // in that case.
184 if (result != previous_result_) {
185 completion_callback_.Run(SERVICE_WORKER_OK, false);
186 return;
187 }
188
189 if (result == 0) {
190 completion_callback_.Run(SERVICE_WORKER_OK, true);
191 return;
192 }
193
194 int compare_result =
195 memcmp(lhs_buffer_->data(), rhs_buffer_->data(), result);
196 if (compare_result != 0) {
197 completion_callback_.Run(SERVICE_WORKER_OK, false);
198 return;
199 }
200
201 ReadSomeData();
202 }
203
76 } // namespace 204 } // namespace
77 205
78 ServiceWorkerStorage::InitialData::InitialData() 206 ServiceWorkerStorage::InitialData::InitialData()
79 : next_registration_id(kInvalidServiceWorkerRegistrationId), 207 : next_registration_id(kInvalidServiceWorkerRegistrationId),
80 next_version_id(kInvalidServiceWorkerVersionId), 208 next_version_id(kInvalidServiceWorkerVersionId),
81 next_resource_id(kInvalidServiceWorkerResourceId) { 209 next_resource_id(kInvalidServiceWorkerResourceId) {
82 } 210 }
83 211
84 ServiceWorkerStorage::InitialData::~InitialData() { 212 ServiceWorkerStorage::InitialData::~InitialData() {
85 } 213 }
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 DCHECK_NE(kInvalidServiceWorkerResponseId, id); 513 DCHECK_NE(kInvalidServiceWorkerResponseId, id);
386 database_task_runner_->PostTask( 514 database_task_runner_->PostTask(
387 FROM_HERE, 515 FROM_HERE,
388 base::Bind(base::IgnoreResult( 516 base::Bind(base::IgnoreResult(
389 &ServiceWorkerDatabase::PurgeUncommittedResourceIds), 517 &ServiceWorkerDatabase::PurgeUncommittedResourceIds),
390 base::Unretained(database_.get()), 518 base::Unretained(database_.get()),
391 std::set<int64>(&id, &id + 1))); 519 std::set<int64>(&id, &id + 1)));
392 StartPurgingResources(std::vector<int64>(1, id)); 520 StartPurgingResources(std::vector<int64>(1, id));
393 } 521 }
394 522
523 void ServiceWorkerStorage::CompareScriptResources(
524 int64 lhs_id, int64 rhs_id,
525 const CompareCallback& callback) {
526 DCHECK(!callback.is_null());
527 scoped_refptr<ResponseComparer> comparer =
528 new ResponseComparer(weak_factory_.GetWeakPtr(),
529 CreateResponseReader(lhs_id),
530 CreateResponseReader(rhs_id),
531 callback);
532 comparer->Start(); // It deletes itself when done.
533 }
534
395 void ServiceWorkerStorage::DeleteAndStartOver(const StatusCallback& callback) { 535 void ServiceWorkerStorage::DeleteAndStartOver(const StatusCallback& callback) {
396 Disable(); 536 Disable();
397 537
398 // Delete the database on the database thread. 538 // Delete the database on the database thread.
399 PostTaskAndReplyWithResult( 539 PostTaskAndReplyWithResult(
400 database_task_runner_, 540 database_task_runner_,
401 FROM_HERE, 541 FROM_HERE,
402 base::Bind(&ServiceWorkerDatabase::DestroyDatabase, 542 base::Bind(&ServiceWorkerDatabase::DestroyDatabase,
403 base::Unretained(database_.get())), 543 base::Unretained(database_.get())),
404 base::Bind(&ServiceWorkerStorage::DidDeleteDatabase, 544 base::Bind(&ServiceWorkerStorage::DidDeleteDatabase,
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 894
755 registration = new ServiceWorkerRegistration( 895 registration = new ServiceWorkerRegistration(
756 data.scope, data.script, data.registration_id, context_); 896 data.scope, data.script, data.registration_id, context_);
757 scoped_refptr<ServiceWorkerVersion> version = 897 scoped_refptr<ServiceWorkerVersion> version =
758 context_->GetLiveVersion(data.version_id); 898 context_->GetLiveVersion(data.version_id);
759 if (!version) { 899 if (!version) {
760 version = new ServiceWorkerVersion(registration, data.version_id, context_); 900 version = new ServiceWorkerVersion(registration, data.version_id, context_);
761 version->SetStatus(data.is_active ? 901 version->SetStatus(data.is_active ?
762 ServiceWorkerVersion::ACTIVATED : ServiceWorkerVersion::INSTALLED); 902 ServiceWorkerVersion::ACTIVATED : ServiceWorkerVersion::INSTALLED);
763 version->script_cache_map()->SetResources(resources); 903 version->script_cache_map()->SetResources(resources);
904
905 // TODO(michaeln): need to activate a waiting version that wasn't
906 // actrivated in an earlier session, maybe test for this condition
907 // (waitingversion and no activeversion) when navigating to a page?
764 } 908 }
765 909
766 if (version->status() == ServiceWorkerVersion::ACTIVATED) 910 if (version->status() == ServiceWorkerVersion::ACTIVATED)
767 registration->SetActiveVersion(version); 911 registration->SetActiveVersion(version);
768 else if (version->status() == ServiceWorkerVersion::INSTALLED) 912 else if (version->status() == ServiceWorkerVersion::INSTALLED)
769 registration->SetWaitingVersion(version); 913 registration->SetWaitingVersion(version);
770 else 914 else
771 NOTREACHED(); 915 NOTREACHED();
772 // TODO(michaeln): Hmmm, what if DeleteReg was invoked after 916
773 // the Find result we're returning here? NOTREACHED condition?
774 return registration; 917 return registration;
775 } 918 }
776 919
777 ServiceWorkerRegistration* 920 ServiceWorkerRegistration*
778 ServiceWorkerStorage::FindInstallingRegistrationForDocument( 921 ServiceWorkerStorage::FindInstallingRegistrationForDocument(
779 const GURL& document_url) { 922 const GURL& document_url) {
780 DCHECK(!document_url.has_ref()); 923 DCHECK(!document_url.has_ref());
781 924
782 LongestScopeMatcher matcher(document_url); 925 LongestScopeMatcher matcher(document_url);
783 ServiceWorkerRegistration* match = NULL; 926 ServiceWorkerRegistration* match = NULL;
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 // Give up the corruption recovery until the browser restarts. 1319 // Give up the corruption recovery until the browser restarts.
1177 LOG(ERROR) << "Failed to delete the diskcache."; 1320 LOG(ERROR) << "Failed to delete the diskcache.";
1178 callback.Run(SERVICE_WORKER_ERROR_FAILED); 1321 callback.Run(SERVICE_WORKER_ERROR_FAILED);
1179 return; 1322 return;
1180 } 1323 }
1181 DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully."; 1324 DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully.";
1182 callback.Run(SERVICE_WORKER_OK); 1325 callback.Run(SERVICE_WORKER_OK);
1183 } 1326 }
1184 1327
1185 } // namespace content 1328 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698