Simplify ChildProcessLauncher
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_context_watcher.cc
blob13e1228ec154cf3df65f99ad057107826db3d047
1 // Copyright 2015 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/browser/service_worker/service_worker_context_watcher.h"
7 #include "base/bind.h"
8 #include "base/containers/scoped_ptr_hash_map.h"
9 #include "content/browser/service_worker/service_worker_context_observer.h"
10 #include "content/browser/service_worker/service_worker_context_wrapper.h"
11 #include "content/browser/service_worker/service_worker_version.h"
12 #include "content/common/service_worker/service_worker_types.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "url/gurl.h"
16 namespace content {
17 namespace {
19 bool IsStoppedAndRedundant(const ServiceWorkerVersionInfo& version_info) {
20 return version_info.running_status ==
21 content::ServiceWorkerVersion::STOPPED &&
22 version_info.status == content::ServiceWorkerVersion::REDUNDANT;
25 } // namespace
27 ServiceWorkerContextWatcher::ServiceWorkerContextWatcher(
28 scoped_refptr<ServiceWorkerContextWrapper> context,
29 const WorkerRegistrationUpdatedCallback& registration_callback,
30 const WorkerVersionUpdatedCallback& version_callback,
31 const WorkerErrorReportedCallback& error_callback)
32 : context_(context),
33 registration_callback_(registration_callback),
34 version_callback_(version_callback),
35 error_callback_(error_callback) {
36 DCHECK_CURRENTLY_ON(BrowserThread::UI);
39 void ServiceWorkerContextWatcher::Start() {
40 DCHECK_CURRENTLY_ON(BrowserThread::UI);
41 BrowserThread::PostTask(
42 BrowserThread::IO, FROM_HERE,
43 base::Bind(&ServiceWorkerContextWatcher::GetStoredRegistrationsOnIOThread,
44 this));
47 void ServiceWorkerContextWatcher::Stop() {
48 DCHECK_CURRENTLY_ON(BrowserThread::UI);
49 BrowserThread::PostTask(
50 BrowserThread::IO, FROM_HERE,
51 base::Bind(&ServiceWorkerContextWatcher::StopOnIOThread, this));
54 void ServiceWorkerContextWatcher::GetStoredRegistrationsOnIOThread() {
55 DCHECK_CURRENTLY_ON(BrowserThread::IO);
56 context_->context()->storage()->GetAllRegistrations(base::Bind(
57 &ServiceWorkerContextWatcher::OnStoredRegistrationsOnIOThread, this));
60 void ServiceWorkerContextWatcher::OnStoredRegistrationsOnIOThread(
61 const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations) {
62 DCHECK_CURRENTLY_ON(BrowserThread::IO);
63 context_->AddObserver(this);
65 base::ScopedPtrHashMap<int64, ServiceWorkerRegistrationInfo>
66 registration_info_map;
67 for (const auto& registration : stored_registrations)
68 StoreRegistrationInfo(registration, &registration_info_map);
69 for (const auto& registration :
70 context_->context()->GetAllLiveRegistrationInfo()) {
71 StoreRegistrationInfo(registration, &registration_info_map);
73 for (const auto& version : context_->context()->GetAllLiveVersionInfo())
74 StoreVersionInfo(version);
76 std::vector<ServiceWorkerRegistrationInfo> registrations;
77 registrations.reserve(registration_info_map.size());
78 for (const auto& registration_id_info_pair : registration_info_map)
79 registrations.push_back(*registration_id_info_pair.second);
81 std::vector<ServiceWorkerVersionInfo> versions;
82 versions.reserve(version_info_map_.size());
84 for (auto version_it = version_info_map_.begin();
85 version_it != version_info_map_.end();) {
86 versions.push_back(*version_it->second);
87 if (IsStoppedAndRedundant(*version_it->second))
88 version_info_map_.erase(version_it++);
89 else
90 ++version_it;
93 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
94 base::Bind(registration_callback_, registrations));
95 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
96 base::Bind(version_callback_, versions));
99 void ServiceWorkerContextWatcher::StopOnIOThread() {
100 DCHECK_CURRENTLY_ON(BrowserThread::IO);
101 context_->RemoveObserver(this);
104 ServiceWorkerContextWatcher::~ServiceWorkerContextWatcher() {
107 void ServiceWorkerContextWatcher::StoreRegistrationInfo(
108 const ServiceWorkerRegistrationInfo& registration_info,
109 base::ScopedPtrHashMap<int64, ServiceWorkerRegistrationInfo>* info_map) {
110 DCHECK_CURRENTLY_ON(BrowserThread::IO);
111 if (registration_info.registration_id == kInvalidServiceWorkerRegistrationId)
112 return;
113 info_map->set(registration_info.registration_id,
114 scoped_ptr<ServiceWorkerRegistrationInfo>(
115 new ServiceWorkerRegistrationInfo(registration_info)));
116 StoreVersionInfo(registration_info.active_version);
117 StoreVersionInfo(registration_info.waiting_version);
118 StoreVersionInfo(registration_info.installing_version);
121 void ServiceWorkerContextWatcher::StoreVersionInfo(
122 const ServiceWorkerVersionInfo& version_info) {
123 DCHECK_CURRENTLY_ON(BrowserThread::IO);
124 if (version_info.version_id == kInvalidServiceWorkerVersionId)
125 return;
126 version_info_map_.set(version_info.version_id,
127 scoped_ptr<ServiceWorkerVersionInfo>(
128 new ServiceWorkerVersionInfo(version_info)));
131 void ServiceWorkerContextWatcher::SendRegistrationInfo(
132 int64 registration_id,
133 const GURL& pattern,
134 ServiceWorkerRegistrationInfo::DeleteFlag delete_flag) {
135 std::vector<ServiceWorkerRegistrationInfo> registrations;
136 registrations.push_back(
137 ServiceWorkerRegistrationInfo(pattern, registration_id, delete_flag));
138 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
139 base::Bind(registration_callback_, registrations));
142 void ServiceWorkerContextWatcher::SendVersionInfo(
143 const ServiceWorkerVersionInfo& version_info) {
144 DCHECK_CURRENTLY_ON(BrowserThread::IO);
145 std::vector<ServiceWorkerVersionInfo> versions;
146 versions.push_back(version_info);
147 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
148 base::Bind(version_callback_, versions));
151 void ServiceWorkerContextWatcher::OnNewLiveRegistration(int64 registration_id,
152 const GURL& pattern) {
153 SendRegistrationInfo(registration_id, pattern,
154 ServiceWorkerRegistrationInfo::IS_NOT_DELETED);
157 void ServiceWorkerContextWatcher::OnNewLiveVersion(int64 version_id,
158 int64 registration_id,
159 const GURL& script_url) {
160 if (ServiceWorkerVersionInfo* version = version_info_map_.get(version_id)) {
161 DCHECK_EQ(version->registration_id, registration_id);
162 DCHECK_EQ(version->script_url, script_url);
163 return;
166 scoped_ptr<ServiceWorkerVersionInfo> version(new ServiceWorkerVersionInfo());
167 version->version_id = version_id;
168 version->registration_id = registration_id;
169 version->script_url = script_url;
170 SendVersionInfo(*version);
171 if (!IsStoppedAndRedundant(*version))
172 version_info_map_.set(version_id, version.Pass());
175 void ServiceWorkerContextWatcher::OnRunningStateChanged(
176 int64 version_id,
177 content::ServiceWorkerVersion::RunningStatus running_status) {
178 ServiceWorkerVersionInfo* version = version_info_map_.get(version_id);
179 DCHECK(version);
180 if (version->running_status == running_status)
181 return;
182 version->running_status = running_status;
183 SendVersionInfo(*version);
184 if (IsStoppedAndRedundant(*version))
185 version_info_map_.erase(version_id);
188 void ServiceWorkerContextWatcher::OnVersionStateChanged(
189 int64 version_id,
190 content::ServiceWorkerVersion::Status status) {
191 ServiceWorkerVersionInfo* version = version_info_map_.get(version_id);
192 DCHECK(version);
193 if (version->status == status)
194 return;
195 version->status = status;
196 SendVersionInfo(*version);
197 if (IsStoppedAndRedundant(*version))
198 version_info_map_.erase(version_id);
201 void ServiceWorkerContextWatcher::OnErrorReported(int64 version_id,
202 int process_id,
203 int thread_id,
204 const ErrorInfo& info) {
205 int64 registration_id = kInvalidServiceWorkerRegistrationId;
206 if (ServiceWorkerVersionInfo* version = version_info_map_.get(version_id))
207 registration_id = version->registration_id;
208 BrowserThread::PostTask(
209 BrowserThread::UI, FROM_HERE,
210 base::Bind(error_callback_, registration_id, version_id, info));
213 void ServiceWorkerContextWatcher::OnRegistrationStored(int64 registration_id,
214 const GURL& pattern) {
215 SendRegistrationInfo(registration_id, pattern,
216 ServiceWorkerRegistrationInfo::IS_NOT_DELETED);
219 void ServiceWorkerContextWatcher::OnRegistrationDeleted(int64 registration_id,
220 const GURL& pattern) {
221 SendRegistrationInfo(registration_id, pattern,
222 ServiceWorkerRegistrationInfo::IS_DELETED);
225 } // namespace content