OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/extensions/script_executor_impl.h" | |
6 | |
7 #include "base/callback.h" | |
8 #include "base/logging.h" | |
9 #include "base/pickle.h" | |
10 #include "chrome/common/extensions/extension_messages.h" | |
11 #include "content/public/browser/render_view_host.h" | |
12 #include "content/public/browser/web_contents.h" | |
13 #include "content/public/browser/web_contents_observer.h" | |
14 #include "ipc/ipc_message.h" | |
15 #include "ipc/ipc_message_macros.h" | |
16 | |
17 namespace extensions { | |
18 | |
19 namespace { | |
20 | |
21 const char* kRendererDestroyed = "The tab was closed."; | |
22 | |
23 // A handler for a single injection request. On creation this will send the | |
24 // injection request to the renderer, and it will be destroyed after either the | |
25 // corresponding response comes from the renderer, or the renderer is destroyed. | |
26 class Handler : public content::WebContentsObserver { | |
27 public: | |
28 Handler(content::WebContents* web_contents, | |
29 const ExtensionMsg_ExecuteCode_Params& params, | |
30 const ScriptExecutor::ExecuteScriptCallback& callback) | |
31 : content::WebContentsObserver(web_contents), | |
32 request_id_(params.request_id), | |
33 callback_(callback) { | |
34 content::RenderViewHost* rvh = web_contents->GetRenderViewHost(); | |
35 rvh->Send(new ExtensionMsg_ExecuteCode(rvh->GetRoutingID(), params)); | |
36 } | |
37 | |
38 virtual ~Handler() {} | |
39 | |
40 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | |
41 // Unpack by hand to check the request_id, since there may be multiple | |
42 // requests in flight but only one is for this. | |
43 if (message.type() != ExtensionHostMsg_ExecuteCodeFinished::ID) | |
44 return false; | |
45 | |
46 int message_request_id; | |
47 PickleIterator iter(message); | |
48 CHECK(message.ReadInt(&iter, &message_request_id)); | |
49 | |
50 if (message_request_id != request_id_) | |
51 return false; | |
52 | |
53 IPC_BEGIN_MESSAGE_MAP(Handler, message) | |
54 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ExecuteCodeFinished, | |
55 OnExecuteCodeFinished) | |
56 IPC_END_MESSAGE_MAP() | |
57 return true; | |
58 } | |
59 | |
60 virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE { | |
61 callback_.Run(false, -1, kRendererDestroyed); | |
62 delete this; | |
63 } | |
64 | |
65 private: | |
66 void OnExecuteCodeFinished(int request_id, | |
67 bool success, | |
68 int32 page_id, | |
69 const std::string& error) { | |
70 callback_.Run(success, page_id, error); | |
71 delete this; | |
72 } | |
73 | |
74 int request_id_; | |
75 ScriptExecutor::ExecuteScriptCallback callback_; | |
76 }; | |
77 | |
78 } // namespace | |
79 | |
80 ScriptExecutorImpl::ScriptExecutorImpl( | |
81 content::WebContents* web_contents) | |
82 : next_request_id_(0), | |
83 web_contents_(web_contents) {} | |
84 | |
85 ScriptExecutorImpl::~ScriptExecutorImpl() {} | |
86 | |
87 void ScriptExecutorImpl::ExecuteScript( | |
88 const std::string& extension_id, | |
89 ScriptExecutor::ScriptType script_type, | |
90 const std::string& code, | |
91 ScriptExecutor::FrameScope frame_scope, | |
92 UserScript::RunLocation run_at, | |
93 ScriptExecutor::WorldType world_type, | |
94 const ExecuteScriptCallback& callback) { | |
95 ExtensionMsg_ExecuteCode_Params params; | |
96 params.request_id = next_request_id_++; | |
97 params.extension_id = extension_id; | |
98 params.is_javascript = (script_type == JAVASCRIPT); | |
99 params.code = code; | |
100 params.all_frames = (frame_scope == ALL_FRAMES); | |
101 params.run_at = (int) run_at; | |
102 params.in_main_world = (world_type == MAIN_WORLD); | |
103 | |
104 // Handler handles IPCs and deletes itself on completion. | |
105 new Handler(web_contents_, params, callback); | |
106 } | |
107 | |
108 } // namespace extensions | |
OLD | NEW |