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  DCHECK(proxy_);
47  if (proxy_->isReady())
48    ChangeState(new_state);
49  else
50    queued_states_.push_back(new_state);
51}
52
53void WebServiceWorkerImpl::setProxy(blink::WebServiceWorkerProxy* proxy) {
54  proxy_ = proxy;
55}
56
57blink::WebServiceWorkerProxy* WebServiceWorkerImpl::proxy() {
58  return proxy_;
59}
60
61void WebServiceWorkerImpl::proxyReadyChanged() {
62  if (!proxy_->isReady())
63    return;
64  for (std::vector<blink::WebServiceWorkerState>::iterator it =
65           queued_states_.begin();
66       it != queued_states_.end();
67       ++it) {
68    ChangeState(*it);
69  }
70  queued_states_.clear();
71}
72
73blink::WebURL WebServiceWorkerImpl::scope() const {
74  return handle_ref_->scope();
75}
76
77blink::WebURL WebServiceWorkerImpl::url() const {
78  return handle_ref_->url();
79}
80
81blink::WebServiceWorkerState WebServiceWorkerImpl::state() const {
82  return state_;
83}
84
85void WebServiceWorkerImpl::postMessage(const WebString& message,
86                                       WebMessagePortChannelArray* channels) {
87  thread_safe_sender_->Send(new ServiceWorkerHostMsg_PostMessageToWorker(
88      handle_ref_->handle_id(),
89      message,
90      WebMessagePortChannelImpl::ExtractMessagePortIDs(channels)));
91}
92
93void WebServiceWorkerImpl::ChangeState(blink::WebServiceWorkerState new_state) {
94  DCHECK(proxy_);
95  DCHECK(proxy_->isReady());
96  state_ = new_state;
97  proxy_->dispatchStateChangeEvent();
98}
99
100}  // namespace content
101