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