Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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/devtools/protocol/service_worker_handler.h" | 5 #include "content/browser/devtools/protocol/service_worker_handler.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | |
| 8 #include "base/strings/string_number_conversions.h" | |
| 9 #include "content/browser/devtools/service_worker_devtools_manager.h" | |
| 10 #include "content/browser/service_worker/service_worker_context_observer.h" | |
| 11 #include "content/browser/service_worker/service_worker_context_wrapper.h" | |
| 12 #include "content/public/browser/browser_context.h" | |
| 13 #include "content/public/browser/browser_thread.h" | |
| 7 #include "content/public/browser/devtools_agent_host.h" | 14 #include "content/public/browser/devtools_agent_host.h" |
| 15 #include "content/public/browser/render_frame_host.h" | |
| 16 #include "content/public/browser/render_process_host.h" | |
| 17 #include "content/public/browser/storage_partition.h" | |
| 18 #include "url/gurl.h" | |
| 19 | |
| 20 // Windows headers will redefine SendMessage. | |
| 21 #ifdef SendMessage | |
| 22 #undef SendMessage | |
| 23 #endif | |
| 8 | 24 |
| 9 namespace content { | 25 namespace content { |
| 10 namespace devtools { | 26 namespace devtools { |
| 11 namespace service_worker { | 27 namespace service_worker { |
| 12 | 28 |
| 29 namespace { | |
| 30 | |
| 31 const char* GetVersionRunningStatusString( | |
|
pfeldman
2015/03/09 19:16:49
std::string ?
horo
2015/03/10 01:34:07
Done.
| |
| 32 content::ServiceWorkerVersion::RunningStatus running_status) { | |
| 33 switch (running_status) { | |
| 34 case content::ServiceWorkerVersion::STOPPED: | |
| 35 return service_worker_version::kRunningStatusStopped; | |
| 36 case content::ServiceWorkerVersion::STARTING: | |
| 37 return service_worker_version::kRunningStatusStarting; | |
| 38 case content::ServiceWorkerVersion::RUNNING: | |
| 39 return service_worker_version::kRunningStatusRunning; | |
| 40 case content::ServiceWorkerVersion::STOPPING: | |
| 41 return service_worker_version::kRunningStatusStopping; | |
| 42 } | |
| 43 return ""; | |
| 44 } | |
| 45 | |
| 46 const char* GetVersionStatusString( | |
|
pfeldman
2015/03/09 19:16:49
ditto
horo
2015/03/10 01:34:07
Done.
| |
| 47 content::ServiceWorkerVersion::Status status) { | |
| 48 switch (status) { | |
| 49 case content::ServiceWorkerVersion::NEW: | |
| 50 return service_worker_version::kStatusNew; | |
| 51 case content::ServiceWorkerVersion::INSTALLING: | |
| 52 return service_worker_version::kStatusInstalling; | |
| 53 case content::ServiceWorkerVersion::INSTALLED: | |
| 54 return service_worker_version::kStatusInstalled; | |
| 55 case content::ServiceWorkerVersion::ACTIVATING: | |
| 56 return service_worker_version::kStatusActivating; | |
| 57 case content::ServiceWorkerVersion::ACTIVATED: | |
| 58 return service_worker_version::kStatusActivated; | |
| 59 case content::ServiceWorkerVersion::REDUNDANT: | |
| 60 return service_worker_version::kStatusRedundant; | |
| 61 } | |
| 62 return ""; | |
| 63 } | |
| 64 | |
| 65 scoped_refptr<ServiceWorkerVersion> CreateVersionDictionaryValue( | |
| 66 const ServiceWorkerVersionInfo& version_info) { | |
| 67 scoped_refptr<ServiceWorkerVersion> version( | |
| 68 ServiceWorkerVersion::Create() | |
| 69 ->set_version_id(base::Int64ToString(version_info.version_id)) | |
| 70 ->set_registration_id( | |
| 71 base::Int64ToString(version_info.registration_id)) | |
| 72 ->set_script_url(version_info.script_url.spec()) | |
| 73 ->set_running_status( | |
| 74 GetVersionRunningStatusString(version_info.running_status)) | |
| 75 ->set_status(GetVersionStatusString(version_info.status))); | |
| 76 return version; | |
| 77 } | |
| 78 | |
| 79 scoped_refptr<ServiceWorkerRegistration> CreateRegistrationDictionaryValue( | |
| 80 const ServiceWorkerRegistrationInfo& registration_info) { | |
| 81 scoped_refptr<ServiceWorkerRegistration> registration( | |
| 82 ServiceWorkerRegistration::Create() | |
| 83 ->set_registration_id( | |
| 84 base::Int64ToString(registration_info.registration_id)) | |
| 85 ->set_scope_url(registration_info.pattern.spec())); | |
| 86 if (registration_info.active_version.version_id != | |
| 87 kInvalidServiceWorkerVersionId) { | |
| 88 registration->set_active_version( | |
| 89 CreateVersionDictionaryValue(registration_info.active_version)); | |
| 90 } | |
| 91 if (registration_info.waiting_version.version_id != | |
| 92 kInvalidServiceWorkerVersionId) { | |
| 93 registration->set_waiting_version( | |
| 94 CreateVersionDictionaryValue(registration_info.waiting_version)); | |
| 95 } | |
| 96 if (registration_info.installing_version.version_id != | |
| 97 kInvalidServiceWorkerVersionId) { | |
| 98 registration->set_installing_version( | |
| 99 CreateVersionDictionaryValue(registration_info.installing_version)); | |
| 100 } | |
| 101 return registration; | |
| 102 } | |
| 103 | |
| 104 } // namespace | |
| 105 | |
| 13 using Response = DevToolsProtocolClient::Response; | 106 using Response = DevToolsProtocolClient::Response; |
| 14 | 107 |
| 15 ServiceWorkerHandler::ServiceWorkerHandler() { | 108 class ServiceWorkerHandler::ContextObserver |
| 109 : public ServiceWorkerContextObserver, | |
| 110 public base::RefCountedThreadSafe<ContextObserver> { | |
| 111 public: | |
| 112 ContextObserver(scoped_refptr<ServiceWorkerContextWrapper> context, | |
| 113 base::WeakPtr<ServiceWorkerHandler> handler); | |
| 114 void Start(); | |
| 115 void Stop(); | |
| 116 | |
| 117 private: | |
| 118 friend class base::RefCountedThreadSafe<ContextObserver>; | |
| 119 ~ContextObserver(); | |
| 120 void GetStoredRegistrationsOnIOThread(); | |
| 121 void OnStoredRegistrationsOnIOThread( | |
| 122 const std::vector<ServiceWorkerRegistrationInfo>& registrations); | |
| 123 void StopOnIOThread(); | |
| 124 | |
| 125 void OnVersionUpdated(int64 version_id); | |
| 126 void OnRegistrationUpdated(int64 registration_id); | |
| 127 | |
| 128 // ServiceWorkerContextObserver implements | |
| 129 void OnRunningStateChanged(int64 version_id) override; | |
| 130 void OnVersionStateChanged(int64 version_id) override; | |
| 131 void OnRegistrationStored(int64 registration_id, | |
| 132 const GURL& pattern) override; | |
| 133 void OnRegistrationDeleted(int64 registration_id, | |
| 134 const GURL& pattern) override; | |
| 135 | |
| 136 scoped_refptr<ServiceWorkerContextWrapper> context_; | |
| 137 base::WeakPtr<ServiceWorkerHandler> handler_; | |
| 138 }; | |
| 139 | |
| 140 ServiceWorkerHandler::ContextObserver::ContextObserver( | |
| 141 scoped_refptr<ServiceWorkerContextWrapper> context, | |
| 142 base::WeakPtr<ServiceWorkerHandler> handler) | |
| 143 : context_(context), handler_(handler) { | |
| 144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 145 } | |
| 146 | |
| 147 void ServiceWorkerHandler::ContextObserver::Start() { | |
| 148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 149 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
| 150 base::Bind(&ServiceWorkerHandler::ContextObserver:: | |
| 151 GetStoredRegistrationsOnIOThread, | |
| 152 this)); | |
| 153 } | |
| 154 | |
| 155 void ServiceWorkerHandler::ContextObserver::Stop() { | |
| 156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 157 BrowserThread::PostTask( | |
| 158 BrowserThread::IO, FROM_HERE, | |
| 159 base::Bind(&ServiceWorkerHandler::ContextObserver::StopOnIOThread, this)); | |
| 160 } | |
| 161 | |
| 162 void ServiceWorkerHandler::ContextObserver::GetStoredRegistrationsOnIOThread() { | |
| 163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 164 context_->context()->storage()->GetAllRegistrations(base::Bind( | |
| 165 &ServiceWorkerHandler::ContextObserver::OnStoredRegistrationsOnIOThread, | |
| 166 this)); | |
| 167 } | |
| 168 | |
| 169 void ServiceWorkerHandler::ContextObserver::OnStoredRegistrationsOnIOThread( | |
| 170 const std::vector<ServiceWorkerRegistrationInfo>& registrations) { | |
| 171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 172 context_->AddObserver(this); | |
| 173 BrowserThread::PostTask( | |
| 174 BrowserThread::UI, FROM_HERE, | |
| 175 base::Bind(&ServiceWorkerHandler::OnWorkerRegistrationUpdated, handler_, | |
| 176 registrations)); | |
| 177 BrowserThread::PostTask( | |
| 178 BrowserThread::UI, FROM_HERE, | |
| 179 base::Bind(&ServiceWorkerHandler::OnWorkerRegistrationUpdated, handler_, | |
| 180 context_->context()->GetAllLiveRegistrationInfo())); | |
| 181 BrowserThread::PostTask( | |
| 182 BrowserThread::UI, FROM_HERE, | |
| 183 base::Bind(&ServiceWorkerHandler::OnWorkerVersionUpdated, handler_, | |
| 184 context_->context()->GetAllLiveVersionInfo())); | |
| 185 } | |
| 186 | |
| 187 void ServiceWorkerHandler::ContextObserver::StopOnIOThread() { | |
| 188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 189 context_->RemoveObserver(this); | |
| 190 } | |
| 191 | |
| 192 ServiceWorkerHandler::ContextObserver::~ContextObserver() { | |
| 193 } | |
| 194 | |
| 195 void ServiceWorkerHandler::ContextObserver::OnVersionUpdated(int64 version_id) { | |
| 196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 197 content::ServiceWorkerVersion* version = | |
| 198 context_->context()->GetLiveVersion(version_id); | |
| 199 if (!version) | |
| 200 return; | |
| 201 OnRegistrationUpdated(version->registration_id()); | |
| 202 std::vector<ServiceWorkerVersionInfo> versions; | |
| 203 versions.push_back(version->GetInfo()); | |
| 204 BrowserThread::PostTask( | |
| 205 BrowserThread::UI, FROM_HERE, | |
| 206 base::Bind(&ServiceWorkerHandler::OnWorkerVersionUpdated, handler_, | |
| 207 versions)); | |
| 208 } | |
| 209 | |
| 210 void ServiceWorkerHandler::ContextObserver::OnRegistrationUpdated( | |
| 211 int64 registration_id) { | |
| 212 content::ServiceWorkerRegistration* registration = | |
| 213 context_->context()->GetLiveRegistration(registration_id); | |
| 214 if (!registration) | |
| 215 return; | |
| 216 std::vector<ServiceWorkerRegistrationInfo> registrations; | |
| 217 registrations.push_back(registration->GetInfo()); | |
| 218 BrowserThread::PostTask( | |
| 219 BrowserThread::UI, FROM_HERE, | |
| 220 base::Bind(&ServiceWorkerHandler::OnWorkerRegistrationUpdated, handler_, | |
| 221 registrations)); | |
| 222 } | |
| 223 | |
| 224 void ServiceWorkerHandler::ContextObserver::OnRunningStateChanged( | |
| 225 int64 version_id) { | |
| 226 OnVersionUpdated(version_id); | |
| 227 } | |
| 228 | |
| 229 void ServiceWorkerHandler::ContextObserver::OnVersionStateChanged( | |
| 230 int64 version_id) { | |
| 231 OnVersionUpdated(version_id); | |
| 232 } | |
| 233 | |
| 234 void ServiceWorkerHandler::ContextObserver::OnRegistrationStored( | |
| 235 int64 registration_id, | |
| 236 const GURL& pattern) { | |
| 237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 238 content::ServiceWorkerRegistration* registration = | |
| 239 context_->context()->GetLiveRegistration(registration_id); | |
| 240 DCHECK(registration); | |
| 241 std::vector<ServiceWorkerRegistrationInfo> registrations; | |
| 242 registrations.push_back(registration->GetInfo()); | |
| 243 BrowserThread::PostTask( | |
| 244 BrowserThread::UI, FROM_HERE, | |
| 245 base::Bind(&ServiceWorkerHandler::OnWorkerRegistrationUpdated, handler_, | |
| 246 registrations)); | |
| 247 } | |
| 248 | |
| 249 void ServiceWorkerHandler::ContextObserver::OnRegistrationDeleted( | |
| 250 int64 registration_id, | |
| 251 const GURL& pattern) { | |
| 252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 253 BrowserThread::PostTask( | |
| 254 BrowserThread::UI, FROM_HERE, | |
| 255 base::Bind(&ServiceWorkerHandler::OnWorkerRegistrationDeleted, handler_, | |
| 256 registration_id)); | |
| 257 } | |
| 258 | |
| 259 ServiceWorkerHandler::ServiceWorkerHandler() | |
| 260 : render_frame_host_(nullptr), weak_factory_(this) { | |
| 16 } | 261 } |
| 17 | 262 |
| 18 ServiceWorkerHandler::~ServiceWorkerHandler() { | 263 ServiceWorkerHandler::~ServiceWorkerHandler() { |
| 19 Disable(); | 264 Disable(); |
| 20 } | 265 } |
| 21 | 266 |
| 22 void ServiceWorkerHandler::SetClient( | 267 void ServiceWorkerHandler::SetRenderFrameHost( |
| 23 scoped_ptr<Client> client) { | 268 RenderFrameHost* render_frame_host) { |
| 269 render_frame_host_ = render_frame_host; | |
|
pfeldman
2015/03/09 19:16:49
This will change on the render swap, so you want t
horo
2015/03/10 01:34:07
Done.
| |
| 270 } | |
| 271 | |
| 272 void ServiceWorkerHandler::SetClient(scoped_ptr<Client> client) { | |
| 24 client_.swap(client); | 273 client_.swap(client); |
| 25 } | 274 } |
| 26 | 275 |
| 27 void ServiceWorkerHandler::Detached() { | 276 void ServiceWorkerHandler::Detached() { |
| 28 Disable(); | 277 Disable(); |
| 29 } | 278 } |
| 30 | 279 |
| 31 Response ServiceWorkerHandler::Enable() { | 280 Response ServiceWorkerHandler::Enable() { |
| 281 if (!render_frame_host_) | |
| 282 return Response::InternalError("Could not connect to frame"); | |
| 32 DevToolsAgentHost::List agent_hosts; | 283 DevToolsAgentHost::List agent_hosts; |
| 33 ServiceWorkerDevToolsManager::GetInstance()->AddAllAgentHosts(&agent_hosts); | 284 ServiceWorkerDevToolsManager::GetInstance()->AddAllAgentHosts(&agent_hosts); |
| 34 ServiceWorkerDevToolsManager::GetInstance()->AddObserver(this); | 285 ServiceWorkerDevToolsManager::GetInstance()->AddObserver(this); |
| 286 StoragePartition* partition = BrowserContext::GetStoragePartition( | |
| 287 render_frame_host_->GetProcess()->GetBrowserContext(), | |
| 288 render_frame_host_->GetSiteInstance()); | |
| 289 scoped_refptr<ServiceWorkerContextWrapper> context = | |
| 290 static_cast<ServiceWorkerContextWrapper*>( | |
| 291 partition->GetServiceWorkerContext()); | |
| 292 context_observer_ = new ContextObserver(context, weak_factory_.GetWeakPtr()); | |
| 293 context_observer_->Start(); | |
| 35 for (auto host : agent_hosts) | 294 for (auto host : agent_hosts) |
| 36 WorkerCreated(host.get()); | 295 WorkerCreated(host.get()); |
| 37 return Response::OK(); | 296 return Response::OK(); |
| 38 } | 297 } |
| 39 | 298 |
| 40 Response ServiceWorkerHandler::Disable() { | 299 Response ServiceWorkerHandler::Disable() { |
| 41 ServiceWorkerDevToolsManager::GetInstance()->RemoveObserver(this); | 300 ServiceWorkerDevToolsManager::GetInstance()->RemoveObserver(this); |
| 42 for (const auto& pair : attached_hosts_) | 301 for (const auto& pair : attached_hosts_) |
| 43 pair.second->DetachClient(); | 302 pair.second->DetachClient(); |
| 44 attached_hosts_.clear(); | 303 attached_hosts_.clear(); |
| 304 if (context_observer_) { | |
|
pfeldman
2015/03/09 19:16:49
The ToT has enabled_ check, so you would not need
horo
2015/03/10 01:34:07
Done.
| |
| 305 context_observer_->Stop(); | |
| 306 context_observer_ = nullptr; | |
| 307 } | |
| 45 return Response::OK(); | 308 return Response::OK(); |
| 46 } | 309 } |
| 47 | 310 |
| 48 Response ServiceWorkerHandler::SendMessage( | 311 Response ServiceWorkerHandler::SendMessage( |
| 49 const std::string& worker_id, | 312 const std::string& worker_id, |
| 50 const std::string& message) { | 313 const std::string& message) { |
| 51 auto it = attached_hosts_.find(worker_id); | 314 auto it = attached_hosts_.find(worker_id); |
| 52 if (it == attached_hosts_.end()) | 315 if (it == attached_hosts_.end()) |
| 53 return Response::InternalError("Not connected to the worker"); | 316 return Response::InternalError("Not connected to the worker"); |
| 54 | 317 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 73 Response ServiceWorkerHandler::Detach(const std::string& worker_id) { | 336 Response ServiceWorkerHandler::Detach(const std::string& worker_id) { |
| 74 auto it = attached_hosts_.find(worker_id); | 337 auto it = attached_hosts_.find(worker_id); |
| 75 if (it == attached_hosts_.end()) | 338 if (it == attached_hosts_.end()) |
| 76 return Response::InternalError("Not connected to the worker"); | 339 return Response::InternalError("Not connected to the worker"); |
| 77 | 340 |
| 78 attached_hosts_.erase(worker_id); | 341 attached_hosts_.erase(worker_id); |
| 79 it->second->DetachClient(); | 342 it->second->DetachClient(); |
| 80 return Response::OK(); | 343 return Response::OK(); |
| 81 } | 344 } |
| 82 | 345 |
| 346 void ServiceWorkerHandler::OnWorkerRegistrationUpdated( | |
| 347 const std::vector<ServiceWorkerRegistrationInfo>& registrations) { | |
| 348 std::vector<scoped_refptr<ServiceWorkerRegistration>> registration_values; | |
| 349 for (const auto& registration : registrations) { | |
| 350 registration_values.push_back( | |
| 351 CreateRegistrationDictionaryValue(registration)); | |
| 352 } | |
| 353 client_->WorkerRegistrationUpdated( | |
| 354 WorkerRegistrationUpdatedParams::Create()->set_registrations( | |
| 355 registration_values)); | |
| 356 } | |
| 357 | |
| 358 void ServiceWorkerHandler::OnWorkerVersionUpdated( | |
| 359 const std::vector<ServiceWorkerVersionInfo>& versions) { | |
| 360 std::vector<scoped_refptr<ServiceWorkerVersion>> version_values; | |
| 361 for (const auto& version : versions) { | |
| 362 version_values.push_back(CreateVersionDictionaryValue(version)); | |
| 363 } | |
| 364 client_->WorkerVersionUpdated( | |
| 365 WorkerVersionUpdatedParams::Create()->set_versions(version_values)); | |
| 366 } | |
| 367 | |
| 368 void ServiceWorkerHandler::OnWorkerRegistrationDeleted(int64 registration_id) { | |
| 369 client_->WorkerRegistrationDeleted( | |
| 370 WorkerRegistrationDeletedParams::Create()->set_registration_id( | |
| 371 base::Int64ToString(registration_id))); | |
| 372 } | |
| 373 | |
| 83 void ServiceWorkerHandler::DispatchProtocolMessage( | 374 void ServiceWorkerHandler::DispatchProtocolMessage( |
| 84 DevToolsAgentHost* host, | 375 DevToolsAgentHost* host, |
| 85 const std::string& message) { | 376 const std::string& message) { |
| 86 auto it = attached_hosts_.find(host->GetId()); | 377 auto it = attached_hosts_.find(host->GetId()); |
| 87 if (it == attached_hosts_.end()) | 378 if (it == attached_hosts_.end()) |
| 88 return; // Already disconnected. | 379 return; // Already disconnected. |
| 89 | 380 |
| 90 client_->DispatchMessage( | 381 client_->DispatchMessage( |
| 91 DispatchMessageParams::Create()-> | 382 DispatchMessageParams::Create()-> |
| 92 set_worker_id(host->GetId())-> | 383 set_worker_id(host->GetId())-> |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 112 if (it == attached_hosts_.end()) | 403 if (it == attached_hosts_.end()) |
| 113 return; | 404 return; |
| 114 client_->WorkerTerminated(WorkerTerminatedParams::Create()-> | 405 client_->WorkerTerminated(WorkerTerminatedParams::Create()-> |
| 115 set_worker_id(host->GetId())); | 406 set_worker_id(host->GetId())); |
| 116 attached_hosts_.erase(it); | 407 attached_hosts_.erase(it); |
| 117 } | 408 } |
| 118 | 409 |
| 119 } // namespace service_worker | 410 } // namespace service_worker |
| 120 } // namespace devtools | 411 } // namespace devtools |
| 121 } // namespace content | 412 } // namespace content |
| OLD | NEW |