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

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

Issue 145463002: Extensions: Send the tab id to platform apps. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/renderer/extensions/messaging_bindings.h" 5 #include "chrome/renderer/extensions/messaging_bindings.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
15 #include "base/values.h" 15 #include "base/values.h"
16 #include "chrome/common/extensions/api/messaging/message.h" 16 #include "chrome/common/extensions/api/messaging/message.h"
17 #include "chrome/common/extensions/extension_messages.h" 17 #include "chrome/common/extensions/extension_messages.h"
18 #include "chrome/common/extensions/manifest_handlers/externally_connectable.h" 18 #include "chrome/common/extensions/manifest_handlers/externally_connectable.h"
19 #include "chrome/common/extensions/message_bundle.h" 19 #include "chrome/common/extensions/message_bundle.h"
20 #include "chrome/common/url_constants.h" 20 #include "chrome/common/url_constants.h"
21 #include "chrome/renderer/extensions/chrome_v8_context.h" 21 #include "chrome/renderer/extensions/chrome_v8_context.h"
22 #include "chrome/renderer/extensions/chrome_v8_context_set.h" 22 #include "chrome/renderer/extensions/chrome_v8_context_set.h"
23 #include "chrome/renderer/extensions/chrome_v8_extension.h" 23 #include "chrome/renderer/extensions/chrome_v8_extension.h"
24 #include "chrome/renderer/extensions/dispatcher.h" 24 #include "chrome/renderer/extensions/dispatcher.h"
25 #include "chrome/renderer/extensions/event_bindings.h" 25 #include "chrome/renderer/extensions/event_bindings.h"
26 #include "chrome/renderer/extensions/media_galleries_custom_bindings.h"
26 #include "chrome/renderer/extensions/scoped_persistent.h" 27 #include "chrome/renderer/extensions/scoped_persistent.h"
27 #include "content/public/renderer/render_thread.h" 28 #include "content/public/renderer/render_thread.h"
28 #include "content/public/renderer/render_view.h" 29 #include "content/public/renderer/render_view.h"
29 #include "content/public/renderer/v8_value_converter.h" 30 #include "content/public/renderer/v8_value_converter.h"
30 #include "grit/renderer_resources.h" 31 #include "grit/renderer_resources.h"
31 #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" 32 #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
32 #include "third_party/WebKit/public/web/WebScopedUserGesture.h" 33 #include "third_party/WebKit/public/web/WebScopedUserGesture.h"
33 #include "third_party/WebKit/public/web/WebScopedWindowFocusAllowedIndicator.h" 34 #include "third_party/WebKit/public/web/WebScopedWindowFocusAllowedIndicator.h"
34 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" 35 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
35 #include "v8/include/v8.h" 36 #include "v8/include/v8.h"
36 37
37 // Message passing API example (in a content script): 38 // Message passing API example (in a content script):
38 // var extension = 39 // var extension =
39 // new chrome.Extension('00123456789abcdef0123456789abcdef0123456'); 40 // new chrome.Extension('00123456789abcdef0123456789abcdef0123456');
40 // var port = runtime.connect(); 41 // var port = runtime.connect();
41 // port.postMessage('Can you hear me now?'); 42 // port.postMessage('Can you hear me now?');
42 // port.onmessage.addListener(function(msg, port) { 43 // port.onmessage.addListener(function(msg, port) {
43 // alert('response=' + msg); 44 // alert('response=' + msg);
44 // port.postMessage('I got your reponse'); 45 // port.postMessage('I got your reponse');
45 // }); 46 // });
46 47
47 using content::RenderThread; 48 using content::RenderThread;
48 using content::V8ValueConverter; 49 using content::V8ValueConverter;
49 50
51 namespace extensions {
52
50 namespace { 53 namespace {
51 54
52 struct ExtensionData { 55 struct ExtensionData {
53 struct PortData { 56 struct PortData {
54 int ref_count; // how many contexts have a handle to this port 57 int ref_count; // how many contexts have a handle to this port
55 PortData() : ref_count(0) {} 58 PortData() : ref_count(0) {}
56 }; 59 };
57 std::map<int, PortData> ports; // port ID -> data 60 std::map<int, PortData> ports; // port ID -> data
58 }; 61 };
59 62
(...skipping 10 matching lines...) Expand all
70 } 73 }
71 74
72 static void ClearPortData(int port_id) { 75 static void ClearPortData(int port_id) {
73 g_extension_data.Get().ports.erase(port_id); 76 g_extension_data.Get().ports.erase(port_id);
74 } 77 }
75 78
76 const char kPortClosedError[] = "Attempting to use a disconnected port object"; 79 const char kPortClosedError[] = "Attempting to use a disconnected port object";
77 const char kReceivingEndDoesntExistError[] = 80 const char kReceivingEndDoesntExistError[] =
78 "Could not establish connection. Receiving end does not exist."; 81 "Could not establish connection. Receiving end does not exist.";
79 82
80 class ExtensionImpl : public extensions::ChromeV8Extension { 83 class ExtensionImpl : public ChromeV8Extension {
81 public: 84 public:
82 explicit ExtensionImpl(extensions::Dispatcher* dispatcher, 85 ExtensionImpl(Dispatcher* dispatcher, ChromeV8Context* context)
83 extensions::ChromeV8Context* context) 86 : ChromeV8Extension(dispatcher, context) {
84 : extensions::ChromeV8Extension(dispatcher, context) {
85 RouteFunction("CloseChannel", 87 RouteFunction("CloseChannel",
86 base::Bind(&ExtensionImpl::CloseChannel, base::Unretained(this))); 88 base::Bind(&ExtensionImpl::CloseChannel, base::Unretained(this)));
89 RouteFunction("GetSenderTabId",
90 base::Bind(&ExtensionImpl::GetSenderTabId, base::Unretained(this)));
87 RouteFunction("PortAddRef", 91 RouteFunction("PortAddRef",
88 base::Bind(&ExtensionImpl::PortAddRef, base::Unretained(this))); 92 base::Bind(&ExtensionImpl::PortAddRef, base::Unretained(this)));
89 RouteFunction("PortRelease", 93 RouteFunction("PortRelease",
90 base::Bind(&ExtensionImpl::PortRelease, base::Unretained(this))); 94 base::Bind(&ExtensionImpl::PortRelease, base::Unretained(this)));
91 RouteFunction("PostMessage", 95 RouteFunction("PostMessage",
92 base::Bind(&ExtensionImpl::PostMessage, base::Unretained(this))); 96 base::Bind(&ExtensionImpl::PostMessage, base::Unretained(this)));
93 // TODO(fsamuel, kalman): Move BindToGC out of messaging natives. 97 // TODO(fsamuel, kalman): Move BindToGC out of messaging natives.
94 RouteFunction("BindToGC", 98 RouteFunction("BindToGC",
95 base::Bind(&ExtensionImpl::BindToGC, base::Unretained(this))); 99 base::Bind(&ExtensionImpl::BindToGC, base::Unretained(this)));
96 } 100 }
(...skipping 13 matching lines...) Expand all
110 114
111 int port_id = args[0]->Int32Value(); 115 int port_id = args[0]->Int32Value();
112 if (!HasPortData(port_id)) { 116 if (!HasPortData(port_id)) {
113 args.GetIsolate()->ThrowException(v8::Exception::Error( 117 args.GetIsolate()->ThrowException(v8::Exception::Error(
114 v8::String::NewFromUtf8(args.GetIsolate(), kPortClosedError))); 118 v8::String::NewFromUtf8(args.GetIsolate(), kPortClosedError)));
115 return; 119 return;
116 } 120 }
117 121
118 renderview->Send(new ExtensionHostMsg_PostMessage( 122 renderview->Send(new ExtensionHostMsg_PostMessage(
119 renderview->GetRoutingID(), port_id, 123 renderview->GetRoutingID(), port_id,
120 extensions::Message( 124 Message(*v8::String::Utf8Value(args[1]),
121 *v8::String::Utf8Value(args[1]), 125 blink::WebUserGestureIndicator::isProcessingUserGesture())));
122 blink::WebUserGestureIndicator::isProcessingUserGesture())));
123 } 126 }
124 127
125 // Forcefully disconnects a port. 128 // Forcefully disconnects a port.
126 void CloseChannel(const v8::FunctionCallbackInfo<v8::Value>& args) { 129 void CloseChannel(const v8::FunctionCallbackInfo<v8::Value>& args) {
127 // Arguments are (int32 port_id, boolean notify_browser). 130 // Arguments are (int32 port_id, boolean notify_browser).
128 CHECK_EQ(2, args.Length()); 131 CHECK_EQ(2, args.Length());
129 CHECK(args[0]->IsInt32()); 132 CHECK(args[0]->IsInt32());
130 CHECK(args[1]->IsBoolean()); 133 CHECK(args[1]->IsBoolean());
131 134
132 int port_id = args[0]->Int32Value(); 135 int port_id = args[0]->Int32Value();
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 v8::HandleScope handle_scope(isolate_); 206 v8::HandleScope handle_scope(isolate_);
204 v8::Handle<v8::Function> callback = callback_.NewHandle(isolate_); 207 v8::Handle<v8::Function> callback = callback_.NewHandle(isolate_);
205 v8::Handle<v8::Context> context = callback->CreationContext(); 208 v8::Handle<v8::Context> context = callback->CreationContext();
206 if (context.IsEmpty()) 209 if (context.IsEmpty())
207 return; 210 return;
208 v8::Context::Scope context_scope(context); 211 v8::Context::Scope context_scope(context);
209 blink::WebScopedMicrotaskSuppression suppression; 212 blink::WebScopedMicrotaskSuppression suppression;
210 callback->Call(context->Global(), 0, NULL); 213 callback->Call(context->Global(), 0, NULL);
211 } 214 }
212 215
213 extensions::ScopedPersistent<v8::Object> object_; 216 ScopedPersistent<v8::Object> object_;
214 extensions::ScopedPersistent<v8::Function> callback_; 217 ScopedPersistent<v8::Function> callback_;
215 v8::Isolate* isolate_; 218 v8::Isolate* isolate_;
216 219
217 DISALLOW_COPY_AND_ASSIGN(GCCallback); 220 DISALLOW_COPY_AND_ASSIGN(GCCallback);
218 }; 221 };
219 222
220 // void BindToGC(object, callback) 223 // void BindToGC(object, callback)
221 // 224 //
222 // Binds |callback| to be invoked *sometime after* |object| is garbage 225 // Binds |callback| to be invoked *sometime after* |object| is garbage
223 // collected. We don't call the method re-entrantly so as to avoid executing 226 // collected. We don't call the method re-entrantly so as to avoid executing
224 // JS in some bizarro undefined mid-GC state. 227 // JS in some bizarro undefined mid-GC state.
225 void BindToGC(const v8::FunctionCallbackInfo<v8::Value>& args) { 228 void BindToGC(const v8::FunctionCallbackInfo<v8::Value>& args) {
226 CHECK(args.Length() == 2 && args[0]->IsObject() && args[1]->IsFunction()); 229 CHECK(args.Length() == 2 && args[0]->IsObject() && args[1]->IsFunction());
227 GCCallback::Bind(args[0].As<v8::Object>(), 230 GCCallback::Bind(args[0].As<v8::Object>(),
228 args[1].As<v8::Function>(), 231 args[1].As<v8::Function>(),
229 args.GetIsolate()); 232 args.GetIsolate());
230 } 233 }
234
235 void GetSenderTabId(const v8::FunctionCallbackInfo<v8::Value>& args) {
236 CHECK_EQ(0, args.Length());
237 args.GetReturnValue().Set(dispatcher()->request_sender()->sender_tab_id());
238 }
231 }; 239 };
232 240
233 } // namespace 241 } // namespace
234 242
235 namespace extensions {
236
237 ChromeV8Extension* MessagingBindings::Get( 243 ChromeV8Extension* MessagingBindings::Get(
238 Dispatcher* dispatcher, 244 Dispatcher* dispatcher,
239 ChromeV8Context* context) { 245 ChromeV8Context* context) {
240 return new ExtensionImpl(dispatcher, context); 246 return new ExtensionImpl(dispatcher, context);
241 } 247 }
242 248
243 // static 249 // static
244 void MessagingBindings::DispatchOnConnect( 250 void MessagingBindings::DispatchOnConnect(
245 const ChromeV8ContextSet::ContextSet& contexts, 251 const ChromeV8ContextSet::ContextSet& contexts,
246 int target_port_id, 252 int target_port_id,
(...skipping 18 matching lines...) Expand all
265 if (restrict_to_render_view && 271 if (restrict_to_render_view &&
266 restrict_to_render_view != (*it)->GetRenderView()) { 272 restrict_to_render_view != (*it)->GetRenderView()) {
267 continue; 273 continue;
268 } 274 }
269 275
270 // TODO(kalman): remove when ContextSet::ForEach is available. 276 // TODO(kalman): remove when ContextSet::ForEach is available.
271 if ((*it)->v8_context().IsEmpty()) 277 if ((*it)->v8_context().IsEmpty())
272 continue; 278 continue;
273 279
274 v8::Handle<v8::Value> tab = v8::Null(isolate); 280 v8::Handle<v8::Value> tab = v8::Null(isolate);
275 if (!source_tab.empty()) 281 if (!source_tab.empty() && !(*it)->extension()->is_platform_app())
276 tab = converter->ToV8Value(&source_tab, (*it)->v8_context()); 282 tab = converter->ToV8Value(&source_tab, (*it)->v8_context());
277 283
278 v8::Handle<v8::Value> tls_channel_id_value = v8::Undefined(isolate); 284 v8::Handle<v8::Value> tls_channel_id_value = v8::Undefined(isolate);
279 if ((*it)->extension()) { 285 if ((*it)->extension()) {
280 ExternallyConnectableInfo* externally_connectable = 286 ExternallyConnectableInfo* externally_connectable =
281 ExternallyConnectableInfo::Get((*it)->extension()); 287 ExternallyConnectableInfo::Get((*it)->extension());
282 if (externally_connectable && 288 if (externally_connectable &&
283 externally_connectable->accepts_tls_channel_id) { 289 externally_connectable->accepts_tls_channel_id) {
284 tls_channel_id_value = 290 tls_channel_id_value =
285 v8::String::NewFromUtf8(isolate, 291 v8::String::NewFromUtf8(isolate,
286 tls_channel_id.c_str(), 292 tls_channel_id.c_str(),
287 v8::String::kNormalString, 293 v8::String::kNormalString,
288 tls_channel_id.size()); 294 tls_channel_id.size());
289 } 295 }
290 } 296 }
291 297
292 v8::Handle<v8::Value> arguments[] = { 298 v8::Handle<v8::Value> arguments[] = {
299 // portId
293 v8::Integer::New(isolate, target_port_id), 300 v8::Integer::New(isolate, target_port_id),
301 // channelName
294 v8::String::NewFromUtf8(isolate, 302 v8::String::NewFromUtf8(isolate,
295 channel_name.c_str(), 303 channel_name.c_str(),
296 v8::String::kNormalString, 304 v8::String::kNormalString,
297 channel_name.size()), 305 channel_name.size()),
298 tab, v8::String::NewFromUtf8(isolate, 306 // sourceTab
299 source_extension_id.c_str(), 307 tab,
300 v8::String::kNormalString, 308 // sourceExtensionId
301 source_extension_id.size()), 309 v8::String::NewFromUtf8(isolate,
310 source_extension_id.c_str(),
311 v8::String::kNormalString,
312 source_extension_id.size()),
313 // targetExtensionId
302 v8::String::NewFromUtf8(isolate, 314 v8::String::NewFromUtf8(isolate,
303 target_extension_id.c_str(), 315 target_extension_id.c_str(),
304 v8::String::kNormalString, 316 v8::String::kNormalString,
305 target_extension_id.size()), 317 target_extension_id.size()),
318 // sourceUrl
306 v8::String::NewFromUtf8(isolate, 319 v8::String::NewFromUtf8(isolate,
307 source_url_spec.c_str(), 320 source_url_spec.c_str(),
308 v8::String::kNormalString, 321 v8::String::kNormalString,
309 source_url_spec.size()), 322 source_url_spec.size()),
323 // tlsChannelId
310 tls_channel_id_value, 324 tls_channel_id_value,
311 }; 325 };
312 326
313 v8::Handle<v8::Value> retval = (*it)->module_system()->CallModuleMethod( 327 v8::Handle<v8::Value> retval = (*it)->module_system()->CallModuleMethod(
314 "messaging", 328 "messaging",
315 "dispatchOnConnect", 329 "dispatchOnConnect",
316 arraysize(arguments), arguments); 330 arraysize(arguments), arguments);
317 331
318 if (retval.IsEmpty()) { 332 if (retval.IsEmpty()) {
319 LOG(ERROR) << "Empty return value from dispatchOnConnect."; 333 LOG(ERROR) << "Empty return value from dispatchOnConnect.";
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 } else { 429 } else {
416 arguments.push_back(v8::Null(isolate)); 430 arguments.push_back(v8::Null(isolate));
417 } 431 }
418 (*it)->module_system()->CallModuleMethod("messaging", 432 (*it)->module_system()->CallModuleMethod("messaging",
419 "dispatchOnDisconnect", 433 "dispatchOnDisconnect",
420 &arguments); 434 &arguments);
421 } 435 }
422 } 436 }
423 437
424 } // namespace extensions 438 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698