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