Chromium Code Reviews| Index: extensions/renderer/dispatcher.cc |
| diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc |
| index fe1cff9c125c395142fc73e8489cfdee47110f17..faff1f62096bd26f2ce46b89760830a30b95bda9 100644 |
| --- a/extensions/renderer/dispatcher.cc |
| +++ b/extensions/renderer/dispatcher.cc |
| @@ -100,6 +100,7 @@ |
| #include "extensions/renderer/wake_event_page.h" |
| #include "extensions/renderer/worker_script_context_set.h" |
| #include "extensions/renderer/worker_thread_dispatcher.h" |
| +#include "gin/converter.h" |
| #include "grit/extensions_renderer_resources.h" |
| #include "mojo/public/js/constants.h" |
| #include "third_party/WebKit/public/platform/WebString.h" |
| @@ -204,6 +205,34 @@ class ChromeNativeHandler : public ObjectBackedNativeHandler { |
| base::LazyInstance<WorkerScriptContextSet> g_worker_script_context_set = |
| LAZY_INSTANCE_INITIALIZER; |
| +// Dispatches the event with the given name, arguments, and filtering info in |
| +// the given |context|. |
| +void DispatchEventInContext(const std::string& event_name, |
| + const base::ListValue* event_args, |
| + const base::DictionaryValue* filtering_info, |
| + ScriptContext* context) { |
| + v8::HandleScope handle_scope(context->isolate()); |
| + v8::Context::Scope context_scope(context->v8_context()); |
| + |
| + std::vector<v8::Local<v8::Value>> arguments; |
| + arguments.push_back(gin::StringToSymbol(context->isolate(), event_name)); |
| + |
| + { |
| + std::unique_ptr<content::V8ValueConverter> converter( |
| + content::V8ValueConverter::create()); |
| + arguments.push_back( |
| + converter->ToV8Value(event_args, context->v8_context())); |
| + if (!filtering_info->empty()) { |
| + arguments.push_back( |
| + converter->ToV8Value(filtering_info, context->v8_context())); |
| + } |
| + } |
| + |
| + context->module_system()->CallModuleMethodSafe( |
| + kEventBindings, kEventDispatchFunction, arguments.size(), |
| + arguments.data()); |
| +} |
| + |
| } // namespace |
| // Note that we can't use Blink public APIs in the constructor becase Blink |
| @@ -623,59 +652,42 @@ void Dispatcher::OnExtensionResponse(int request_id, |
| request_sender_->HandleResponse(request_id, success, response, error); |
| } |
| -void Dispatcher::DispatchEvent(const std::string& extension_id, |
| - const std::string& event_name) const { |
| - base::ListValue args; |
| - args.Set(0, new base::StringValue(event_name)); |
| - args.Set(1, new base::ListValue()); |
| +void Dispatcher::DispatchEvent( |
| + const std::string& extension_id, |
| + const std::string& event_name, |
| + const base::ListValue& event_args, |
| + const base::DictionaryValue& filtering_info) const { |
| + script_context_set_->ForEach(extension_id, nullptr, |
| + base::Bind(&DispatchEventInContext, event_name, |
| + &event_args, &filtering_info)); |
| - // Needed for Windows compilation, since kEventBindings is declared extern. |
| - const char* local_event_bindings = kEventBindings; |
| - script_context_set_->ForEach( |
| - extension_id, base::Bind(&CallModuleMethod, local_event_bindings, |
| - kEventDispatchFunction, &args)); |
| + // Reset the idle handler each time there's any activity like event or message |
| + // dispatch. |
| + // TODO(devlin): It's likely this is totally wrong. See |
| + // https://groups.google.com/a/chromium.org/forum/#!msg/scheduler-dev/iTRVbcmmpAs/pfqyUyEeAAAJ |
| + if (set_idle_notifications_) { |
| + RenderThread::Get()->ScheduleIdleHandler( |
| + kInitialExtensionIdleHandlerDelayMs); |
| + } |
| } |
| void Dispatcher::InvokeModuleSystemMethod(content::RenderFrame* render_frame, |
| const std::string& extension_id, |
| const std::string& module_name, |
| const std::string& function_name, |
| - const base::ListValue& args, |
| - bool user_gesture) { |
| - std::unique_ptr<WebScopedUserGesture> web_user_gesture; |
| - if (user_gesture) { |
| - blink::WebLocalFrame* web_frame = |
| - render_frame ? render_frame->GetWebFrame() : nullptr; |
| - web_user_gesture.reset(new WebScopedUserGesture(web_frame)); |
| - } |
| - |
| + const base::ListValue& args) { |
| script_context_set_->ForEach( |
| extension_id, render_frame, |
| base::Bind(&CallModuleMethod, module_name, function_name, &args)); |
| // Reset the idle handler each time there's any activity like event or message |
| - // dispatch, for which Invoke is the chokepoint. |
| + // dispatch. |
| + // TODO(devlin): It's likely this is totally wrong. See |
| + // https://groups.google.com/a/chromium.org/forum/#!msg/scheduler-dev/iTRVbcmmpAs/pfqyUyEeAAAJ |
| if (set_idle_notifications_) { |
| RenderThread::Get()->ScheduleIdleHandler( |
| kInitialExtensionIdleHandlerDelayMs); |
| } |
| - |
| - // Tell the browser process when an event has been dispatched with a lazy |
| - // background page active. |
| - const Extension* extension = |
| - RendererExtensionRegistry::Get()->GetByID(extension_id); |
| - if (extension && BackgroundInfo::HasLazyBackgroundPage(extension) && |
| - module_name == kEventBindings && |
| - function_name == kEventDispatchFunction) { |
| - content::RenderFrame* background_frame = |
| - ExtensionFrameHelper::GetBackgroundPageFrame(extension_id); |
| - if (background_frame) { |
| - int message_id; |
| - args.GetInteger(3, &message_id); |
|
Devlin
2016/11/16 20:52:55
(Note: This is where it used to be used)
|
| - background_frame->Send(new ExtensionHostMsg_EventAck( |
| - background_frame->GetRoutingID(), message_id)); |
| - } |
| - } |
| } |
| // static |
| @@ -923,6 +935,7 @@ bool Dispatcher::OnControlMessageReceived(const IPC::Message& message) { |
| IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect, OnDispatchOnDisconnect) |
| IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded) |
| IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) |
| + IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchEvent, OnDispatchEvent) |
| IPC_MESSAGE_HANDLER(ExtensionMsg_SetSessionInfo, OnSetSessionInfo) |
| IPC_MESSAGE_HANDLER(ExtensionMsg_SetScriptingWhitelist, |
| OnSetScriptingWhitelist) |
| @@ -1013,7 +1026,8 @@ void Dispatcher::OnActivateExtension(const std::string& extension_id) { |
| } |
| void Dispatcher::OnCancelSuspend(const std::string& extension_id) { |
| - DispatchEvent(extension_id, kOnSuspendCanceledEvent); |
| + DispatchEvent(extension_id, kOnSuspendCanceledEvent, base::ListValue(), |
| + base::DictionaryValue()); |
| } |
| void Dispatcher::OnDeliverMessage(int target_port_id, |
| @@ -1091,10 +1105,33 @@ void Dispatcher::OnLoaded( |
| void Dispatcher::OnMessageInvoke(const std::string& extension_id, |
| const std::string& module_name, |
| const std::string& function_name, |
| - const base::ListValue& args, |
| - bool user_gesture) { |
| - InvokeModuleSystemMethod( |
| - NULL, extension_id, module_name, function_name, args, user_gesture); |
| + const base::ListValue& args) { |
| + InvokeModuleSystemMethod(NULL, extension_id, module_name, function_name, |
|
lazyboy
2016/11/16 20:21:02
nullptr
Devlin
2016/11/16 20:52:55
Done.
|
| + args); |
| +} |
| + |
| +void Dispatcher::OnDispatchEvent( |
| + const ExtensionMsg_DispatchEvent_Params& params, |
| + const base::ListValue& event_args) { |
| + std::unique_ptr<WebScopedUserGesture> web_user_gesture; |
| + if (params.is_user_gesture) |
| + web_user_gesture.reset(new WebScopedUserGesture(nullptr)); |
| + |
| + DispatchEvent(params.extension_id, params.event_name, event_args, |
| + params.filtering_info); |
| + |
| + // Tell the browser process when an event has been dispatched with a lazy |
| + // background page active. |
| + const Extension* extension = |
| + RendererExtensionRegistry::Get()->GetByID(params.extension_id); |
| + if (extension && BackgroundInfo::HasLazyBackgroundPage(extension)) { |
| + content::RenderFrame* background_frame = |
| + ExtensionFrameHelper::GetBackgroundPageFrame(params.extension_id); |
| + if (background_frame) { |
| + background_frame->Send(new ExtensionHostMsg_EventAck( |
| + background_frame->GetRoutingID(), params.event_id)); |
| + } |
| + } |
| } |
| void Dispatcher::OnSetSessionInfo(version_info::Channel channel, |
| @@ -1138,7 +1175,8 @@ void Dispatcher::OnSuspend(const std::string& extension_id) { |
| // the browser know when we are starting and stopping the event dispatch, so |
| // that it still considers the extension idle despite any activity the suspend |
| // event creates. |
| - DispatchEvent(extension_id, kOnSuspendEvent); |
| + DispatchEvent(extension_id, kOnSuspendEvent, base::ListValue(), |
| + base::DictionaryValue()); |
| RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); |
| } |