1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file. 4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/service_worker/service_worker_provider_context.h" 6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/bind.h" 8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/stl_util.h" 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/child_thread.h" 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/service_worker/service_worker_dispatcher.h" 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/service_worker/service_worker_handle_reference.h" 13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/thread_safe_sender.h" 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/worker_task_runner.h" 15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/common/service_worker/service_worker_messages.h" 16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace content { 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ServiceWorkerProviderContext::ServiceWorkerProviderContext(int provider_id) 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : provider_id_(provider_id), 21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) main_thread_loop_proxy_(base::MessageLoopProxy::current()) { 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!ChildThread::current()) 23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; // May be null in some tests. 24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) thread_safe_sender_ = ChildThread::current()->thread_safe_sender(); 25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ServiceWorkerDispatcher* dispatcher = 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) thread_safe_sender_); 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(dispatcher); 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dispatcher->AddProviderContext(this); 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ServiceWorkerProviderContext::~ServiceWorkerProviderContext() { 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (ServiceWorkerDispatcher* dispatcher = 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ServiceWorkerDispatcher::GetThreadSpecificInstance()) { 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dispatcher->RemoveProviderContext(this); 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)ServiceWorkerHandleReference* ServiceWorkerProviderContext::waiting() { 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread()); 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return waiting_.get(); 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ServiceWorkerHandleReference* ServiceWorkerProviderContext::current() { 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread()); 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return current_.get(); 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerProviderContext::OnServiceWorkerStateChanged( 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int handle_id, 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) blink::WebServiceWorkerState state) { 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ServiceWorkerHandleReference* which = NULL; 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (handle_id == current_handle_id()) { 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) which = current_.get(); 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else if (handle_id == waiting_handle_id()) { 56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) which = waiting_.get(); 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // We should only get messages for ServiceWorkers associated with 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // this provider. 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(which); 62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) which->set_state(state); 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(kinuko): We can forward the message to other threads here 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // when we support navigator.serviceWorker in dedicated workers. 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ServiceWorkerProviderContext::OnSetWaitingServiceWorker( 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int provider_id, 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ServiceWorkerObjectInfo& info) { 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK_EQ(provider_id_, provider_id); 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) waiting_ = ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_); 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerProviderContext::OnSetCurrentServiceWorker( 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int provider_id, 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const ServiceWorkerObjectInfo& info) { 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(provider_id_, provider_id); 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // This context is is the primary owner of this handle, keeps the 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // initial reference until it goes away. 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) current_ = ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_); 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(kinuko): We can forward the message to other threads here 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // when we support navigator.serviceWorker in dedicated workers. 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)int ServiceWorkerProviderContext::current_handle_id() const { 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread()); 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return current_ ? current_->info().handle_id : kInvalidServiceWorkerHandleId; 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int ServiceWorkerProviderContext::waiting_handle_id() const { 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread()); 96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return waiting_ ? waiting_->info().handle_id : kInvalidServiceWorkerHandleId; 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace content 100