Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / content / child / service_worker / service_worker_provider_context.cc
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