embedded_worker_registry.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/embedded_worker_registry.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/stl_util.h"
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/embedded_worker_instance.h"
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_context_core.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/common/service_worker/embedded_worker_messages.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ipc/ipc_message.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ipc/ipc_sender.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace content {
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)EmbeddedWorkerRegistry::EmbeddedWorkerRegistry(
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::WeakPtr<ServiceWorkerContextCore> context)
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : context_(context),
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      next_embedded_worker_id_(0) {}
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)scoped_ptr<EmbeddedWorkerInstance> EmbeddedWorkerRegistry::CreateWorker() {
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<EmbeddedWorkerInstance> worker(
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      new EmbeddedWorkerInstance(this, next_embedded_worker_id_));
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  worker_map_[next_embedded_worker_id_++] = worker.get();
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return worker.Pass();
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ServiceWorkerStatusCode EmbeddedWorkerRegistry::StartWorker(
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int process_id,
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int embedded_worker_id,
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int64 service_worker_version_id,
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& scope,
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const GURL& script_url) {
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return Send(
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      process_id,
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new EmbeddedWorkerMsg_StartWorker(
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          embedded_worker_id, service_worker_version_id, scope, script_url));
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ServiceWorkerStatusCode EmbeddedWorkerRegistry::StopWorker(
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int process_id, int embedded_worker_id) {
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return Send(process_id,
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              new EmbeddedWorkerMsg_StopWorker(embedded_worker_id));
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool EmbeddedWorkerRegistry::OnMessageReceived(const IPC::Message& message) {
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // TODO(kinuko): Move all EmbeddedWorker message handling from
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // ServiceWorkerDispatcherHost.
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  WorkerInstanceMap::iterator found = worker_map_.find(message.routing_id());
510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (found == worker_map_.end()) {
520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    LOG(ERROR) << "Worker " << message.routing_id() << " not registered";
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return false;
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return found->second->OnMessageReceived(message);
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void EmbeddedWorkerRegistry::OnWorkerStarted(
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int process_id, int thread_id, int embedded_worker_id) {
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!ContainsKey(worker_process_map_, process_id) ||
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         worker_process_map_[process_id].count(embedded_worker_id) == 0);
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (found == worker_map_.end()) {
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  worker_process_map_[process_id].insert(embedded_worker_id);
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(found->second->process_id(), process_id);
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  found->second->OnStarted(thread_id);
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void EmbeddedWorkerRegistry::OnWorkerStopped(
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int process_id, int embedded_worker_id) {
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (found == worker_map_.end()) {
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(found->second->process_id(), process_id);
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  worker_process_map_[process_id].erase(embedded_worker_id);
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  found->second->OnStopped();
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool EmbeddedWorkerRegistry::OnReplyToBrowser(
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int embedded_worker_id, int request_id, const IPC::Message& message) {
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (found == worker_map_.end()) {
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return false;
900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return found->second->OnReplyReceived(request_id, message);
920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid EmbeddedWorkerRegistry::OnReportException(
950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int embedded_worker_id,
960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::string16& error_message,
970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int line_number,
980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int column_number,
990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& source_url) {
1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (found == worker_map_.end()) {
1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  found->second->OnReportException(
1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      error_message, line_number, column_number, source_url);
1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid EmbeddedWorkerRegistry::OnReportConsoleMessage(
1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int embedded_worker_id,
1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int source_identifier,
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int message_level,
1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::string16& message,
1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int line_number,
1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& source_url) {
1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (found == worker_map_.end()) {
1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  found->second->OnReportConsoleMessage(
1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      source_identifier, message_level, message, line_number, source_url);
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void EmbeddedWorkerRegistry::AddChildProcessSender(
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int process_id, IPC::Sender* sender) {
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  process_sender_map_[process_id] = sender;
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!ContainsKey(worker_process_map_, process_id));
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void EmbeddedWorkerRegistry::RemoveChildProcessSender(int process_id) {
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  process_sender_map_.erase(process_id);
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::map<int, std::set<int> >::iterator found =
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      worker_process_map_.find(process_id);
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (found != worker_process_map_.end()) {
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::set<int>& worker_set = worker_process_map_[process_id];
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (std::set<int>::const_iterator it = worker_set.begin();
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         it != worker_set.end();
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         ++it) {
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int embedded_worker_id = *it;
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(ContainsKey(worker_map_, embedded_worker_id));
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      worker_map_[embedded_worker_id]->OnStopped();
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    worker_process_map_.erase(found);
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)EmbeddedWorkerInstance* EmbeddedWorkerRegistry::GetWorker(
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int embedded_worker_id) {
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (found == worker_map_.end())
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return NULL;
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return found->second;
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)EmbeddedWorkerRegistry::~EmbeddedWorkerRegistry() {}
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ServiceWorkerStatusCode EmbeddedWorkerRegistry::Send(
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int process_id, IPC::Message* message) {
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!context_)
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return SERVICE_WORKER_ERROR_ABORT;
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ProcessToSenderMap::iterator found = process_sender_map_.find(process_id);
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (found == process_sender_map_.end())
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND;
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!found->second->Send(message))
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return SERVICE_WORKER_ERROR_IPC_FAILED;
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return SERVICE_WORKER_OK;
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void EmbeddedWorkerRegistry::RemoveWorker(int process_id,
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          int embedded_worker_id) {
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(ContainsKey(worker_map_, embedded_worker_id));
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  worker_map_.erase(embedded_worker_id);
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  worker_process_map_.erase(process_id);
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace content
178