1// Copyright 2014 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. 4 5#include "content/browser/service_worker/service_worker_registration_handle.h" 6 7#include "content/browser/service_worker/service_worker_context_core.h" 8#include "content/browser/service_worker/service_worker_dispatcher_host.h" 9#include "content/browser/service_worker/service_worker_handle.h" 10#include "content/common/service_worker/service_worker_messages.h" 11 12namespace content { 13 14static const int kDocumentMainThreadId = 0; 15 16ServiceWorkerRegistrationHandle::ServiceWorkerRegistrationHandle( 17 base::WeakPtr<ServiceWorkerContextCore> context, 18 ServiceWorkerDispatcherHost* dispatcher_host, 19 int provider_id, 20 ServiceWorkerRegistration* registration) 21 : context_(context), 22 dispatcher_host_(dispatcher_host), 23 provider_id_(provider_id), 24 handle_id_(context ? context->GetNewRegistrationHandleId() 25 : kInvalidServiceWorkerRegistrationHandleId), 26 ref_count_(1), 27 registration_(registration) { 28 DCHECK(registration_.get()); 29 SetVersionAttributes(registration->installing_version(), 30 registration->waiting_version(), 31 registration->active_version()); 32 registration_->AddListener(this); 33} 34 35ServiceWorkerRegistrationHandle::~ServiceWorkerRegistrationHandle() { 36 DCHECK(registration_.get()); 37 registration_->RemoveListener(this); 38} 39 40ServiceWorkerRegistrationObjectInfo 41ServiceWorkerRegistrationHandle::GetObjectInfo() { 42 ServiceWorkerRegistrationObjectInfo info; 43 info.handle_id = handle_id_; 44 info.scope = registration_->pattern(); 45 return info; 46} 47 48ServiceWorkerObjectInfo 49ServiceWorkerRegistrationHandle::CreateServiceWorkerHandleAndPass( 50 ServiceWorkerVersion* version) { 51 ServiceWorkerObjectInfo info; 52 if (context_ && version) { 53 scoped_ptr<ServiceWorkerHandle> handle = 54 ServiceWorkerHandle::Create(context_, 55 dispatcher_host_, 56 kDocumentMainThreadId, 57 provider_id_, 58 version); 59 info = handle->GetObjectInfo(); 60 dispatcher_host_->RegisterServiceWorkerHandle(handle.Pass()); 61 } 62 return info; 63} 64 65void ServiceWorkerRegistrationHandle::IncrementRefCount() { 66 DCHECK_GT(ref_count_, 0); 67 ++ref_count_; 68} 69 70void ServiceWorkerRegistrationHandle::DecrementRefCount() { 71 DCHECK_GT(ref_count_, 0); 72 --ref_count_; 73} 74 75void ServiceWorkerRegistrationHandle::OnVersionAttributesChanged( 76 ServiceWorkerRegistration* registration, 77 ChangedVersionAttributesMask changed_mask, 78 const ServiceWorkerRegistrationInfo& info) { 79 DCHECK_EQ(registration->id(), registration_->id()); 80 SetVersionAttributes(registration->installing_version(), 81 registration->waiting_version(), 82 registration->active_version()); 83} 84 85void ServiceWorkerRegistrationHandle::OnRegistrationFailed( 86 ServiceWorkerRegistration* registration) { 87 DCHECK_EQ(registration->id(), registration_->id()); 88 ClearVersionAttributes(); 89} 90 91void ServiceWorkerRegistrationHandle::OnUpdateFound( 92 ServiceWorkerRegistration* registration) { 93 if (!dispatcher_host_) 94 return; // Could be NULL in some tests. 95 dispatcher_host_->Send(new ServiceWorkerMsg_UpdateFound( 96 kDocumentMainThreadId, GetObjectInfo())); 97} 98 99void ServiceWorkerRegistrationHandle::SetVersionAttributes( 100 ServiceWorkerVersion* installing_version, 101 ServiceWorkerVersion* waiting_version, 102 ServiceWorkerVersion* active_version) { 103 ChangedVersionAttributesMask mask; 104 105 if (installing_version != installing_version_.get()) { 106 installing_version_ = installing_version; 107 mask.add(ChangedVersionAttributesMask::INSTALLING_VERSION); 108 } 109 if (waiting_version != waiting_version_.get()) { 110 waiting_version_ = waiting_version; 111 mask.add(ChangedVersionAttributesMask::WAITING_VERSION); 112 } 113 if (active_version != active_version_.get()) { 114 active_version_ = active_version; 115 mask.add(ChangedVersionAttributesMask::ACTIVE_VERSION); 116 } 117 118 if (!dispatcher_host_) 119 return; // Could be NULL in some tests. 120 if (!mask.changed()) 121 return; 122 123 ServiceWorkerVersionAttributes attributes; 124 if (mask.installing_changed()) { 125 attributes.installing = 126 CreateServiceWorkerHandleAndPass(installing_version); 127 } 128 if (mask.waiting_changed()) { 129 attributes.waiting = 130 CreateServiceWorkerHandleAndPass(waiting_version); 131 } 132 if (mask.active_changed()) { 133 attributes.active = 134 CreateServiceWorkerHandleAndPass(active_version); 135 } 136 137 dispatcher_host_->Send(new ServiceWorkerMsg_SetVersionAttributes( 138 kDocumentMainThreadId, provider_id_, handle_id_, 139 mask.changed(), attributes)); 140} 141 142void ServiceWorkerRegistrationHandle::ClearVersionAttributes() { 143 SetVersionAttributes(NULL, NULL, NULL); 144} 145 146} // namespace content 147