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

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, 11 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 explicit 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)));
87 RouteFunction("PortAddRef", 89 RouteFunction("PortAddRef",
88 base::Bind(&ExtensionImpl::PortAddRef, base::Unretained(this))); 90 base::Bind(&ExtensionImpl::PortAddRef, base::Unretained(this)));
89 RouteFunction("PortRelease", 91 RouteFunction("PortRelease",
90 base::Bind(&ExtensionImpl::PortRelease, base::Unretained(this))); 92 base::Bind(&ExtensionImpl::PortRelease, base::Unretained(this)));
91 RouteFunction("PostMessage", 93 RouteFunction("PostMessage",
92 base::Bind(&ExtensionImpl::PostMessage, base::Unretained(this))); 94 base::Bind(&ExtensionImpl::PostMessage, base::Unretained(this)));
93 // TODO(fsamuel, kalman): Move BindToGC out of messaging natives. 95 // TODO(fsamuel, kalman): Move BindToGC out of messaging natives.
94 RouteFunction("BindToGC", 96 RouteFunction("BindToGC",
(...skipping 15 matching lines...) Expand all
110 112
111 int port_id = args[0]->Int32Value(); 113 int port_id = args[0]->Int32Value();
112 if (!HasPortData(port_id)) { 114 if (!HasPortData(port_id)) {
113 args.GetIsolate()->ThrowException(v8::Exception::Error( 115 args.GetIsolate()->ThrowException(v8::Exception::Error(
114 v8::String::NewFromUtf8(args.GetIsolate(), kPortClosedError))); 116 v8::String::NewFromUtf8(args.GetIsolate(), kPortClosedError)));
115 return; 117 return;
116 } 118 }
117 119
118 renderview->Send(new ExtensionHostMsg_PostMessage( 120 renderview->Send(new ExtensionHostMsg_PostMessage(
119 renderview->GetRoutingID(), port_id, 121 renderview->GetRoutingID(), port_id,
120 extensions::Message( 122 Message(*v8::String::Utf8Value(args[1]),
121 *v8::String::Utf8Value(args[1]), 123 blink::WebUserGestureIndicator::isProcessingUserGesture())));
122 blink::WebUserGestureIndicator::isProcessingUserGesture())));
123 } 124 }
124 125
125 // Forcefully disconnects a port. 126 // Forcefully disconnects a port.
126 void CloseChannel(const v8::FunctionCallbackInfo<v8::Value>& args) { 127 void CloseChannel(const v8::FunctionCallbackInfo<v8::Value>& args) {
127 // Arguments are (int32 port_id, boolean notify_browser). 128 // Arguments are (int32 port_id, boolean notify_browser).
128 CHECK_EQ(2, args.Length()); 129 CHECK_EQ(2, args.Length());
129 CHECK(args[0]->IsInt32()); 130 CHECK(args[0]->IsInt32());
130 CHECK(args[1]->IsBoolean()); 131 CHECK(args[1]->IsBoolean());
131 132
132 int port_id = args[0]->Int32Value(); 133 int port_id = args[0]->Int32Value();
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 v8::HandleScope handle_scope(isolate_); 204 v8::HandleScope handle_scope(isolate_);
204 v8::Handle<v8::Function> callback = callback_.NewHandle(isolate_); 205 v8::Handle<v8::Function> callback = callback_.NewHandle(isolate_);
205 v8::Handle<v8::Context> context = callback->CreationContext(); 206 v8::Handle<v8::Context> context = callback->CreationContext();
206 if (context.IsEmpty()) 207 if (context.IsEmpty())
207 return; 208 return;
208 v8::Context::Scope context_scope(context); 209 v8::Context::Scope context_scope(context);
209 blink::WebScopedMicrotaskSuppression suppression; 210 blink::WebScopedMicrotaskSuppression suppression;
210 callback->Call(context->Global(), 0, NULL); 211 callback->Call(context->Global(), 0, NULL);
211 } 212 }
212 213
213 extensions::ScopedPersistent<v8::Object> object_; 214 ScopedPersistent<v8::Object> object_;
214 extensions::ScopedPersistent<v8::Function> callback_; 215 ScopedPersistent<v8::Function> callback_;
215 v8::Isolate* isolate_; 216 v8::Isolate* isolate_;
216 217
217 DISALLOW_COPY_AND_ASSIGN(GCCallback); 218 DISALLOW_COPY_AND_ASSIGN(GCCallback);
218 }; 219 };
219 220
220 // void BindToGC(object, callback) 221 // void BindToGC(object, callback)
221 // 222 //
222 // Binds |callback| to be invoked *sometime after* |object| is garbage 223 // 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 224 // collected. We don't call the method re-entrantly so as to avoid executing
224 // JS in some bizarro undefined mid-GC state. 225 // JS in some bizarro undefined mid-GC state.
225 void BindToGC(const v8::FunctionCallbackInfo<v8::Value>& args) { 226 void BindToGC(const v8::FunctionCallbackInfo<v8::Value>& args) {
226 CHECK(args.Length() == 2 && args[0]->IsObject() && args[1]->IsFunction()); 227 CHECK(args.Length() == 2 && args[0]->IsObject() && args[1]->IsFunction());
227 GCCallback::Bind(args[0].As<v8::Object>(), 228 GCCallback::Bind(args[0].As<v8::Object>(),
228 args[1].As<v8::Function>(), 229 args[1].As<v8::Function>(),
229 args.GetIsolate()); 230 args.GetIsolate());
230 } 231 }
231 }; 232 };
232 233
233 } // namespace 234 } // namespace
234 235
235 namespace extensions {
236
237 ChromeV8Extension* MessagingBindings::Get( 236 ChromeV8Extension* MessagingBindings::Get(
238 Dispatcher* dispatcher, 237 Dispatcher* dispatcher,
239 ChromeV8Context* context) { 238 ChromeV8Context* context) {
240 return new ExtensionImpl(dispatcher, context); 239 return new ExtensionImpl(dispatcher, context);
241 } 240 }
242 241
243 // static 242 // static
244 void MessagingBindings::DispatchOnConnect( 243 void MessagingBindings::DispatchOnConnect(
245 const ChromeV8ContextSet::ContextSet& contexts, 244 const ChromeV8ContextSet::ContextSet& contexts,
246 int target_port_id, 245 int target_port_id,
(...skipping 18 matching lines...) Expand all
265 if (restrict_to_render_view && 264 if (restrict_to_render_view &&
266 restrict_to_render_view != (*it)->GetRenderView()) { 265 restrict_to_render_view != (*it)->GetRenderView()) {
267 continue; 266 continue;
268 } 267 }
269 268
270 // TODO(kalman): remove when ContextSet::ForEach is available. 269 // TODO(kalman): remove when ContextSet::ForEach is available.
271 if ((*it)->v8_context().IsEmpty()) 270 if ((*it)->v8_context().IsEmpty())
272 continue; 271 continue;
273 272
274 v8::Handle<v8::Value> tab = v8::Null(isolate); 273 v8::Handle<v8::Value> tab = v8::Null(isolate);
275 if (!source_tab.empty()) 274 if (!source_tab.empty() && (*it)->extension()->is_platform_app())
not at google - send to devlin 2014/01/24 21:37:27 shouldn't this be !is_platform_app() ?
Lei Zhang 2014/01/25 01:47:09 Whoops.
276 tab = converter->ToV8Value(&source_tab, (*it)->v8_context()); 275 tab = converter->ToV8Value(&source_tab, (*it)->v8_context());
277 276
278 v8::Handle<v8::Value> tls_channel_id_value = v8::Undefined(isolate); 277 v8::Handle<v8::Value> tls_channel_id_value = v8::Undefined(isolate);
279 if ((*it)->extension()) { 278 if ((*it)->extension()) {
280 ExternallyConnectableInfo* externally_connectable = 279 ExternallyConnectableInfo* externally_connectable =
281 ExternallyConnectableInfo::Get((*it)->extension()); 280 ExternallyConnectableInfo::Get((*it)->extension());
282 if (externally_connectable && 281 if (externally_connectable &&
283 externally_connectable->accepts_tls_channel_id) { 282 externally_connectable->accepts_tls_channel_id) {
284 tls_channel_id_value = 283 tls_channel_id_value =
285 v8::String::NewFromUtf8(isolate, 284 v8::String::NewFromUtf8(isolate,
286 tls_channel_id.c_str(), 285 tls_channel_id.c_str(),
287 v8::String::kNormalString, 286 v8::String::kNormalString,
288 tls_channel_id.size()); 287 tls_channel_id.size());
289 } 288 }
290 } 289 }
291 290
292 v8::Handle<v8::Value> arguments[] = { 291 v8::Handle<v8::Value> arguments[] = {
292 // portId
293 v8::Integer::New(isolate, target_port_id), 293 v8::Integer::New(isolate, target_port_id),
294 // channelName
294 v8::String::NewFromUtf8(isolate, 295 v8::String::NewFromUtf8(isolate,
295 channel_name.c_str(), 296 channel_name.c_str(),
296 v8::String::kNormalString, 297 v8::String::kNormalString,
297 channel_name.size()), 298 channel_name.size()),
298 tab, v8::String::NewFromUtf8(isolate, 299 // sourceTab
299 source_extension_id.c_str(), 300 tab,
300 v8::String::kNormalString, 301 // sourceExtensionId
301 source_extension_id.size()), 302 v8::String::NewFromUtf8(isolate,
303 source_extension_id.c_str(),
304 v8::String::kNormalString,
305 source_extension_id.size()),
306 // targetExtensionId
302 v8::String::NewFromUtf8(isolate, 307 v8::String::NewFromUtf8(isolate,
303 target_extension_id.c_str(), 308 target_extension_id.c_str(),
304 v8::String::kNormalString, 309 v8::String::kNormalString,
305 target_extension_id.size()), 310 target_extension_id.size()),
311 // sourceUrl
306 v8::String::NewFromUtf8(isolate, 312 v8::String::NewFromUtf8(isolate,
307 source_url_spec.c_str(), 313 source_url_spec.c_str(),
308 v8::String::kNormalString, 314 v8::String::kNormalString,
309 source_url_spec.size()), 315 source_url_spec.size()),
316 // tlsChannelId
310 tls_channel_id_value, 317 tls_channel_id_value,
311 }; 318 };
312 319
320 int tab_id = -1;
321 source_tab.GetInteger("id", &tab_id);
322 MediaGalleriesCustomBindings::PushSenderTabId(*it, tab_id);
not at google - send to devlin 2014/01/24 21:37:27 Having this in MediaGalleriesCustomBindings is odd
Lei Zhang 2014/01/25 01:47:09 Sure, moved here.
not at google - send to devlin 2014/01/27 17:51:46 No, it's an async API, but running the callback it
Lei Zhang 2014/01/27 23:19:13 Ah I see what you mean. I'll try to narrow the sco
not at google - send to devlin 2014/01/27 23:27:40 So what I'd probably do is have that scoped thing
313 v8::Handle<v8::Value> retval = (*it)->module_system()->CallModuleMethod( 323 v8::Handle<v8::Value> retval = (*it)->module_system()->CallModuleMethod(
314 "messaging", 324 "messaging",
315 "dispatchOnConnect", 325 "dispatchOnConnect",
316 arraysize(arguments), arguments); 326 arraysize(arguments), arguments);
317 327
318 if (retval.IsEmpty()) { 328 if (retval.IsEmpty()) {
319 LOG(ERROR) << "Empty return value from dispatchOnConnect."; 329 LOG(ERROR) << "Empty return value from dispatchOnConnect.";
320 continue; 330 continue;
321 } 331 }
322 332
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 continue; 418 continue;
409 419
410 std::vector<v8::Handle<v8::Value> > arguments; 420 std::vector<v8::Handle<v8::Value> > arguments;
411 arguments.push_back(v8::Integer::New(isolate, port_id)); 421 arguments.push_back(v8::Integer::New(isolate, port_id));
412 if (!error_message.empty()) { 422 if (!error_message.empty()) {
413 arguments.push_back( 423 arguments.push_back(
414 v8::String::NewFromUtf8(isolate, error_message.c_str())); 424 v8::String::NewFromUtf8(isolate, error_message.c_str()));
415 } else { 425 } else {
416 arguments.push_back(v8::Null(isolate)); 426 arguments.push_back(v8::Null(isolate));
417 } 427 }
428 MediaGalleriesCustomBindings::PopSenderTabId(*it);
418 (*it)->module_system()->CallModuleMethod("messaging", 429 (*it)->module_system()->CallModuleMethod("messaging",
419 "dispatchOnDisconnect", 430 "dispatchOnDisconnect",
420 &arguments); 431 &arguments);
421 } 432 }
422 } 433 }
423 434
424 } // namespace extensions 435 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698