service_worker_provider_host.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/service_worker/service_worker_provider_host.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/stl_util.h"
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/message_port_message_filter.h"
9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/service_worker/service_worker_context_core.h"
105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_context_request_handler.h"
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_controllee_request_handler.h"
12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/service_worker/service_worker_dispatcher_host.h"
13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/service_worker/service_worker_handle.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_utils.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/service_worker/service_worker_version.h"
160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/common/service_worker/service_worker_messages.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace content {
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)static const int kDocumentMainThreadId = 0;
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ServiceWorkerProviderHost::ServiceWorkerProviderHost(
23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    int process_id, int provider_id,
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::WeakPtr<ServiceWorkerContextCore> context,
25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ServiceWorkerDispatcherHost* dispatcher_host)
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : process_id_(process_id),
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      provider_id_(provider_id),
28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      context_(context),
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      dispatcher_host_(dispatcher_host) {
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (active_version_)
34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    active_version_->RemoveControllee(this);
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (waiting_version_)
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    waiting_version_->RemoveWaitingControllee(this);
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ServiceWorkerProviderHost::SetActiveVersion(
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ServiceWorkerVersion* version) {
41a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (version == active_version_)
42a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<ServiceWorkerVersion> previous_version = active_version_;
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  active_version_ = version;
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (version)
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    version->AddControllee(this);
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (previous_version)
48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    previous_version->RemoveControllee(this);
49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!dispatcher_host_)
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;  // Could be NULL in some tests.
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ServiceWorkerObjectInfo info;
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (context_ && version) {
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<ServiceWorkerHandle> handle =
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        ServiceWorkerHandle::Create(context_, dispatcher_host_,
57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                    kDocumentMainThreadId, version);
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    info = handle->GetObjectInfo();
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    dispatcher_host_->RegisterServiceWorkerHandle(handle.Pass());
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  dispatcher_host_->Send(
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      new ServiceWorkerMsg_SetCurrentServiceWorker(
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          kDocumentMainThreadId, provider_id(), info));
64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerProviderHost::SetWaitingVersion(
67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ServiceWorkerVersion* version) {
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (version == waiting_version_)
69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<ServiceWorkerVersion> previous_version = waiting_version_;
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  waiting_version_ = version;
72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (version)
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    version->AddWaitingControllee(this);
74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (previous_version)
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    previous_version->RemoveWaitingControllee(this);
76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!dispatcher_host_)
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;  // Could be NULL in some tests.
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // TODO(kinuko): dispatch pendingchange event to the document.
81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool ServiceWorkerProviderHost::SetHostedVersionId(int64 version_id) {
84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!context_)
85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return true;  // System is shutting down.
86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (active_version_)
87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;  // Unexpected bad message.
88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ServiceWorkerVersion* live_version = context_->GetLiveVersion(version_id);
90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!live_version)
91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return true;  // Was deleted before it got started.
92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ServiceWorkerVersionInfo info = live_version->GetInfo();
94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (info.running_status != ServiceWorkerVersion::STARTING ||
95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      info.process_id != process_id_) {
96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // If we aren't trying to start this version in our process
97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // something is amiss.
98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  running_hosted_version_ = live_version;
102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return true;
103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuscoped_ptr<ServiceWorkerRequestHandler>
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuServiceWorkerProviderHost::CreateRequestHandler(
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ResourceType::Type resource_type,
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context) {
1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (IsHostToRunningServiceWorker()) {
1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return scoped_ptr<ServiceWorkerRequestHandler>(
1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        new ServiceWorkerContextRequestHandler(
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            context_, AsWeakPtr(), blob_storage_context, resource_type));
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (ServiceWorkerUtils::IsMainResourceType(resource_type) ||
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      active_version()) {
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return scoped_ptr<ServiceWorkerRequestHandler>(
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        new ServiceWorkerControlleeRequestHandler(
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            context_, AsWeakPtr(), blob_storage_context, resource_type));
1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return scoped_ptr<ServiceWorkerRequestHandler>();
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerProviderHost::PostMessage(
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const base::string16& message,
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::vector<int>& sent_message_port_ids) {
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!dispatcher_host_)
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;  // Could be NULL in some tests.
128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::vector<int> new_routing_ids;
130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  dispatcher_host_->message_port_message_filter()->
131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      UpdateMessagePortsWithNewRoutes(sent_message_port_ids,
132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                      &new_routing_ids);
133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  dispatcher_host_->Send(
135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      new ServiceWorkerMsg_MessageToDocument(
136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          kDocumentMainThreadId, provider_id(),
137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          message,
138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          sent_message_port_ids,
139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          new_routing_ids));
140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace content
143