diff options
author | wjmaclean@chromium.org <wjmaclean@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-15 09:44:43 +0000 |
---|---|---|
committer | wjmaclean@chromium.org <wjmaclean@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-15 09:46:27 +0000 |
commit | 16a4206fa5c288cae557309927a5c1b78e030b4d (patch) | |
tree | 4b5209ff9e95a0301817599bc8acceb3bd2e14a8 /extensions/browser/script_executor.cc | |
parent | 6ca7dc17ec1c73d41ffdb8344bf0a6a17bb29319 (diff) | |
download | chromium_src-16a4206fa5c288cae557309927a5c1b78e030b4d.zip chromium_src-16a4206fa5c288cae557309927a5c1b78e030b4d.tar.gz chromium_src-16a4206fa5c288cae557309927a5c1b78e030b4d.tar.bz2 |
Move script_executor.* to extensions/browser
This CL abstracts the dependence of ScriptExecutionObserver on
TabHelper through the introduction of ScriptExecutionObserver::Delegate
and then moves the script_executor files.
BUG=352290
Review URL: https://codereview.chromium.org/477433002
Cr-Commit-Position: refs/heads/master@{#289837}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289837 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'extensions/browser/script_executor.cc')
-rw-r--r-- | extensions/browser/script_executor.cc | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/extensions/browser/script_executor.cc b/extensions/browser/script_executor.cc new file mode 100644 index 0000000..a2ce27b --- /dev/null +++ b/extensions/browser/script_executor.cc @@ -0,0 +1,155 @@ +// Copyright 2014 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 "extensions/browser/script_executor.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/logging.h" +#include "base/pickle.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/script_execution_observer.h" +#include "extensions/common/extension_messages.h" +#include "ipc/ipc_message.h" +#include "ipc/ipc_message_macros.h" + +namespace base { +class ListValue; +} // namespace base + +namespace extensions { + +namespace { + +const char* kRendererDestroyed = "The tab was closed."; + +// A handler for a single injection request. On creation this will send the +// injection request to the renderer, and it will be destroyed after either the +// corresponding response comes from the renderer, or the renderer is destroyed. +class Handler : public content::WebContentsObserver { + public: + Handler(ObserverList<ScriptExecutionObserver>* script_observers, + content::WebContents* web_contents, + const ExtensionMsg_ExecuteCode_Params& params, + const ScriptExecutor::ExecuteScriptCallback& callback) + : content::WebContentsObserver(web_contents), + script_observers_(AsWeakPtr(script_observers)), + extension_id_(params.extension_id), + request_id_(params.request_id), + callback_(callback) { + content::RenderViewHost* rvh = web_contents->GetRenderViewHost(); + rvh->Send(new ExtensionMsg_ExecuteCode(rvh->GetRoutingID(), params)); + } + + virtual ~Handler() {} + + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { + // Unpack by hand to check the request_id, since there may be multiple + // requests in flight but only one is for this. + if (message.type() != ExtensionHostMsg_ExecuteCodeFinished::ID) + return false; + + int message_request_id; + PickleIterator iter(message); + CHECK(message.ReadInt(&iter, &message_request_id)); + + if (message_request_id != request_id_) + return false; + + IPC_BEGIN_MESSAGE_MAP(Handler, message) + IPC_MESSAGE_HANDLER(ExtensionHostMsg_ExecuteCodeFinished, + OnExecuteCodeFinished) + IPC_END_MESSAGE_MAP() + return true; + } + + virtual void WebContentsDestroyed() OVERRIDE { + base::ListValue val; + callback_.Run(kRendererDestroyed, GURL(std::string()), val); + delete this; + } + + private: + void OnExecuteCodeFinished(int request_id, + const std::string& error, + const GURL& on_url, + const base::ListValue& script_result) { + if (script_observers_.get() && error.empty()) { + ScriptExecutionObserver::ExecutingScriptsMap id_map; + id_map[extension_id_] = std::set<std::string>(); + FOR_EACH_OBSERVER(ScriptExecutionObserver, + *script_observers_, + OnScriptsExecuted(web_contents(), id_map, on_url)); + } + + callback_.Run(error, on_url, script_result); + delete this; + } + + base::WeakPtr<ObserverList<ScriptExecutionObserver> > script_observers_; + std::string extension_id_; + int request_id_; + ScriptExecutor::ExecuteScriptCallback callback_; +}; + +} // namespace + +ScriptExecutionObserver::~ScriptExecutionObserver() { +} + +ScriptExecutor::ScriptExecutor( + content::WebContents* web_contents, + ObserverList<ScriptExecutionObserver>* script_observers) + : next_request_id_(0), + web_contents_(web_contents), + script_observers_(script_observers) { + CHECK(web_contents_); +} + +ScriptExecutor::~ScriptExecutor() { +} + +void ScriptExecutor::ExecuteScript(const std::string& extension_id, + ScriptExecutor::ScriptType script_type, + const std::string& code, + ScriptExecutor::FrameScope frame_scope, + ScriptExecutor::MatchAboutBlank about_blank, + UserScript::RunLocation run_at, + ScriptExecutor::WorldType world_type, + ScriptExecutor::ProcessType process_type, + const GURL& webview_src, + const GURL& file_url, + bool user_gesture, + ScriptExecutor::ResultType result_type, + const ExecuteScriptCallback& callback) { + // Don't execute if the extension has been unloaded. + const Extension* extension = + ExtensionRegistry::Get(web_contents_->GetBrowserContext()) + ->enabled_extensions().GetByID(extension_id); + if (!extension) + return; + + ExtensionMsg_ExecuteCode_Params params; + params.request_id = next_request_id_++; + params.extension_id = extension_id; + params.is_javascript = (script_type == JAVASCRIPT); + params.code = code; + params.all_frames = (frame_scope == ALL_FRAMES); + params.match_about_blank = (about_blank == MATCH_ABOUT_BLANK); + params.run_at = static_cast<int>(run_at); + params.in_main_world = (world_type == MAIN_WORLD); + params.is_web_view = (process_type == WEB_VIEW_PROCESS); + params.webview_src = webview_src; + params.file_url = file_url; + params.wants_result = (result_type == JSON_SERIALIZED_RESULT); + params.user_gesture = user_gesture; + + // Handler handles IPCs and deletes itself on completion. + new Handler(script_observers_, web_contents_, params, callback); +} + +} // namespace extensions |