OLD | NEW |
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 Loading... |
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 CompareHelper : public base::RefCounted<CompareHelper> { |
| 78 public: |
| 79 CompareHelper( |
| 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<CompareHelper>; |
| 96 |
| 97 const int kBufferSize = 16 * 1024; |
| 98 |
| 99 ~CompareHelper() {} |
| 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(CompareHelper); |
| 116 }; |
| 117 |
| 118 void CompareHelper::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 CompareHelper::ReadInfos() { |
| 128 lhs_reader_->ReadInfo( |
| 129 lhs_info_, |
| 130 base::Bind(&CompareHelper::OnReadInfoComplete, |
| 131 this)); |
| 132 rhs_reader_->ReadInfo( |
| 133 rhs_info_, |
| 134 base::Bind(&CompareHelper::OnReadInfoComplete, |
| 135 this)); |
| 136 } |
| 137 |
| 138 void CompareHelper::OnReadInfoComplete(int result) { |
| 139 if (completion_callback_.is_null() || !owner_) |
| 140 return; |
| 141 if (result < 0) { |
| 142 completion_callback_.Run(SERVICE_WORKER_ERROR_FAILED, -1); |
| 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, -1); |
| 151 return; |
| 152 } |
| 153 ReadSomeData(); |
| 154 } |
| 155 |
| 156 void CompareHelper::ReadSomeData() { |
| 157 completion_count_ = 0; |
| 158 lhs_reader_->ReadData( |
| 159 lhs_buffer_, |
| 160 kBufferSize, |
| 161 base::Bind(&CompareHelper::OnReadDataComplete, this)); |
| 162 rhs_reader_->ReadData( |
| 163 rhs_buffer_, |
| 164 kBufferSize, |
| 165 base::Bind(&CompareHelper::OnReadDataComplete, this)); |
| 166 } |
| 167 |
| 168 void CompareHelper::OnReadDataComplete(int result) { |
| 169 if (completion_callback_.is_null() || !owner_) |
| 170 return; |
| 171 if (result < 0) { |
| 172 completion_callback_.Run(SERVICE_WORKER_ERROR_FAILED, -1); |
| 173 completion_callback_.Reset(); |
| 174 return; |
| 175 } |
| 176 if (++(completion_count_) != 2) { |
| 177 previous_result_ = result; |
| 178 return; |
| 179 } |
| 180 |
| 181 if (result != previous_result_) { |
| 182 completion_callback_.Run(SERVICE_WORKER_ERROR_FAILED, -1); |
| 183 return; |
| 184 } |
| 185 |
| 186 if (result == 0) { |
| 187 completion_callback_.Run(SERVICE_WORKER_OK, 0); |
| 188 return; |
| 189 } |
| 190 |
| 191 int compare_result = |
| 192 memcmp(lhs_buffer_->data(), rhs_buffer_->data(), result); |
| 193 if (compare_result != 0) { |
| 194 completion_callback_.Run(SERVICE_WORKER_OK, compare_result); |
| 195 return; |
| 196 } |
| 197 |
| 198 ReadSomeData(); |
| 199 } |
| 200 |
76 } // namespace | 201 } // namespace |
77 | 202 |
78 ServiceWorkerStorage::InitialData::InitialData() | 203 ServiceWorkerStorage::InitialData::InitialData() |
79 : next_registration_id(kInvalidServiceWorkerRegistrationId), | 204 : next_registration_id(kInvalidServiceWorkerRegistrationId), |
80 next_version_id(kInvalidServiceWorkerVersionId), | 205 next_version_id(kInvalidServiceWorkerVersionId), |
81 next_resource_id(kInvalidServiceWorkerResourceId) { | 206 next_resource_id(kInvalidServiceWorkerResourceId) { |
82 } | 207 } |
83 | 208 |
84 ServiceWorkerStorage::InitialData::~InitialData() { | 209 ServiceWorkerStorage::InitialData::~InitialData() { |
85 } | 210 } |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 DCHECK_NE(kInvalidServiceWorkerResponseId, id); | 510 DCHECK_NE(kInvalidServiceWorkerResponseId, id); |
386 database_task_runner_->PostTask( | 511 database_task_runner_->PostTask( |
387 FROM_HERE, | 512 FROM_HERE, |
388 base::Bind(base::IgnoreResult( | 513 base::Bind(base::IgnoreResult( |
389 &ServiceWorkerDatabase::PurgeUncommittedResourceIds), | 514 &ServiceWorkerDatabase::PurgeUncommittedResourceIds), |
390 base::Unretained(database_.get()), | 515 base::Unretained(database_.get()), |
391 std::set<int64>(&id, &id + 1))); | 516 std::set<int64>(&id, &id + 1))); |
392 StartPurgingResources(std::vector<int64>(1, id)); | 517 StartPurgingResources(std::vector<int64>(1, id)); |
393 } | 518 } |
394 | 519 |
| 520 void ServiceWorkerStorage::CompareScriptResources( |
| 521 int64 lhs_id, int64 rhs_id, |
| 522 const CompareCallback& callback) { |
| 523 DCHECK(!callback.is_null()); |
| 524 scoped_refptr<CompareHelper> helper = |
| 525 new CompareHelper(weak_factory_.GetWeakPtr(), |
| 526 CreateResponseReader(lhs_id), |
| 527 CreateResponseReader(rhs_id), |
| 528 callback); |
| 529 helper->Start(); // It deletes itself when done. |
| 530 } |
| 531 |
395 void ServiceWorkerStorage::DeleteAndStartOver(const StatusCallback& callback) { | 532 void ServiceWorkerStorage::DeleteAndStartOver(const StatusCallback& callback) { |
396 Disable(); | 533 Disable(); |
397 | 534 |
398 // Delete the database on the database thread. | 535 // Delete the database on the database thread. |
399 PostTaskAndReplyWithResult( | 536 PostTaskAndReplyWithResult( |
400 database_task_runner_, | 537 database_task_runner_, |
401 FROM_HERE, | 538 FROM_HERE, |
402 base::Bind(&ServiceWorkerDatabase::DestroyDatabase, | 539 base::Bind(&ServiceWorkerDatabase::DestroyDatabase, |
403 base::Unretained(database_.get())), | 540 base::Unretained(database_.get())), |
404 base::Bind(&ServiceWorkerStorage::DidDeleteDatabase, | 541 base::Bind(&ServiceWorkerStorage::DidDeleteDatabase, |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 | 891 |
755 registration = new ServiceWorkerRegistration( | 892 registration = new ServiceWorkerRegistration( |
756 data.scope, data.script, data.registration_id, context_); | 893 data.scope, data.script, data.registration_id, context_); |
757 scoped_refptr<ServiceWorkerVersion> version = | 894 scoped_refptr<ServiceWorkerVersion> version = |
758 context_->GetLiveVersion(data.version_id); | 895 context_->GetLiveVersion(data.version_id); |
759 if (!version) { | 896 if (!version) { |
760 version = new ServiceWorkerVersion(registration, data.version_id, context_); | 897 version = new ServiceWorkerVersion(registration, data.version_id, context_); |
761 version->SetStatus(data.is_active ? | 898 version->SetStatus(data.is_active ? |
762 ServiceWorkerVersion::ACTIVATED : ServiceWorkerVersion::INSTALLED); | 899 ServiceWorkerVersion::ACTIVATED : ServiceWorkerVersion::INSTALLED); |
763 version->script_cache_map()->SetResources(resources); | 900 version->script_cache_map()->SetResources(resources); |
| 901 |
| 902 // TODO(michaeln): need to activate a waiting version that wasn't |
| 903 // actrivated in an earlier session, maybe test for this condition |
| 904 // (waitingversion and no activeversion) when navigating to a page? |
764 } | 905 } |
765 | 906 |
766 if (version->status() == ServiceWorkerVersion::ACTIVATED) | 907 if (version->status() == ServiceWorkerVersion::ACTIVATED) { |
767 registration->SetActiveVersion(version); | 908 registration->SetActiveVersion(version); |
768 else if (version->status() == ServiceWorkerVersion::INSTALLED) | 909 } else if (version->status() == ServiceWorkerVersion::INSTALLED) { |
769 registration->SetWaitingVersion(version); | 910 registration->SetWaitingVersion(version); |
770 else | 911 } else { |
771 NOTREACHED(); | 912 NOTREACHED(); |
772 // TODO(michaeln): Hmmm, what if DeleteReg was invoked after | 913 } |
773 // the Find result we're returning here? NOTREACHED condition? | |
774 return registration; | 914 return registration; |
775 } | 915 } |
776 | 916 |
777 ServiceWorkerRegistration* | 917 ServiceWorkerRegistration* |
778 ServiceWorkerStorage::FindInstallingRegistrationForDocument( | 918 ServiceWorkerStorage::FindInstallingRegistrationForDocument( |
779 const GURL& document_url) { | 919 const GURL& document_url) { |
780 DCHECK(!document_url.has_ref()); | 920 DCHECK(!document_url.has_ref()); |
781 | 921 |
782 LongestScopeMatcher matcher(document_url); | 922 LongestScopeMatcher matcher(document_url); |
783 ServiceWorkerRegistration* match = NULL; | 923 ServiceWorkerRegistration* match = NULL; |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1176 // Give up the corruption recovery until the browser restarts. | 1316 // Give up the corruption recovery until the browser restarts. |
1177 LOG(ERROR) << "Failed to delete the diskcache."; | 1317 LOG(ERROR) << "Failed to delete the diskcache."; |
1178 callback.Run(SERVICE_WORKER_ERROR_FAILED); | 1318 callback.Run(SERVICE_WORKER_ERROR_FAILED); |
1179 return; | 1319 return; |
1180 } | 1320 } |
1181 DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully."; | 1321 DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully."; |
1182 callback.Run(SERVICE_WORKER_OK); | 1322 callback.Run(SERVICE_WORKER_OK); |
1183 } | 1323 } |
1184 | 1324 |
1185 } // namespace content | 1325 } // namespace content |
OLD | NEW |