16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (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) 56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "extensions/browser/script_executor.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/pickle.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_observer.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_registry.h" 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "extensions/browser/script_execution_observer.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/common/extension_messages.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_macros.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ListValue; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kRendererDestroyed = "The tab was closed."; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A handler for a single injection request. On creation this will send the 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// injection request to the renderer, and it will be destroyed after either the 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// corresponding response comes from the renderer, or the renderer is destroyed. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Handler : public content::WebContentsObserver { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Handler(ObserverList<ScriptExecutionObserver>* script_observers, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionMsg_ExecuteCode_Params& params, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ScriptExecutor::ExecuteScriptCallback& callback) 396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : content::WebContentsObserver(web_contents), 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) script_observers_(AsWeakPtr(script_observers)), 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) extension_id_(params.extension_id), 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) request_id_(params.request_id), 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) callback_(callback) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderViewHost* rvh = web_contents->GetRenderViewHost(); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rvh->Send(new ExtensionMsg_ExecuteCode(rvh->GetRoutingID(), params)); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Handler() {} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unpack by hand to check the request_id, since there may be multiple 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // requests in flight but only one is for this. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message.type() != ExtensionHostMsg_ExecuteCodeFinished::ID) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int message_request_id; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(message); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(message.ReadInt(&iter, &message_request_id)); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message_request_id != request_id_) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(Handler, message) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(ExtensionHostMsg_ExecuteCodeFinished, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnExecuteCodeFinished) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual void WebContentsDestroyed() OVERRIDE { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ListValue val; 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback_.Run(kRendererDestroyed, GURL(std::string()), val); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnExecuteCodeFinished(int request_id, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& error, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& on_url, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::ListValue& script_result) { 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (script_observers_.get() && error.empty()) { 826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ScriptExecutionObserver::ExecutingScriptsMap id_map; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_map[extension_id_] = std::set<std::string>(); 846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) FOR_EACH_OBSERVER(ScriptExecutionObserver, 856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *script_observers_, 866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) OnScriptsExecuted(web_contents(), id_map, on_url)); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback_.Run(error, on_url, script_result); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::WeakPtr<ObserverList<ScriptExecutionObserver> > script_observers_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_id_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int request_id_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScriptExecutor::ExecuteScriptCallback callback_; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ScriptExecutionObserver::~ScriptExecutionObserver() { 1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScriptExecutor::ScriptExecutor( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents, 1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ObserverList<ScriptExecutionObserver>* script_observers) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : next_request_id_(0), 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_contents_(web_contents), 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) script_observers_(script_observers) { 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK(web_contents_); 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ScriptExecutor::~ScriptExecutor() { 1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ScriptExecutor::ExecuteScript(const std::string& extension_id, 117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ScriptExecutor::ScriptType script_type, 118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const std::string& code, 119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ScriptExecutor::FrameScope frame_scope, 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScriptExecutor::MatchAboutBlank about_blank, 121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch UserScript::RunLocation run_at, 122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ScriptExecutor::WorldType world_type, 123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ScriptExecutor::ProcessType process_type, 124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const GURL& webview_src, 125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const GURL& file_url, 126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bool user_gesture, 127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ScriptExecutor::ResultType result_type, 128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const ExecuteScriptCallback& callback) { 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Don't execute if the extension has been unloaded. 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const Extension* extension = 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ExtensionRegistry::Get(web_contents_->GetBrowserContext()) 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ->enabled_extensions().GetByID(extension_id); 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!extension) 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ExtensionMsg_ExecuteCode_Params params; 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.request_id = next_request_id_++; 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.extension_id = extension_id; 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.is_javascript = (script_type == JAVASCRIPT); 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.code = code; 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.all_frames = (frame_scope == ALL_FRAMES); 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.match_about_blank = (about_blank == MATCH_ABOUT_BLANK); 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.run_at = static_cast<int>(run_at); 144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.in_main_world = (world_type == MAIN_WORLD); 145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.is_web_view = (process_type == WEB_VIEW_PROCESS); 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.webview_src = webview_src; 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.file_url = file_url; 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.wants_result = (result_type == JSON_SERIALIZED_RESULT); 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.user_gesture = user_gesture; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handler handles IPCs and deletes itself on completion. 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new Handler(script_observers_, web_contents_, params, callback); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 156