ServiceWorker: Stop exposing ServiceWorkerContextCore
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_context_watcher.cc
blob7c69ea222f4fb70ebcfeceae35e4ad99d4651e7d
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 "content/public/common/console_message_level.h"
15 #include "url/gurl.h"
17 namespace content {
18 namespace {
20 bool IsStoppedAndRedundant(const ServiceWorkerVersionInfo& version_info) {
21 return version_info.running_status ==
22 content::ServiceWorkerVersion::STOPPED &&
23 version_info.status == content::ServiceWorkerVersion::REDUNDANT;
26 } // namespace
28 ServiceWorkerContextWatcher::ServiceWorkerContextWatcher(
29 scoped_refptr<ServiceWorkerContextWrapper> context,
30 const WorkerRegistrationUpdatedCallback& registration_callback,
31 const WorkerVersionUpdatedCallback& version_callback,
32 const WorkerErrorReportedCallback& error_callback)
33 : context_(context),
34 registration_callback_(registration_callback),
35 version_callback_(version_callback),
36 error_callback_(error_callback) {
37 DCHECK_CURRENTLY_ON(BrowserThread::UI);
40 void ServiceWorkerContextWatcher::Start() {
41 DCHECK_CURRENTLY_ON(BrowserThread::UI);
42 BrowserThread::PostTask(
43 BrowserThread::IO, FROM_HERE,
44 base::Bind(&ServiceWorkerContextWatcher::GetStoredRegistrationsOnIOThread,
45 this));
48 void ServiceWorkerContextWatcher::Stop() {
49 DCHECK_CURRENTLY_ON(BrowserThread::UI);
50 BrowserThread::PostTask(
51 BrowserThread::IO, FROM_HERE,
52 base::Bind(&ServiceWorkerContextWatcher::StopOnIOThread, this));
55 void ServiceWorkerContextWatcher::GetStoredRegistrationsOnIOThread() {
56 DCHECK_CURRENTLY_ON(BrowserThread::IO);
57 context_->GetAllRegistrations(base::Bind(
58 &ServiceWorkerContextWatcher::OnStoredRegistrationsOnIOThread, this));
61 void ServiceWorkerContextWatcher::OnStoredRegistrationsOnIOThread(
62 const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations) {
63 DCHECK_CURRENTLY_ON(BrowserThread::IO);
64 context_->AddObserver(this);
66 base::ScopedPtrHashMap<int64, ServiceWorkerRegistrationInfo>
67 registration_info_map;
68 for (const auto& registration : stored_registrations)
69 StoreRegistrationInfo(registration, &registration_info_map);
70 for (const auto& registration : context_->GetAllLiveRegistrationInfo())
71 StoreRegistrationInfo(registration, &registration_info_map);
72 for (const auto& version : context_->GetAllLiveVersionInfo())
73 StoreVersionInfo(version);
75 std::vector<ServiceWorkerRegistrationInfo> registrations;
76 registrations.reserve(registration_info_map.size());
77 for (const auto& registration_id_info_pair : registration_info_map)
78 registrations.push_back(*registration_id_info_pair.second);
80 std::vector<ServiceWorkerVersionInfo> versions;
81 versions.reserve(version_info_map_.size());
83 for (auto version_it = version_info_map_.begin();
84 version_it != version_info_map_.end();) {
85 versions.push_back(*version_it->second);
86 if (IsStoppedAndRedundant(*version_it->second))
87 version_info_map_.erase(version_it++);
88 else
89 ++version_it;
92 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
93 base::Bind(registration_callback_, registrations));
94 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
95 base::Bind(version_callback_, versions));
98 void ServiceWorkerContextWatcher::StopOnIOThread() {
99 DCHECK_CURRENTLY_ON(BrowserThread::IO);
100 context_->RemoveObserver(this);
103 ServiceWorkerContextWatcher::~ServiceWorkerContextWatcher() {
106 void ServiceWorkerContextWatcher::StoreRegistrationInfo(
107 const ServiceWorkerRegistrationInfo& registration_info,
108 base::ScopedPtrHashMap<int64, ServiceWorkerRegistrationInfo>* info_map) {
109 DCHECK_CURRENTLY_ON(BrowserThread::IO);
110 if (registration_info.registration_id == kInvalidServiceWorkerRegistrationId)
111 return;
112 info_map->set(registration_info.registration_id,
113 scoped_ptr<ServiceWorkerRegistrationInfo>(
114 new ServiceWorkerRegistrationInfo(registration_info)));
115 StoreVersionInfo(registration_info.active_version);
116 StoreVersionInfo(registration_info.waiting_version);
117 StoreVersionInfo(registration_info.installing_version);
120 void ServiceWorkerContextWatcher::StoreVersionInfo(
121 const ServiceWorkerVersionInfo& version_info) {
122 DCHECK_CURRENTLY_ON(BrowserThread::IO);
123 if (version_info.version_id == kInvalidServiceWorkerVersionId)
124 return;
125 version_info_map_.set(version_info.version_id,
126 scoped_ptr<ServiceWorkerVersionInfo>(
127 new ServiceWorkerVersionInfo(version_info)));
130 void ServiceWorkerContextWatcher::SendRegistrationInfo(
131 int64 registration_id,
132 const GURL& pattern,
133 ServiceWorkerRegistrationInfo::DeleteFlag delete_flag) {
134 std::vector<ServiceWorkerRegistrationInfo> registrations;
135 registrations.push_back(
136 ServiceWorkerRegistrationInfo(pattern, registration_id, delete_flag));
137 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
138 base::Bind(registration_callback_, registrations));
141 void ServiceWorkerContextWatcher::SendVersionInfo(
142 const ServiceWorkerVersionInfo& version_info) {
143 DCHECK_CURRENTLY_ON(BrowserThread::IO);
144 std::vector<ServiceWorkerVersionInfo> versions;
145 versions.push_back(version_info);
146 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
147 base::Bind(version_callback_, versions));
150 void ServiceWorkerContextWatcher::OnNewLiveRegistration(int64 registration_id,
151 const GURL& pattern) {
152 SendRegistrationInfo(registration_id, pattern,
153 ServiceWorkerRegistrationInfo::IS_NOT_DELETED);
156 void ServiceWorkerContextWatcher::OnNewLiveVersion(int64 version_id,
157 int64 registration_id,
158 const GURL& script_url) {
159 if (ServiceWorkerVersionInfo* version = version_info_map_.get(version_id)) {
160 DCHECK_EQ(version->registration_id, registration_id);
161 DCHECK_EQ(version->script_url, script_url);
162 return;
165 scoped_ptr<ServiceWorkerVersionInfo> version(new ServiceWorkerVersionInfo());
166 version->version_id = version_id;
167 version->registration_id = registration_id;
168 version->script_url = script_url;
169 SendVersionInfo(*version);
170 if (!IsStoppedAndRedundant(*version))
171 version_info_map_.set(version_id, version.Pass());
174 void ServiceWorkerContextWatcher::OnRunningStateChanged(
175 int64 version_id,
176 content::ServiceWorkerVersion::RunningStatus running_status) {
177 ServiceWorkerVersionInfo* version = version_info_map_.get(version_id);
178 DCHECK(version);
179 if (version->running_status == running_status)
180 return;
181 version->running_status = running_status;
182 SendVersionInfo(*version);
183 if (IsStoppedAndRedundant(*version))
184 version_info_map_.erase(version_id);
187 void ServiceWorkerContextWatcher::OnVersionStateChanged(
188 int64 version_id,
189 content::ServiceWorkerVersion::Status status) {
190 ServiceWorkerVersionInfo* version = version_info_map_.get(version_id);
191 DCHECK(version);
192 if (version->status == status)
193 return;
194 version->status = status;
195 SendVersionInfo(*version);
196 if (IsStoppedAndRedundant(*version))
197 version_info_map_.erase(version_id);
200 void ServiceWorkerContextWatcher::OnMainScriptHttpResponseInfoSet(
201 int64 version_id,
202 base::Time script_response_time,
203 base::Time script_last_modified) {
204 ServiceWorkerVersionInfo* version = version_info_map_.get(version_id);
205 DCHECK(version);
206 version->script_response_time = script_response_time;
207 version->script_last_modified = script_last_modified;
208 SendVersionInfo(*version);
211 void ServiceWorkerContextWatcher::OnErrorReported(int64 version_id,
212 int process_id,
213 int thread_id,
214 const ErrorInfo& info) {
215 int64 registration_id = kInvalidServiceWorkerRegistrationId;
216 if (ServiceWorkerVersionInfo* version = version_info_map_.get(version_id))
217 registration_id = version->registration_id;
218 BrowserThread::PostTask(
219 BrowserThread::UI, FROM_HERE,
220 base::Bind(error_callback_, registration_id, version_id, info));
223 void ServiceWorkerContextWatcher::OnReportConsoleMessage(
224 int64 version_id,
225 int process_id,
226 int thread_id,
227 const ConsoleMessage& message) {
228 if (message.message_level != CONSOLE_MESSAGE_LEVEL_ERROR)
229 return;
230 int64 registration_id = kInvalidServiceWorkerRegistrationId;
231 if (ServiceWorkerVersionInfo* version = version_info_map_.get(version_id))
232 registration_id = version->registration_id;
233 BrowserThread::PostTask(
234 BrowserThread::UI, FROM_HERE,
235 base::Bind(error_callback_, registration_id, version_id,
236 ErrorInfo(message.message, message.line_number, -1,
237 message.source_url)));
240 void ServiceWorkerContextWatcher::OnRegistrationStored(int64 registration_id,
241 const GURL& pattern) {
242 SendRegistrationInfo(registration_id, pattern,
243 ServiceWorkerRegistrationInfo::IS_NOT_DELETED);
246 void ServiceWorkerContextWatcher::OnRegistrationDeleted(int64 registration_id,
247 const GURL& pattern) {
248 SendRegistrationInfo(registration_id, pattern,
249 ServiceWorkerRegistrationInfo::IS_DELETED);
252 } // namespace content