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/child/service_worker/web_service_worker_impl.h"
6
7#include "content/child/service_worker/service_worker_dispatcher.h"
8#include "content/child/service_worker/service_worker_handle_reference.h"
9#include "content/child/thread_safe_sender.h"
10#include "content/child/webmessageportchannel_impl.h"
11#include "content/common/service_worker/service_worker_messages.h"
12#include "third_party/WebKit/public/platform/WebServiceWorkerProxy.h"
13#include "third_party/WebKit/public/platform/WebString.h"
14
15using blink::WebMessagePortChannel;
16using blink::WebMessagePortChannelArray;
17using blink::WebMessagePortChannelClient;
18using blink::WebString;
19
20namespace content {
21
22WebServiceWorkerImpl::WebServiceWorkerImpl(
23    scoped_ptr<ServiceWorkerHandleReference> handle_ref,
24    ThreadSafeSender* thread_safe_sender)
25    : handle_ref_(handle_ref.Pass()),
26      state_(handle_ref_->state()),
27      thread_safe_sender_(thread_safe_sender),
28      proxy_(NULL) {
29  ServiceWorkerDispatcher* dispatcher =
30      ServiceWorkerDispatcher::GetThreadSpecificInstance();
31  DCHECK(dispatcher);
32  dispatcher->AddServiceWorker(handle_ref_->handle_id(), this);
33}
34
35WebServiceWorkerImpl::~WebServiceWorkerImpl() {
36  if (handle_ref_->handle_id() == kInvalidServiceWorkerHandleId)
37    return;
38  ServiceWorkerDispatcher* dispatcher =
39      ServiceWorkerDispatcher::GetThreadSpecificInstance();
40  if (dispatcher)
41    dispatcher->RemoveServiceWorker(handle_ref_->handle_id());
42}
43
44void WebServiceWorkerImpl::OnStateChanged(
45    blink::WebServiceWorkerState new_state) {
46  if (proxy_ && proxy_->isReady())
47    CommitState(new_state);
48  else
49    queued_states_.push_back(new_state);
50}
51
52void WebServiceWorkerImpl::setProxy(blink::WebServiceWorkerProxy* proxy) {
53  proxy_ = proxy;
54}
55
56blink::WebServiceWorkerProxy* WebServiceWorkerImpl::proxy() {
57  return proxy_;
58}
59
60void WebServiceWorkerImpl::proxyReadyChanged() {
61  if (!proxy_->isReady())
62    return;
63  for (std::vector<blink::WebServiceWorkerState>::iterator it =
64           queued_states_.begin();
65       it != queued_states_.end();
66       ++it) {
67    CommitState(*it);
68  }
69  queued_states_.clear();
70}
71
72blink::WebURL WebServiceWorkerImpl::scope() const {
73  return handle_ref_->scope();
74}
75
76blink::WebURL WebServiceWorkerImpl::url() const {
77  return handle_ref_->url();
78}
79
80blink::WebServiceWorkerState WebServiceWorkerImpl::state() const {
81  return state_;
82}
83
84void WebServiceWorkerImpl::postMessage(const WebString& message,
85                                       WebMessagePortChannelArray* channels) {
86  thread_safe_sender_->Send(new ServiceWorkerHostMsg_PostMessageToWorker(
87      handle_ref_->handle_id(),
88      message,
89      WebMessagePortChannelImpl::ExtractMessagePortIDs(channels)));
90}
91
92void WebServiceWorkerImpl::CommitState(blink::WebServiceWorkerState new_state) {
93  DCHECK(proxy_);
94  DCHECK(proxy_->isReady());
95  state_ = new_state;
96  proxy_->dispatchStateChangeEvent();
97}
98
99}  // namespace content
100