blob: 432592fea6edd77c1d9f7d02fc5b8b48d5057a9c [file] [log] [blame]
lazyboyee4adef2016-05-24 00:55:161// Copyright 2016 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 "extensions/renderer/worker_thread_dispatcher.h"
6
7#include "base/threading/thread_local.h"
8#include "base/values.h"
9#include "content/public/child/worker_thread.h"
10#include "content/public/renderer/render_thread.h"
11#include "extensions/common/extension_messages.h"
rdevlin.cronin9f338892016-11-21 19:37:0012#include "extensions/renderer/extension_bindings_system.h"
13#include "extensions/renderer/js_extension_bindings_system.h"
lazyboyee4adef2016-05-24 00:55:1614#include "extensions/renderer/service_worker_data.h"
15
16namespace extensions {
17
18namespace {
19
20base::LazyInstance<WorkerThreadDispatcher> g_instance =
21 LAZY_INSTANCE_INITIALIZER;
22base::LazyInstance<base::ThreadLocalPointer<extensions::ServiceWorkerData>>
23 g_data_tls = LAZY_INSTANCE_INITIALIZER;
24
25void OnResponseOnWorkerThread(int request_id,
26 bool succeeded,
27 const std::unique_ptr<base::ListValue>& response,
28 const std::string& error) {
rdevlin.cronin9f338892016-11-21 19:37:0029 // TODO(devlin): Using the RequestSender directly here won't work with
30 // NativeExtensionBindingsSystem (since there is no associated RequestSender
31 // in that case). We should instead be going
32 // ExtensionBindingsSystem::HandleResponse().
lazyboy4c82177a2016-10-18 00:04:0933 ServiceWorkerData* data = g_data_tls.Pointer()->Get();
34 WorkerThreadDispatcher::GetRequestSender()->HandleWorkerResponse(
35 request_id, data->service_worker_version_id(), succeeded, *response,
36 error);
lazyboyee4adef2016-05-24 00:55:1637}
38
rdevlin.cronin9f338892016-11-21 19:37:0039ServiceWorkerData* GetServiceWorkerData() {
40 ServiceWorkerData* data = g_data_tls.Pointer()->Get();
41 DCHECK(data);
42 return data;
43}
44
lazyboyee4adef2016-05-24 00:55:1645} // namespace
46
47WorkerThreadDispatcher::WorkerThreadDispatcher() {}
48WorkerThreadDispatcher::~WorkerThreadDispatcher() {}
49
50WorkerThreadDispatcher* WorkerThreadDispatcher::Get() {
51 return g_instance.Pointer();
52}
53
54void WorkerThreadDispatcher::Init(content::RenderThread* render_thread) {
55 DCHECK(render_thread);
56 DCHECK_EQ(content::RenderThread::Get(), render_thread);
57 DCHECK(!message_filter_);
58 message_filter_ = render_thread->GetSyncMessageFilter();
59 render_thread->AddObserver(this);
60}
61
rdevlin.cronin9f338892016-11-21 19:37:0062// static
63ExtensionBindingsSystem* WorkerThreadDispatcher::GetBindingsSystem() {
64 return GetServiceWorkerData()->bindings_system();
lazyboyee4adef2016-05-24 00:55:1665}
66
67// static
lazyboy4c82177a2016-10-18 00:04:0968ServiceWorkerRequestSender* WorkerThreadDispatcher::GetRequestSender() {
rdevlin.cronin9f338892016-11-21 19:37:0069 return static_cast<ServiceWorkerRequestSender*>(
70 GetBindingsSystem()->GetRequestSender());
71}
72
73// static
74V8SchemaRegistry* WorkerThreadDispatcher::GetV8SchemaRegistry() {
75 return GetServiceWorkerData()->v8_schema_registry();
lazyboyee4adef2016-05-24 00:55:1676}
77
78bool WorkerThreadDispatcher::OnControlMessageReceived(
79 const IPC::Message& message) {
80 bool handled = true;
81 IPC_BEGIN_MESSAGE_MAP(WorkerThreadDispatcher, message)
82 IPC_MESSAGE_HANDLER(ExtensionMsg_ResponseWorker, OnResponseWorker)
83 IPC_MESSAGE_UNHANDLED(handled = false)
84 IPC_END_MESSAGE_MAP()
85 return handled;
86}
87
88bool WorkerThreadDispatcher::Send(IPC::Message* message) {
89 return message_filter_->Send(message);
90}
91
92void WorkerThreadDispatcher::OnResponseWorker(int worker_thread_id,
93 int request_id,
94 bool succeeded,
95 const base::ListValue& response,
96 const std::string& error) {
97 content::WorkerThread::PostTask(
98 worker_thread_id,
99 base::Bind(&OnResponseOnWorkerThread, request_id, succeeded,
100 // TODO(lazyboy): Can we avoid CreateDeepCopy()?
101 base::Passed(response.CreateDeepCopy()), error));
102}
103
rdevlin.cronin9f338892016-11-21 19:37:00104void WorkerThreadDispatcher::AddWorkerData(
105 int64_t service_worker_version_id,
106 ResourceBundleSourceMap* source_map) {
lazyboyee4adef2016-05-24 00:55:16107 ServiceWorkerData* data = g_data_tls.Pointer()->Get();
108 if (!data) {
rdevlin.cronin9f338892016-11-21 19:37:00109 std::unique_ptr<ExtensionBindingsSystem> bindings_system =
110 base::MakeUnique<JsExtensionBindingsSystem>(
111 source_map, base::MakeUnique<ServiceWorkerRequestSender>(
112 this, service_worker_version_id));
113 ServiceWorkerData* new_data = new ServiceWorkerData(
114 service_worker_version_id, std::move(bindings_system));
lazyboyee4adef2016-05-24 00:55:16115 g_data_tls.Pointer()->Set(new_data);
116 }
117}
118
lazyboy4c82177a2016-10-18 00:04:09119void WorkerThreadDispatcher::RemoveWorkerData(
120 int64_t service_worker_version_id) {
lazyboyee4adef2016-05-24 00:55:16121 ServiceWorkerData* data = g_data_tls.Pointer()->Get();
122 if (data) {
lazyboy4c82177a2016-10-18 00:04:09123 DCHECK_EQ(service_worker_version_id, data->service_worker_version_id());
lazyboyee4adef2016-05-24 00:55:16124 delete data;
125 g_data_tls.Pointer()->Set(nullptr);
126 }
127}
128
129} // namespace extensions