Home | History | Annotate | Download | only in service_worker
      1 // Copyright 2014 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/child/service_worker/service_worker_provider_context.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/message_loop/message_loop_proxy.h"
      9 #include "base/stl_util.h"
     10 #include "content/child/child_thread.h"
     11 #include "content/child/service_worker/service_worker_dispatcher.h"
     12 #include "content/child/service_worker/service_worker_handle_reference.h"
     13 #include "content/child/thread_safe_sender.h"
     14 #include "content/child/worker_task_runner.h"
     15 #include "content/common/service_worker/service_worker_messages.h"
     16 
     17 namespace content {
     18 
     19 ServiceWorkerProviderContext::ServiceWorkerProviderContext(int provider_id)
     20     : provider_id_(provider_id),
     21       main_thread_loop_proxy_(base::MessageLoopProxy::current()) {
     22   if (!ChildThread::current())
     23     return;  // May be null in some tests.
     24   thread_safe_sender_ = ChildThread::current()->thread_safe_sender();
     25   ServiceWorkerDispatcher* dispatcher =
     26       ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
     27           thread_safe_sender_);
     28   DCHECK(dispatcher);
     29   dispatcher->AddProviderContext(this);
     30 }
     31 
     32 ServiceWorkerProviderContext::~ServiceWorkerProviderContext() {
     33   if (ServiceWorkerDispatcher* dispatcher =
     34           ServiceWorkerDispatcher::GetThreadSpecificInstance()) {
     35     dispatcher->RemoveProviderContext(this);
     36   }
     37 }
     38 
     39 ServiceWorkerHandleReference* ServiceWorkerProviderContext::waiting() {
     40   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
     41   return waiting_.get();
     42 }
     43 
     44 ServiceWorkerHandleReference* ServiceWorkerProviderContext::current() {
     45   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
     46   return current_.get();
     47 }
     48 
     49 void ServiceWorkerProviderContext::OnServiceWorkerStateChanged(
     50     int handle_id,
     51     blink::WebServiceWorkerState state) {
     52   ServiceWorkerHandleReference* which = NULL;
     53   if (handle_id == current_handle_id()) {
     54     which = current_.get();
     55   } else if (handle_id == waiting_handle_id()) {
     56     which = waiting_.get();
     57   }
     58 
     59   // We should only get messages for ServiceWorkers associated with
     60   // this provider.
     61   DCHECK(which);
     62 
     63   which->set_state(state);
     64 
     65   // TODO(kinuko): We can forward the message to other threads here
     66   // when we support navigator.serviceWorker in dedicated workers.
     67 }
     68 
     69 void ServiceWorkerProviderContext::OnSetWaitingServiceWorker(
     70     int provider_id,
     71     const ServiceWorkerObjectInfo& info) {
     72   DCHECK_EQ(provider_id_, provider_id);
     73   waiting_ = ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_);
     74 }
     75 
     76 void ServiceWorkerProviderContext::OnSetCurrentServiceWorker(
     77     int provider_id,
     78     const ServiceWorkerObjectInfo& info) {
     79   DCHECK_EQ(provider_id_, provider_id);
     80 
     81   // This context is is the primary owner of this handle, keeps the
     82   // initial reference until it goes away.
     83   current_ = ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_);
     84 
     85   // TODO(kinuko): We can forward the message to other threads here
     86   // when we support navigator.serviceWorker in dedicated workers.
     87 }
     88 
     89 int ServiceWorkerProviderContext::current_handle_id() const {
     90   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
     91   return current_ ? current_->info().handle_id : kInvalidServiceWorkerHandleId;
     92 }
     93 
     94 int ServiceWorkerProviderContext::waiting_handle_id() const {
     95   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
     96   return waiting_ ? waiting_->info().handle_id : kInvalidServiceWorkerHandleId;
     97 }
     98 
     99 }  // namespace content
    100