service_worker_provider_host.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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 3// found in the LICENSE file. 4 5#include "content/browser/service_worker/service_worker_provider_host.h" 6 7#include "base/stl_util.h" 8#include "content/browser/message_port_message_filter.h" 9#include "content/browser/service_worker/service_worker_context_core.h" 10#include "content/browser/service_worker/service_worker_context_request_handler.h" 11#include "content/browser/service_worker/service_worker_controllee_request_handler.h" 12#include "content/browser/service_worker/service_worker_dispatcher_host.h" 13#include "content/browser/service_worker/service_worker_handle.h" 14#include "content/browser/service_worker/service_worker_utils.h" 15#include "content/browser/service_worker/service_worker_version.h" 16#include "content/common/service_worker/service_worker_messages.h" 17 18namespace content { 19 20static const int kDocumentMainThreadId = 0; 21 22ServiceWorkerProviderHost::ServiceWorkerProviderHost( 23 int process_id, int provider_id, 24 base::WeakPtr<ServiceWorkerContextCore> context, 25 ServiceWorkerDispatcherHost* dispatcher_host) 26 : process_id_(process_id), 27 provider_id_(provider_id), 28 context_(context), 29 dispatcher_host_(dispatcher_host) { 30} 31 32ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { 33 if (active_version_) 34 active_version_->RemoveControllee(this); 35 if (waiting_version_) 36 waiting_version_->RemoveWaitingControllee(this); 37} 38 39void ServiceWorkerProviderHost::SetDocumentUrl(const GURL& url) { 40 DCHECK(!url.has_ref()); 41 document_url_ = url; 42} 43 44void ServiceWorkerProviderHost::SetActiveVersion( 45 ServiceWorkerVersion* version) { 46 if (version == active_version_) 47 return; 48 scoped_refptr<ServiceWorkerVersion> previous_version = active_version_; 49 active_version_ = version; 50 if (version) 51 version->AddControllee(this); 52 if (previous_version) 53 previous_version->RemoveControllee(this); 54 55 if (!dispatcher_host_) 56 return; // Could be NULL in some tests. 57 58 ServiceWorkerObjectInfo info; 59 if (context_ && version) { 60 scoped_ptr<ServiceWorkerHandle> handle = 61 ServiceWorkerHandle::Create(context_, dispatcher_host_, 62 kDocumentMainThreadId, version); 63 info = handle->GetObjectInfo(); 64 dispatcher_host_->RegisterServiceWorkerHandle(handle.Pass()); 65 } 66 dispatcher_host_->Send( 67 new ServiceWorkerMsg_SetCurrentServiceWorker( 68 kDocumentMainThreadId, provider_id(), info)); 69} 70 71void ServiceWorkerProviderHost::SetWaitingVersion( 72 ServiceWorkerVersion* version) { 73 if (version == waiting_version_) 74 return; 75 scoped_refptr<ServiceWorkerVersion> previous_version = waiting_version_; 76 waiting_version_ = version; 77 if (version) 78 version->AddWaitingControllee(this); 79 if (previous_version) 80 previous_version->RemoveWaitingControllee(this); 81 82 if (!dispatcher_host_) 83 return; // Could be NULL in some tests. 84 85 // TODO(kinuko): dispatch pendingchange event to the document. 86} 87 88bool ServiceWorkerProviderHost::SetHostedVersionId(int64 version_id) { 89 if (!context_) 90 return true; // System is shutting down. 91 if (active_version_) 92 return false; // Unexpected bad message. 93 94 ServiceWorkerVersion* live_version = context_->GetLiveVersion(version_id); 95 if (!live_version) 96 return true; // Was deleted before it got started. 97 98 ServiceWorkerVersionInfo info = live_version->GetInfo(); 99 if (info.running_status != ServiceWorkerVersion::STARTING || 100 info.process_id != process_id_) { 101 // If we aren't trying to start this version in our process 102 // something is amiss. 103 return false; 104 } 105 106 running_hosted_version_ = live_version; 107 return true; 108} 109 110scoped_ptr<ServiceWorkerRequestHandler> 111ServiceWorkerProviderHost::CreateRequestHandler( 112 ResourceType::Type resource_type, 113 base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context) { 114 if (IsHostToRunningServiceWorker()) { 115 return scoped_ptr<ServiceWorkerRequestHandler>( 116 new ServiceWorkerContextRequestHandler( 117 context_, AsWeakPtr(), blob_storage_context, resource_type)); 118 } 119 if (ServiceWorkerUtils::IsMainResourceType(resource_type) || 120 active_version()) { 121 return scoped_ptr<ServiceWorkerRequestHandler>( 122 new ServiceWorkerControlleeRequestHandler( 123 context_, AsWeakPtr(), blob_storage_context, resource_type)); 124 } 125 return scoped_ptr<ServiceWorkerRequestHandler>(); 126} 127 128void ServiceWorkerProviderHost::PostMessage( 129 const base::string16& message, 130 const std::vector<int>& sent_message_port_ids) { 131 if (!dispatcher_host_) 132 return; // Could be NULL in some tests. 133 134 std::vector<int> new_routing_ids; 135 dispatcher_host_->message_port_message_filter()-> 136 UpdateMessagePortsWithNewRoutes(sent_message_port_ids, 137 &new_routing_ids); 138 139 dispatcher_host_->Send( 140 new ServiceWorkerMsg_MessageToDocument( 141 kDocumentMainThreadId, provider_id(), 142 message, 143 sent_message_port_ids, 144 new_routing_ids)); 145} 146 147} // namespace content 148