service_worker_provider_host.cc revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
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"
8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/service_worker/service_worker_context_core.h"
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_context_request_handler.h"
105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_controllee_request_handler.h"
11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/service_worker/service_worker_dispatcher_host.h"
12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/service_worker/service_worker_handle.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_utils.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/service_worker/service_worker_version.h"
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/common/service_worker/service_worker_messages.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace content {
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ServiceWorkerProviderHost::ServiceWorkerProviderHost(
20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    int process_id, int provider_id,
21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::WeakPtr<ServiceWorkerContextCore> context,
22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ServiceWorkerDispatcherHost* dispatcher_host)
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : process_id_(process_id),
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      provider_id_(provider_id),
25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      context_(context),
26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      dispatcher_host_(dispatcher_host) {
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (active_version_)
31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    active_version_->RemoveControllee(this);
32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (pending_version_)
33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    pending_version_->RemovePendingControllee(this);
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerProviderHost::AddScriptClient(int thread_id) {
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!ContainsKey(script_client_thread_ids_, thread_id));
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  script_client_thread_ids_.insert(thread_id);
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerProviderHost::RemoveScriptClient(int thread_id) {
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(ContainsKey(script_client_thread_ids_, thread_id));
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  script_client_thread_ids_.erase(thread_id);
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ServiceWorkerProviderHost::SetActiveVersion(
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ServiceWorkerVersion* version) {
48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (version == active_version_)
49a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<ServiceWorkerVersion> previous_version = active_version_;
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  active_version_ = version;
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (version)
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    version->AddControllee(this);
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (previous_version)
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    previous_version->RemoveControllee(this);
56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!dispatcher_host_)
58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;  // Could be NULL in some tests.
59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (std::set<int>::iterator it = script_client_thread_ids_.begin();
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch       it != script_client_thread_ids_.end();
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch       ++it) {
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ServiceWorkerObjectInfo info;
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (context_ && version) {
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      scoped_ptr<ServiceWorkerHandle> handle =
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          ServiceWorkerHandle::Create(context_, dispatcher_host_, *it, version);
670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      info = handle->GetObjectInfo();
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      dispatcher_host_->RegisterServiceWorkerHandle(handle.Pass());
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    dispatcher_host_->Send(
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        new ServiceWorkerMsg_SetCurrentServiceWorker(*it, provider_id(), info));
72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ServiceWorkerProviderHost::SetPendingVersion(
76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ServiceWorkerVersion* version) {
77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (version == pending_version_)
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_refptr<ServiceWorkerVersion> previous_version = pending_version_;
80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  pending_version_ = version;
81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (version)
82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    version->AddPendingControllee(this);
83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (previous_version)
84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    previous_version->RemovePendingControllee(this);
85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!dispatcher_host_)
87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;  // Could be NULL in some tests.
88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (std::set<int>::iterator it = script_client_thread_ids_.begin();
90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch       it != script_client_thread_ids_.end();
91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch       ++it) {
92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // TODO(kinuko): dispatch pendingchange event to the script clients.
93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool ServiceWorkerProviderHost::SetHostedVersionId(int64 version_id) {
97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!context_)
98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return true;  // System is shutting down.
99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (active_version_)
100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;  // Unexpected bad message.
101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ServiceWorkerVersion* live_version = context_->GetLiveVersion(version_id);
103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!live_version)
104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return true;  // Was deleted before it got started.
105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ServiceWorkerVersionInfo info = live_version->GetInfo();
107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (info.running_status != ServiceWorkerVersion::STARTING ||
108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      info.process_id != process_id_) {
109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // If we aren't trying to start this version in our process
110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // something is amiss.
111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  running_hosted_version_ = live_version;
115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return true;
116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuscoped_ptr<ServiceWorkerRequestHandler>
1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuServiceWorkerProviderHost::CreateRequestHandler(
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ResourceType::Type resource_type) {
1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (IsHostToRunningServiceWorker()) {
1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return scoped_ptr<ServiceWorkerRequestHandler>(
1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        new ServiceWorkerContextRequestHandler(
1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            context_, AsWeakPtr(), resource_type));
1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (ServiceWorkerUtils::IsMainResourceType(resource_type) ||
1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      active_version()) {
1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return scoped_ptr<ServiceWorkerRequestHandler>(
1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        new ServiceWorkerControlleeRequestHandler(
1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            context_, AsWeakPtr(), resource_type));
1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return scoped_ptr<ServiceWorkerRequestHandler>();
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace content
136