Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(281)

Side by Side Diff: extensions/renderer/messaging_bindings.cc

Issue 2909673003: [Extensions Bindings] Request JS execution from messaging bindings (Closed)
Patch Set: lazyboy's Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/renderer/messaging_bindings.h" 5 #include "extensions/renderer/messaging_bindings.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <map> 9 #include <map>
10 #include <string> 10 #include <string>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
14 #include "base/callback.h" 14 #include "base/callback.h"
15 #include "base/callback_helpers.h" 15 #include "base/callback_helpers.h"
16 #include "base/lazy_instance.h" 16 #include "base/lazy_instance.h"
17 #include "base/memory/ptr_util.h" 17 #include "base/memory/ptr_util.h"
18 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
19 #include "base/metrics/histogram_macros.h" 19 #include "base/metrics/histogram_macros.h"
20 #include "base/values.h" 20 #include "base/values.h"
21 #include "content/public/child/v8_value_converter.h" 21 #include "content/public/child/v8_value_converter.h"
22 #include "content/public/common/child_process_host.h" 22 #include "content/public/common/child_process_host.h"
23 #include "content/public/renderer/render_frame.h" 23 #include "content/public/renderer/render_frame.h"
24 #include "content/public/renderer/render_thread.h" 24 #include "content/public/renderer/render_thread.h"
25 #include "extensions/common/api/messaging/message.h" 25 #include "extensions/common/api/messaging/message.h"
26 #include "extensions/common/api/messaging/port_id.h" 26 #include "extensions/common/api/messaging/port_id.h"
27 #include "extensions/common/extension_messages.h" 27 #include "extensions/common/extension_messages.h"
28 #include "extensions/common/manifest_handlers/externally_connectable.h" 28 #include "extensions/common/manifest_handlers/externally_connectable.h"
29 #include "extensions/renderer/dispatcher.h"
30 #include "extensions/renderer/extension_bindings_system.h"
29 #include "extensions/renderer/extension_frame_helper.h" 31 #include "extensions/renderer/extension_frame_helper.h"
30 #include "extensions/renderer/extension_port.h" 32 #include "extensions/renderer/extension_port.h"
33 #include "extensions/renderer/extensions_renderer_client.h"
31 #include "extensions/renderer/gc_callback.h" 34 #include "extensions/renderer/gc_callback.h"
32 #include "extensions/renderer/script_context.h" 35 #include "extensions/renderer/script_context.h"
33 #include "extensions/renderer/script_context_set.h" 36 #include "extensions/renderer/script_context_set.h"
34 #include "extensions/renderer/v8_helpers.h" 37 #include "extensions/renderer/v8_helpers.h"
35 #include "third_party/WebKit/public/web/WebDocument.h" 38 #include "third_party/WebKit/public/web/WebDocument.h"
36 #include "third_party/WebKit/public/web/WebLocalFrame.h" 39 #include "third_party/WebKit/public/web/WebLocalFrame.h"
37 #include "third_party/WebKit/public/web/WebScopedUserGesture.h" 40 #include "third_party/WebKit/public/web/WebScopedUserGesture.h"
38 #include "third_party/WebKit/public/web/WebScopedWindowFocusAllowedIndicator.h" 41 #include "third_party/WebKit/public/web/WebScopedWindowFocusAllowedIndicator.h"
39 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" 42 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
40 #include "v8/include/v8.h" 43 #include "v8/include/v8.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 ScriptContext* script_context) { 82 ScriptContext* script_context) {
80 MessagingBindings* bindings = g_messaging_map.Get()[script_context]; 83 MessagingBindings* bindings = g_messaging_map.Get()[script_context];
81 DCHECK(bindings); 84 DCHECK(bindings);
82 85
83 // If the channel was opened by this same context, ignore it. This should only 86 // If the channel was opened by this same context, ignore it. This should only
84 // happen when messages are sent to an entire process (rather than a single 87 // happen when messages are sent to an entire process (rather than a single
85 // frame) as an optimization; otherwise the browser process filters this out. 88 // frame) as an optimization; otherwise the browser process filters this out.
86 if (bindings->context_id() == target_port_id.context_id) 89 if (bindings->context_id() == target_port_id.context_id)
87 return; 90 return;
88 91
92 // First, determine the event we'll use to connect.
93 std::string target_extension_id = script_context->GetExtensionID();
94 bool is_external = info.source_id != target_extension_id;
95 std::string event_name;
96 if (channel_name == "chrome.extension.sendRequest") {
97 event_name =
98 is_external ? "extension.onRequestExternal" : "extension.onRequest";
99 } else if (channel_name == "chrome.runtime.sendMessage") {
100 event_name =
101 is_external ? "runtime.onMessageExternal" : "runtime.onMessage";
102 } else {
103 event_name =
104 is_external ? "runtime.onConnectExternal" : "runtime.onConnect";
105 }
106
107 ExtensionBindingsSystem* bindings_system =
108 ExtensionsRendererClient::Get()->GetDispatcher()->bindings_system();
109 // If there are no listeners for the given event, then we know the port won't
110 // be used in this context.
111 if (!bindings_system->HasEventListenerInContext(event_name, script_context)) {
112 return;
113 }
114 *port_created = true;
115
89 ExtensionPort* port = bindings->CreateNewPortWithId(target_port_id); 116 ExtensionPort* port = bindings->CreateNewPortWithId(target_port_id);
90 // Remove the port.
91 base::ScopedClosureRunner remove_port(
92 base::Bind(&MessagingBindings::RemovePortWithJsId, bindings->GetWeakPtr(),
93 port->js_id()));
94 117
95 v8::Isolate* isolate = script_context->isolate(); 118 v8::Isolate* isolate = script_context->isolate();
96 v8::HandleScope handle_scope(isolate); 119 v8::HandleScope handle_scope(isolate);
97 120
98
99 const std::string& source_url_spec = info.source_url.spec(); 121 const std::string& source_url_spec = info.source_url.spec();
100 std::string target_extension_id = script_context->GetExtensionID();
101 const Extension* extension = script_context->extension(); 122 const Extension* extension = script_context->extension();
102 123
103 v8::Local<v8::Value> tab = v8::Null(isolate); 124 v8::Local<v8::Value> tab = v8::Null(isolate);
104 v8::Local<v8::Value> tls_channel_id_value = v8::Undefined(isolate); 125 v8::Local<v8::Value> tls_channel_id_value = v8::Undefined(isolate);
105 v8::Local<v8::Value> guest_process_id = v8::Undefined(isolate); 126 v8::Local<v8::Value> guest_process_id = v8::Undefined(isolate);
106 v8::Local<v8::Value> guest_render_frame_routing_id = v8::Undefined(isolate); 127 v8::Local<v8::Value> guest_render_frame_routing_id = v8::Undefined(isolate);
107 128
108 if (extension) { 129 if (extension) {
109 if (!source->tab.empty() && !extension->is_platform_app()) { 130 if (!source->tab.empty() && !extension->is_platform_app()) {
110 std::unique_ptr<content::V8ValueConverter> converter( 131 std::unique_ptr<content::V8ValueConverter> converter(
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 // sourceExtensionId 178 // sourceExtensionId
158 v8_source_id, 179 v8_source_id,
159 // targetExtensionId 180 // targetExtensionId
160 v8_target_extension_id, 181 v8_target_extension_id,
161 // sourceUrl 182 // sourceUrl
162 v8_source_url_spec, 183 v8_source_url_spec,
163 // tlsChannelId 184 // tlsChannelId
164 tls_channel_id_value, 185 tls_channel_id_value,
165 }; 186 };
166 187
167 v8::Local<v8::Value> retval = 188 // Note: this can execute asynchronously if JS is suspended.
168 script_context->module_system()->CallModuleMethod( 189 script_context->module_system()->CallModuleMethodSafe(
169 "messaging", "dispatchOnConnect", arraysize(arguments), arguments); 190 "messaging", "dispatchOnConnect", arraysize(arguments), arguments);
170
171 if (!retval.IsEmpty() && !retval->IsUndefined()) {
172 CHECK(retval->IsBoolean());
173 bool used = retval.As<v8::Boolean>()->Value();
174 *port_created |= used;
175 if (used) // Port was used; don't remove it.
176 remove_port.ReplaceClosure(base::Closure());
177 } else {
178 LOG(ERROR) << "Empty return value from dispatchOnConnect.";
179 }
180 } 191 }
181 192
182 void DeliverMessageToScriptContext(const Message& message, 193 void DeliverMessageToScriptContext(const Message& message,
183 const PortId& target_port_id, 194 const PortId& target_port_id,
184 ScriptContext* script_context) { 195 ScriptContext* script_context) {
185 MessagingBindings* bindings = g_messaging_map.Get()[script_context]; 196 MessagingBindings* bindings = g_messaging_map.Get()[script_context];
186 DCHECK(bindings); 197 DCHECK(bindings);
187 ExtensionPort* port = bindings->GetPortWithId(target_port_id); 198 ExtensionPort* port = bindings->GetPortWithId(target_port_id);
188 if (!port) 199 if (!port)
189 return; 200 return;
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 return nullptr; 368 return nullptr;
358 } 369 }
359 370
360 ExtensionPort* MessagingBindings::CreateNewPortWithId(const PortId& id) { 371 ExtensionPort* MessagingBindings::CreateNewPortWithId(const PortId& id) {
361 int js_id = GetNextJsId(); 372 int js_id = GetNextJsId();
362 auto port = base::MakeUnique<ExtensionPort>(context(), id, js_id); 373 auto port = base::MakeUnique<ExtensionPort>(context(), id, js_id);
363 return ports_.insert(std::make_pair(js_id, std::move(port))) 374 return ports_.insert(std::make_pair(js_id, std::move(port)))
364 .first->second.get(); 375 .first->second.get();
365 } 376 }
366 377
367 void MessagingBindings::RemovePortWithJsId(int js_id) {
368 ports_.erase(js_id);
369 }
370
371 base::WeakPtr<MessagingBindings> MessagingBindings::GetWeakPtr() { 378 base::WeakPtr<MessagingBindings> MessagingBindings::GetWeakPtr() {
372 return weak_ptr_factory_.GetWeakPtr(); 379 return weak_ptr_factory_.GetWeakPtr();
373 } 380 }
374 381
375 void MessagingBindings::PostMessage( 382 void MessagingBindings::PostMessage(
376 const v8::FunctionCallbackInfo<v8::Value>& args) { 383 const v8::FunctionCallbackInfo<v8::Value>& args) {
377 // Arguments are (int32_t port_id, string message). 384 // Arguments are (int32_t port_id, string message).
378 CHECK(args.Length() == 2); 385 CHECK(args.Length() == 2);
379 CHECK(args[0]->IsInt32()); 386 CHECK(args[0]->IsInt32());
380 CHECK(args[1]->IsString()); 387 CHECK(args[1]->IsString());
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 ports_.erase(iter); 552 ports_.erase(iter);
546 port->Close(force_close); 553 port->Close(force_close);
547 } 554 }
548 } 555 }
549 556
550 int MessagingBindings::GetNextJsId() { 557 int MessagingBindings::GetNextJsId() {
551 return next_js_id_++; 558 return next_js_id_++;
552 } 559 }
553 560
554 } // namespace extensions 561 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/messaging_bindings.h ('k') | extensions/renderer/native_extension_bindings_system.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698