messaging_bindings.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/renderer/messaging_bindings.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 12bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/bind_helpers.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h" 14bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/message_loop/message_loop.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/values.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_thread.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_view.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/renderer/v8_value_converter.h" 19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/common/api/messaging/message.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/common/extension_messages.h" 21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/manifest_handlers/externally_connectable.h" 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/renderer/dispatcher.h" 23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/renderer/event_bindings.h" 240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "extensions/renderer/object_backed_native_handler.h" 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/renderer/scoped_persistent.h" 260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "extensions/renderer/script_context.h" 270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "extensions/renderer/script_context_set.h" 287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" 291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "third_party/WebKit/public/web/WebScopedUserGesture.h" 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebScopedWindowFocusAllowedIndicator.h" 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "v8/include/v8.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Message passing API example (in a content script): 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// var extension = 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// new chrome.Extension('00123456789abcdef0123456789abcdef0123456'); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// var port = runtime.connect(); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// port.postMessage('Can you hear me now?'); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// port.onmessage.addListener(function(msg, port) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// alert('response=' + msg); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// port.postMessage('I got your reponse'); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// }); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderThread; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using content::V8ValueConverter; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace extensions { 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ExtensionData { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PortData { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ref_count; // how many contexts have a handle to this port 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PortData() : ref_count(0) {} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, PortData> ports; // port ID -> data 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::LazyInstance<ExtensionData> g_extension_data = LAZY_INSTANCE_INITIALIZER; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool HasPortData(int port_id) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_extension_data.Get().ports.find(port_id) != 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) g_extension_data.Get().ports.end(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ExtensionData::PortData& GetPortData(int port_id) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_extension_data.Get().ports[port_id]; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ClearPortData(int port_id) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_extension_data.Get().ports.erase(port_id); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPortClosedError[] = "Attempting to use a disconnected port object"; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kReceivingEndDoesntExistError[] = 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Could not establish connection. Receiving end does not exist."; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass ExtensionImpl : public ObjectBackedNativeHandler { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ExtensionImpl(Dispatcher* dispatcher, ScriptContext* context) 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : ObjectBackedNativeHandler(context), dispatcher_(dispatcher) { 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RouteFunction( 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "CloseChannel", 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ExtensionImpl::CloseChannel, base::Unretained(this))); 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RouteFunction( 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "PortAddRef", 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ExtensionImpl::PortAddRef, base::Unretained(this))); 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RouteFunction( 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "PortRelease", 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ExtensionImpl::PortRelease, base::Unretained(this))); 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RouteFunction( 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "PostMessage", 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ExtensionImpl::PostMessage, base::Unretained(this))); 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(fsamuel, kalman): Move BindToGC out of messaging natives. 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RouteFunction("BindToGC", 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&ExtensionImpl::BindToGC, base::Unretained(this))); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~ExtensionImpl() {} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private: 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void ClearPortDataAndNotifyDispatcher(int port_id) { 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ClearPortData(port_id); 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch dispatcher_->ClearPortData(port_id); 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sends a message along the given channel. 1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void PostMessage(const v8::FunctionCallbackInfo<v8::Value>& args) { 1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch content::RenderView* renderview = context()->GetRenderView(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!renderview) 1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Arguments are (int32 port_id, string message). 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK(args.Length() == 2 && args[0]->IsInt32() && args[1]->IsString()); 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int port_id = args[0]->Int32Value(); 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!HasPortData(port_id)) { 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) args.GetIsolate()->ThrowException(v8::Exception::Error( 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::String::NewFromUtf8(args.GetIsolate(), kPortClosedError))); 1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) renderview->Send(new ExtensionHostMsg_PostMessage( 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) renderview->GetRoutingID(), port_id, 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Message(*v8::String::Utf8Value(args[1]), 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) blink::WebUserGestureIndicator::isProcessingUserGesture()))); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Forcefully disconnects a port. 1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void CloseChannel(const v8::FunctionCallbackInfo<v8::Value>& args) { 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Arguments are (int32 port_id, boolean notify_browser). 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK_EQ(2, args.Length()); 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK(args[0]->IsInt32()); 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK(args[1]->IsBoolean()); 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int port_id = args[0]->Int32Value(); 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!HasPortData(port_id)) 1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Send via the RenderThread because the RenderView might be closing. 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool notify_browser = args[1]->BooleanValue(); 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (notify_browser) { 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::RenderThread::Get()->Send( 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new ExtensionHostMsg_CloseChannel(port_id, std::string())); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ClearPortDataAndNotifyDispatcher(port_id); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A new port has been created for a context. This occurs both when script 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // opens a connection, and when a connection is opened to this script. 1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void PortAddRef(const v8::FunctionCallbackInfo<v8::Value>& args) { 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Arguments are (int32 port_id). 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK_EQ(1, args.Length()); 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK(args[0]->IsInt32()); 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int port_id = args[0]->Int32Value(); 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++GetPortData(port_id).ref_count; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The frame a port lived in has been destroyed. When there are no more 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frames with a reference to a given port, we will disconnect it and notify 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the other end of the channel. 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void PortRelease(const v8::FunctionCallbackInfo<v8::Value>& args) { 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Arguments are (int32 port_id). 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK_EQ(1, args.Length()); 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK(args[0]->IsInt32()); 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int port_id = args[0]->Int32Value(); 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (HasPortData(port_id) && --GetPortData(port_id).ref_count == 0) { 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Send via the RenderThread because the RenderView might be closing. 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::RenderThread::Get()->Send( 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new ExtensionHostMsg_CloseChannel(port_id, std::string())); 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ClearPortDataAndNotifyDispatcher(port_id); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 178bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Holds a |callback| to run sometime after |object| is GC'ed. |callback| will 179bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // not be executed re-entrantly to avoid running JS in an unexpected state. 180bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch class GCCallback { 181bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch public: 182bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch static void Bind(v8::Handle<v8::Object> object, 18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) v8::Handle<v8::Function> callback, 18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) v8::Isolate* isolate) { 18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GCCallback* cb = new GCCallback(object, callback, isolate); 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cb->object_.SetWeak(cb, NearDeathCallback); 187bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static void NearDeathCallback( 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const v8::WeakCallbackData<v8::Object, GCCallback>& data) { 192bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // v8 says we need to explicitly reset weak handles from their callbacks. 193bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // It's not implicit as one might expect. 194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) data.GetParameter()->object_.reset(); 195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::MessageLoop::current()->PostTask( 196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FROM_HERE, 197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&GCCallback::RunCallback, 198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Owned(data.GetParameter()))); 199bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GCCallback(v8::Handle<v8::Object> object, 20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) v8::Handle<v8::Function> callback, 20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) v8::Isolate* isolate) 20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : object_(object), callback_(callback), isolate_(isolate) {} 205bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 206bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch void RunCallback() { 20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) v8::HandleScope handle_scope(isolate_); 20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) v8::Handle<v8::Function> callback = callback_.NewHandle(isolate_); 20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) v8::Handle<v8::Context> context = callback->CreationContext(); 210bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (context.IsEmpty()) 211bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return; 212bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch v8::Context::Scope context_scope(context); 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebScopedMicrotaskSuppression suppression; 21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback->Call(context->Global(), 0, NULL); 215bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 216bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedPersistent<v8::Object> object_; 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedPersistent<v8::Function> callback_; 21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) v8::Isolate* isolate_; 220bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 221bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DISALLOW_COPY_AND_ASSIGN(GCCallback); 222bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch }; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 224bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // void BindToGC(object, callback) 225bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // 226bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Binds |callback| to be invoked *sometime after* |object| is garbage 227bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // collected. We don't call the method re-entrantly so as to avoid executing 228bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // JS in some bizarro undefined mid-GC state. 2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void BindToGC(const v8::FunctionCallbackInfo<v8::Value>& args) { 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(args.Length() == 2 && args[0]->IsObject() && args[1]->IsFunction()); 23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GCCallback::Bind(args[0].As<v8::Object>(), 23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) args[1].As<v8::Function>(), 23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) args.GetIsolate()); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Dispatcher handle. Not owned. 2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Dispatcher* dispatcher_; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void DispatchOnConnectToScriptContext( 241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int target_port_id, 242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& channel_name, 243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const base::DictionaryValue* source_tab, 244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ExtensionMsg_ExternalConnectionInfo& info, 245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& tls_channel_id, 246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool* port_created, 247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ScriptContext* script_context) { 248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Isolate* isolate = script_context->isolate(); 249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::HandleScope handle_scope(isolate); 250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); 252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& source_url_spec = info.source_url.spec(); 254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string target_extension_id = script_context->GetExtensionID(); 255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const Extension* extension = script_context->extension(); 256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Handle<v8::Value> tab = v8::Null(isolate); 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Handle<v8::Value> tls_channel_id_value = v8::Undefined(isolate); 259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (extension) { 261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!source_tab->empty() && !extension->is_platform_app()) 262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) tab = converter->ToV8Value(source_tab, script_context->v8_context()); 263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ExternallyConnectableInfo* externally_connectable = 265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ExternallyConnectableInfo::Get(extension); 266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (externally_connectable && 267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) externally_connectable->accepts_tls_channel_id) { 268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) tls_channel_id_value = v8::String::NewFromUtf8(isolate, 269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) tls_channel_id.c_str(), 270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::String::kNormalString, 271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) tls_channel_id.size()); 272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Handle<v8::Value> arguments[] = { 276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // portId 277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Integer::New(isolate, target_port_id), 278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // channelName 279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::String::NewFromUtf8(isolate, 280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) channel_name.c_str(), 281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::String::kNormalString, 282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) channel_name.size()), 283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // sourceTab 284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) tab, 285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // sourceExtensionId 286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::String::NewFromUtf8(isolate, 287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) info.source_id.c_str(), 288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::String::kNormalString, 289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) info.source_id.size()), 290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // targetExtensionId 291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::String::NewFromUtf8(isolate, 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) target_extension_id.c_str(), 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::String::kNormalString, 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) target_extension_id.size()), 295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // sourceUrl 296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::String::NewFromUtf8(isolate, 297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) source_url_spec.c_str(), 298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::String::kNormalString, 299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) source_url_spec.size()), 300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // tlsChannelId 301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) tls_channel_id_value, 302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) }; 303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Handle<v8::Value> retval = 305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) script_context->module_system()->CallModuleMethod( 306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "messaging", "dispatchOnConnect", arraysize(arguments), arguments); 307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!retval.IsEmpty()) { 309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK(retval->IsBoolean()); 310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *port_created |= retval->BooleanValue(); 311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LOG(ERROR) << "Empty return value from dispatchOnConnect."; 313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void DeliverMessageToScriptContext(const std::string& message_data, 317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int target_port_id, 318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ScriptContext* script_context) { 319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::HandleScope handle_scope(isolate); 321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Check to see whether the context has this port before bothering to create 323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // the message. 324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Handle<v8::Value> port_id_handle = 325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Integer::New(isolate, target_port_id); 326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Handle<v8::Value> has_port = 327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) script_context->module_system()->CallModuleMethod( 328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "messaging", "hasPort", 1, &port_id_handle); 329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK(!has_port.IsEmpty()); 331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!has_port->BooleanValue()) 332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<v8::Handle<v8::Value> > arguments; 335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) arguments.push_back(v8::String::NewFromUtf8(isolate, 336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) message_data.c_str(), 337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::String::kNormalString, 338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) message_data.size())); 339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) arguments.push_back(port_id_handle); 340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) script_context->module_system()->CallModuleMethod( 341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "messaging", "dispatchOnMessage", &arguments); 342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void DispatchOnDisconnectToScriptContext(int port_id, 345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& error_message, 346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ScriptContext* script_context) { 347f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Isolate* isolate = script_context->isolate(); 348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::HandleScope handle_scope(isolate); 349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<v8::Handle<v8::Value> > arguments; 351f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) arguments.push_back(v8::Integer::New(isolate, port_id)); 352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!error_message.empty()) { 353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) arguments.push_back( 354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::String::NewFromUtf8(isolate, error_message.c_str())); 355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 356f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) arguments.push_back(v8::Null(isolate)); 357f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) script_context->module_system()->CallModuleMethod( 360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "messaging", "dispatchOnDisconnect", &arguments); 361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3650529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochObjectBackedNativeHandler* MessagingBindings::Get(Dispatcher* dispatcher, 3660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ScriptContext* context) { 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new ExtensionImpl(dispatcher, context); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 371fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid MessagingBindings::DispatchOnConnect( 372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ScriptContextSet& context_set, 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int target_port_id, 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& channel_name, 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue& source_tab, 376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ExtensionMsg_ExternalConnectionInfo& info, 3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& tls_channel_id, 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderView* restrict_to_render_view) { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool port_created = false; 380f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) context_set.ForEach(info.target_id, 381f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) restrict_to_render_view, 382f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&DispatchOnConnectToScriptContext, 383f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) target_port_id, 384f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) channel_name, 385f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &source_tab, 386f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) info, 387f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) tls_channel_id, 388f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &port_created)); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we didn't create a port, notify the other end of the channel (treat it 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as a disconnect). 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!port_created) { 393010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::RenderThread::Get()->Send(new ExtensionHostMsg_CloseChannel( 394010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) target_port_id, kReceivingEndDoesntExistError)); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 399fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid MessagingBindings::DeliverMessage( 400f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ScriptContextSet& context_set, 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int target_port_id, 4021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const Message& message, 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderView* restrict_to_render_view) { 404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<blink::WebScopedUserGesture> web_user_gesture; 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<blink::WebScopedWindowFocusAllowedIndicator> allow_window_focus; 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (message.user_gesture) { 407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_user_gesture.reset(new blink::WebScopedUserGesture); 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) allow_window_focus.reset(new blink::WebScopedWindowFocusAllowedIndicator); 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 411f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) context_set.ForEach( 412f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) restrict_to_render_view, 413f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&DeliverMessageToScriptContext, message.data, target_port_id)); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 417fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid MessagingBindings::DispatchOnDisconnect( 418f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ScriptContextSet& context_set, 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port_id, 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& error_message, 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderView* restrict_to_render_view) { 422f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) context_set.ForEach( 423f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) restrict_to_render_view, 424f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&DispatchOnDisconnectToScriptContext, port_id, error_message)); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 428