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,219 @@ |
+// 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" |
+#include "v8/include/v8.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() { |
+ DCHECK(!g_extension_dispatcher); |
+ g_extension_dispatcher = this; |
+ |
+ 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); |
+ } |
+ |
+ RegisterExtension(extensions_v8::ChromeAppExtension::Get(), false); |
+ |
+ // Add v8 extensions related to chrome extensions. |
+ RegisterExtension(ExtensionProcessBindings::Get(), true); |
+ RegisterExtension(BaseJsV8Extension::Get(), true); |
+ RegisterExtension(JsonSchemaJsV8Extension::Get(), true); |
+ RegisterExtension(EventBindings::Get(), true); |
+ RegisterExtension(RendererExtensionBindings::Get(), true); |
+ RegisterExtension(ExtensionApiTestV8Extension::Get(), true); |
+} |
+ |
+bool ExtensionDispatcher::AllowScriptExtension( |
+ const std::string& v8_extension_name, |
+ const GURL& url, |
+ int extension_group) { |
+ // If the V8 extension is not restricted, allow it to run anywhere. |
+ if (!restricted_v8_extensions_.count(v8_extension_name)) |
+ return true; |
+ |
+ // 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); |
+} |
+ |
+void ExtensionDispatcher::RegisterExtension(v8::Extension* extension, |
+ bool restrict_to_extensions) { |
+ if (restrict_to_extensions) |
+ restricted_v8_extensions_.insert(extension->name()); |
+ |
+ RenderThread::current()->RegisterExtension(extension); |
+} |
Property changes on: chrome\renderer\extensions\extension_dispatcher.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |