Chromium Code Reviews| Index: chrome/renderer/extensions/extension_dispatcher.cc |
| =================================================================== |
| --- chrome/renderer/extensions/extension_dispatcher.cc (revision 0) |
| +++ chrome/renderer/extensions/extension_dispatcher.cc (revision 0) |
| @@ -0,0 +1,212 @@ |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/renderer/extensions/extension_dispatcher.h" |
| + |
| +#include "base/command_line.h" |
| +#include "chrome/common/child_process_logging.h" |
| +#include "chrome/common/chrome_switches.h" |
| +#include "chrome/common/extensions/extension.h" |
| +#include "chrome/common/extensions/extension_messages.h" |
| +#include "chrome/renderer/extension_groups.h" |
| +#include "chrome/renderer/extensions/chrome_app_bindings.h" |
| +#include "chrome/renderer/extensions/event_bindings.h" |
| +#include "chrome/renderer/extensions/extension_process_bindings.h" |
| +#include "chrome/renderer/extensions/js_only_v8_extensions.h" |
| +#include "chrome/renderer/extensions/renderer_extension_bindings.h" |
| +#include "chrome/renderer/render_thread.h" |
| +#include "chrome/renderer/user_script_slave.h" |
| + |
| +namespace { |
| +static const double kInitialExtensionIdleHandlerDelayS = 5.0 /* seconds */; |
| +static const int64 kMaxExtensionIdleHandlerDelayS = 5*60 /* seconds */; |
| +static ExtensionDispatcher* g_extension_dispatcher; |
| +} |
| + |
| +ExtensionDispatcher* ExtensionDispatcher::Get() { |
| + return g_extension_dispatcher; |
| +} |
| + |
| +ExtensionDispatcher::ExtensionDispatcher() { |
| + g_extension_dispatcher = this; |
|
Matt Perry
2011/03/29 00:48:29
CHECK that this is NULL beforehand?
It's weird th
jam
2011/03/29 04:55:37
DONE
|
| + |
| + std::string type_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| + switches::kProcessType); |
| + is_extension_process_ = type_str == switches::kExtensionProcess || |
| + CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess); |
| + |
| + if (is_extension_process_) { |
| + RenderThread::current()->set_idle_notification_delay_in_s( |
| + kInitialExtensionIdleHandlerDelayS); |
| + } |
| + |
| + user_script_slave_.reset(new UserScriptSlave(&extensions_)); |
| +} |
| + |
| +ExtensionDispatcher::~ExtensionDispatcher() { |
| + g_extension_dispatcher = NULL; |
| +} |
| + |
| +bool ExtensionDispatcher::OnControlMessageReceived( |
| + const IPC::Message& message) { |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(ExtensionDispatcher, message) |
| + IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) |
| + IPC_MESSAGE_HANDLER(ExtensionMsg_SetFunctionNames, OnSetFunctionNames) |
| + IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded) |
| + IPC_MESSAGE_HANDLER(ExtensionMsg_Unloaded, OnUnloaded) |
| + IPC_MESSAGE_HANDLER(ExtensionMsg_SetScriptingWhitelist, |
| + OnSetScriptingWhitelist) |
| + IPC_MESSAGE_HANDLER(ExtensionMsg_UpdatePageActions, OnPageActionsUpdated) |
| + IPC_MESSAGE_HANDLER(ExtensionMsg_SetAPIPermissions, OnSetAPIPermissions) |
| + IPC_MESSAGE_HANDLER(ExtensionMsg_SetHostPermissions, OnSetHostPermissions) |
| + IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts, OnUpdateUserScripts) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + |
| + return handled; |
| +} |
| + |
| +void ExtensionDispatcher::OnRenderProcessShutdown() { |
| + delete this; |
| +} |
| + |
| +void ExtensionDispatcher::WebKitInitialized() { |
| + // For extensions, we want to ensure we call the IdleHandler every so often, |
| + // even if the extension keeps up activity. |
| + if (is_extension_process_) { |
| + forced_idle_timer_.Start( |
| + base::TimeDelta::FromSeconds(kMaxExtensionIdleHandlerDelayS), |
| + RenderThread::current(), &RenderThread::IdleHandler); |
| + } |
| + |
| + RenderThread::current()->RegisterExtension( |
| + extensions_v8::ChromeAppExtension::Get(), false); |
| + |
| + // Add v8 extensions related to chrome extensions. |
| + RenderThread::current()->RegisterExtension( |
| + ExtensionProcessBindings::Get(), true); |
| + RenderThread::current()->RegisterExtension( |
| + BaseJsV8Extension::Get(), true); |
| + RenderThread::current()->RegisterExtension( |
| + JsonSchemaJsV8Extension::Get(), true); |
| + RenderThread::current()->RegisterExtension( |
| + EventBindings::Get(), true); |
| + RenderThread::current()->RegisterExtension( |
| + RendererExtensionBindings::Get(), true); |
| + RenderThread::current()->RegisterExtension( |
| + ExtensionApiTestV8Extension::Get(), true); |
| +} |
| + |
| +bool ExtensionDispatcher::AllowScriptExtension( |
| + const std::string& v8_extension_name, |
| + const GURL& url, |
| + int extension_group) { |
| + // Extension-only bindings should be restricted to content scripts and |
| + // extension-blessed URLs. |
| + if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS || |
| + extensions_.ExtensionBindingsAllowed(url)) { |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| +void ExtensionDispatcher::IdleNotification() { |
| + if (is_extension_process_) { |
| + // Dampen the forced delay as well if the extension stays idle for long |
| + // periods of time. |
| + int64 forced_delay_s = std::max(static_cast<int64>( |
| + RenderThread::current()->idle_notification_delay_in_s()), |
| + kMaxExtensionIdleHandlerDelayS); |
| + forced_idle_timer_.Stop(); |
| + forced_idle_timer_.Start( |
| + base::TimeDelta::FromSeconds(forced_delay_s), |
| + RenderThread::current(), &RenderThread::IdleHandler); |
| + } |
| +} |
| + |
| +void ExtensionDispatcher::OnSetFunctionNames( |
| + const std::vector<std::string>& names) { |
| + ExtensionProcessBindings::SetFunctionNames(names); |
| +} |
| + |
| +void ExtensionDispatcher::OnMessageInvoke(const std::string& extension_id, |
| + const std::string& function_name, |
| + const ListValue& args, |
| + const GURL& event_url) { |
| + RendererExtensionBindings::Invoke( |
| + extension_id, function_name, args, NULL, event_url); |
| + |
| + // Reset the idle handler each time there's any activity like event or message |
| + // dispatch, for which Invoke is the chokepoint. |
| + if (is_extension_process_) { |
| + RenderThread::current()->ScheduleIdleHandler( |
| + kInitialExtensionIdleHandlerDelayS); |
| + } |
| +} |
| + |
| +void ExtensionDispatcher::OnLoaded(const ExtensionMsg_Loaded_Params& params) { |
| + scoped_refptr<const Extension> extension(params.ConvertToExtension()); |
| + if (!extension) { |
| + // This can happen if extension parsing fails for any reason. One reason |
| + // this can legitimately happen is if the |
| + // --enable-experimental-extension-apis changes at runtime, which happens |
| + // during browser tests. Existing renderers won't know about the change. |
| + return; |
| + } |
| + |
| + extensions_.Insert(extension); |
| +} |
| + |
| +void ExtensionDispatcher::OnUnloaded(const std::string& id) { |
| + extensions_.Remove(id); |
| +} |
| + |
| +void ExtensionDispatcher::OnSetScriptingWhitelist( |
| + const Extension::ScriptingWhitelist& extension_ids) { |
| + Extension::SetScriptingWhitelist(extension_ids); |
| +} |
| + |
| +void ExtensionDispatcher::OnPageActionsUpdated( |
| + const std::string& extension_id, |
| + const std::vector<std::string>& page_actions) { |
| + ExtensionProcessBindings::SetPageActions(extension_id, page_actions); |
| +} |
| + |
| +void ExtensionDispatcher::OnSetAPIPermissions( |
| + const std::string& extension_id, |
| + const std::set<std::string>& permissions) { |
| + ExtensionProcessBindings::SetAPIPermissions(extension_id, permissions); |
| + |
| + // This is called when starting a new extension page, so start the idle |
| + // handler ticking. |
| + RenderThread::current()->ScheduleIdleHandler( |
| + kInitialExtensionIdleHandlerDelayS); |
| + |
| + UpdateActiveExtensions(); |
| +} |
| + |
| +void ExtensionDispatcher::OnSetHostPermissions( |
| + const GURL& extension_url, const std::vector<URLPattern>& permissions) { |
| + ExtensionProcessBindings::SetHostPermissions(extension_url, permissions); |
| +} |
| + |
| +void ExtensionDispatcher::OnUpdateUserScripts( |
| + base::SharedMemoryHandle scripts) { |
| + DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle"; |
| + user_script_slave_->UpdateScripts(scripts); |
| + UpdateActiveExtensions(); |
| +} |
| + |
| +void ExtensionDispatcher::UpdateActiveExtensions() { |
| + // In single-process mode, the browser process reports the active extensions. |
| + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) |
| + return; |
| + |
| + std::set<std::string> active_extensions; |
| + user_script_slave_->GetActiveExtensions(&active_extensions); |
| + ExtensionProcessBindings::GetActiveExtensions(&active_extensions); |
| + child_process_logging::SetActiveExtensions(active_extensions); |
| +} |
| Property changes on: chrome\renderer\extensions\extension_dispatcher.cc |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + LF |