blob: 07f0a3a6485f3a75d3e97b22c074c021a93a6277 [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
fdorayba121422016-12-23 19:51:487#include "base/memory/ptr_util.h"
lazyboyee4adef2016-05-24 00:55:168#include "base/threading/thread_local.h"
9#include "base/values.h"
10#include "content/public/child/worker_thread.h"
11#include "content/public/renderer/render_thread.h"
12#include "extensions/common/extension_messages.h"
rdevlin.cronin71d78789e2016-11-22 19:49:2713#include "extensions/common/feature_switch.h"
rdevlin.cronin9f338892016-11-21 19:37:0014#include "extensions/renderer/extension_bindings_system.h"
15#include "extensions/renderer/js_extension_bindings_system.h"
rdevlin.cronin71d78789e2016-11-22 19:49:2716#include "extensions/renderer/native_extension_bindings_system.h"
lazyboyee4adef2016-05-24 00:55:1617#include "extensions/renderer/service_worker_data.h"
18
19namespace extensions {
20
21namespace {
22
scottmg5e65e3a2017-03-08 08:48:4623base::LazyInstance<WorkerThreadDispatcher>::DestructorAtExit g_instance =
lazyboyee4adef2016-05-24 00:55:1624 LAZY_INSTANCE_INITIALIZER;
scottmg5e65e3a2017-03-08 08:48:4625base::LazyInstance<base::ThreadLocalPointer<extensions::ServiceWorkerData>>::
26 DestructorAtExit g_data_tls = LAZY_INSTANCE_INITIALIZER;
lazyboyee4adef2016-05-24 00:55:1627
28void OnResponseOnWorkerThread(int request_id,
29 bool succeeded,
30 const std::unique_ptr<base::ListValue>& response,
31 const std::string& error) {
rdevlin.cronin9f338892016-11-21 19:37:0032 // TODO(devlin): Using the RequestSender directly here won't work with
33 // NativeExtensionBindingsSystem (since there is no associated RequestSender
34 // in that case). We should instead be going
35 // ExtensionBindingsSystem::HandleResponse().
lazyboy4c82177a2016-10-18 00:04:0936 ServiceWorkerData* data = g_data_tls.Pointer()->Get();
37 WorkerThreadDispatcher::GetRequestSender()->HandleWorkerResponse(
38 request_id, data->service_worker_version_id(), succeeded, *response,
39 error);
lazyboyee4adef2016-05-24 00:55:1640}
41
rdevlin.cronin9f338892016-11-21 19:37:0042ServiceWorkerData* GetServiceWorkerData() {
43 ServiceWorkerData* data = g_data_tls.Pointer()->Get();
44 DCHECK(data);
45 return data;
46}
47
rdevlin.cronin71d78789e2016-11-22 19:49:2748// Handler for sending IPCs with native extension bindings.
49void SendRequestIPC(ScriptContext* context,
rdevlin.cronin0e622d522017-03-31 01:19:0050 const ExtensionHostMsg_Request_Params& params,
51 binding::RequestThread thread) {
rdevlin.cronin71d78789e2016-11-22 19:49:2752 // TODO(devlin): This won't handle incrementing/decrementing service worker
53 // lifetime.
54 WorkerThreadDispatcher::Get()->Send(
55 new ExtensionHostMsg_RequestWorker(params));
56}
57
rdevlin.croninea496fd2017-01-13 18:22:1458void SendEventListenersIPC(binding::EventListenersChanged changed,
59 ScriptContext* context,
rdevlin.croninddc50bcb2017-03-23 00:55:5260 const std::string& event_name,
rdevlin.cronin707b7322017-03-30 20:56:2661 const base::DictionaryValue* filter,
62 bool was_manual) {
rdevlin.croninea496fd2017-01-13 18:22:1463 // TODO(devlin/lazyboy): Wire this up once extension workers support events.
64}
65
lazyboyee4adef2016-05-24 00:55:1666} // namespace
67
68WorkerThreadDispatcher::WorkerThreadDispatcher() {}
69WorkerThreadDispatcher::~WorkerThreadDispatcher() {}
70
71WorkerThreadDispatcher* WorkerThreadDispatcher::Get() {
72 return g_instance.Pointer();
73}
74
75void WorkerThreadDispatcher::Init(content::RenderThread* render_thread) {
76 DCHECK(render_thread);
77 DCHECK_EQ(content::RenderThread::Get(), render_thread);
78 DCHECK(!message_filter_);
79 message_filter_ = render_thread->GetSyncMessageFilter();
80 render_thread->AddObserver(this);
81}
82
rdevlin.cronin9f338892016-11-21 19:37:0083// static
84ExtensionBindingsSystem* WorkerThreadDispatcher::GetBindingsSystem() {
85 return GetServiceWorkerData()->bindings_system();
lazyboyee4adef2016-05-24 00:55:1686}
87
88// static
lazyboy4c82177a2016-10-18 00:04:0989ServiceWorkerRequestSender* WorkerThreadDispatcher::GetRequestSender() {
rdevlin.cronin9f338892016-11-21 19:37:0090 return static_cast<ServiceWorkerRequestSender*>(
91 GetBindingsSystem()->GetRequestSender());
92}
93
94// static
95V8SchemaRegistry* WorkerThreadDispatcher::GetV8SchemaRegistry() {
96 return GetServiceWorkerData()->v8_schema_registry();
lazyboyee4adef2016-05-24 00:55:1697}
98
99bool WorkerThreadDispatcher::OnControlMessageReceived(
100 const IPC::Message& message) {
101 bool handled = true;
102 IPC_BEGIN_MESSAGE_MAP(WorkerThreadDispatcher, message)
103 IPC_MESSAGE_HANDLER(ExtensionMsg_ResponseWorker, OnResponseWorker)
104 IPC_MESSAGE_UNHANDLED(handled = false)
105 IPC_END_MESSAGE_MAP()
106 return handled;
107}
108
109bool WorkerThreadDispatcher::Send(IPC::Message* message) {
110 return message_filter_->Send(message);
111}
112
113void WorkerThreadDispatcher::OnResponseWorker(int worker_thread_id,
114 int request_id,
115 bool succeeded,
116 const base::ListValue& response,
117 const std::string& error) {
118 content::WorkerThread::PostTask(
119 worker_thread_id,
120 base::Bind(&OnResponseOnWorkerThread, request_id, succeeded,
121 // TODO(lazyboy): Can we avoid CreateDeepCopy()?
122 base::Passed(response.CreateDeepCopy()), error));
123}
124
rdevlin.cronin9f338892016-11-21 19:37:00125void WorkerThreadDispatcher::AddWorkerData(
126 int64_t service_worker_version_id,
127 ResourceBundleSourceMap* source_map) {
lazyboyee4adef2016-05-24 00:55:16128 ServiceWorkerData* data = g_data_tls.Pointer()->Get();
129 if (!data) {
rdevlin.cronin71d78789e2016-11-22 19:49:27130 std::unique_ptr<ExtensionBindingsSystem> bindings_system;
131 if (FeatureSwitch::native_crx_bindings()->IsEnabled()) {
132 bindings_system = base::MakeUnique<NativeExtensionBindingsSystem>(
rdevlin.croninea496fd2017-01-13 18:22:14133 base::Bind(&SendRequestIPC), base::Bind(&SendEventListenersIPC));
rdevlin.cronin71d78789e2016-11-22 19:49:27134 } else {
135 bindings_system = base::MakeUnique<JsExtensionBindingsSystem>(
136 source_map, base::MakeUnique<ServiceWorkerRequestSender>(
137 this, service_worker_version_id));
138 }
rdevlin.cronin9f338892016-11-21 19:37:00139 ServiceWorkerData* new_data = new ServiceWorkerData(
140 service_worker_version_id, std::move(bindings_system));
lazyboyee4adef2016-05-24 00:55:16141 g_data_tls.Pointer()->Set(new_data);
142 }
143}
144
lazyboy4c82177a2016-10-18 00:04:09145void WorkerThreadDispatcher::RemoveWorkerData(
146 int64_t service_worker_version_id) {
lazyboyee4adef2016-05-24 00:55:16147 ServiceWorkerData* data = g_data_tls.Pointer()->Get();
148 if (data) {
lazyboy4c82177a2016-10-18 00:04:09149 DCHECK_EQ(service_worker_version_id, data->service_worker_version_id());
lazyboyee4adef2016-05-24 00:55:16150 delete data;
151 g_data_tls.Pointer()->Set(nullptr);
152 }
153}
154
155} // namespace extensions