Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / script_executor.cc
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.h"
6
7 #include "base/callback.h"
8 #include "base/logging.h"
9 #include "base/pickle.h"
10 #include "content/public/browser/render_view_host.h"
11 #include "content/public/browser/web_contents.h"
12 #include "content/public/browser/web_contents_observer.h"
13 #include "extensions/common/extension_messages.h"
14 #include "ipc/ipc_message.h"
15 #include "ipc/ipc_message_macros.h"
16
17 namespace base {
18 class ListValue;
19 }  // namespace base
20
21 namespace extensions {
22
23 namespace {
24
25 const char* kRendererDestroyed = "The tab was closed.";
26
27 // A handler for a single injection request. On creation this will send the
28 // injection request to the renderer, and it will be destroyed after either the
29 // corresponding response comes from the renderer, or the renderer is destroyed.
30 class Handler : public content::WebContentsObserver {
31  public:
32   Handler(ObserverList<TabHelper::ScriptExecutionObserver>* script_observers,
33           content::WebContents* web_contents,
34           const ExtensionMsg_ExecuteCode_Params& params,
35           const ScriptExecutor::ExecuteScriptCallback& callback)
36           : content::WebContentsObserver(web_contents),
37             script_observers_(AsWeakPtr(script_observers)),
38             extension_id_(params.extension_id),
39             request_id_(params.request_id),
40             callback_(callback) {
41     content::RenderViewHost* rvh = web_contents->GetRenderViewHost();
42     rvh->Send(new ExtensionMsg_ExecuteCode(rvh->GetRoutingID(), params));
43   }
44
45   virtual ~Handler() {}
46
47   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
48     // Unpack by hand to check the request_id, since there may be multiple
49     // requests in flight but only one is for this.
50     if (message.type() != ExtensionHostMsg_ExecuteCodeFinished::ID)
51       return false;
52
53     int message_request_id;
54     PickleIterator iter(message);
55     CHECK(message.ReadInt(&iter, &message_request_id));
56
57     if (message_request_id != request_id_)
58       return false;
59
60     IPC_BEGIN_MESSAGE_MAP(Handler, message)
61       IPC_MESSAGE_HANDLER(ExtensionHostMsg_ExecuteCodeFinished,
62                           OnExecuteCodeFinished)
63     IPC_END_MESSAGE_MAP()
64     return true;
65   }
66
67   virtual void WebContentsDestroyed() OVERRIDE {
68     base::ListValue val;
69     callback_.Run(kRendererDestroyed, -1, GURL(std::string()), val);
70     delete this;
71   }
72
73  private:
74   void OnExecuteCodeFinished(int request_id,
75                              const std::string& error,
76                              int32 on_page_id,
77                              const GURL& on_url,
78                              const base::ListValue& script_result) {
79     if (script_observers_.get() && error.empty()) {
80       TabHelper::ScriptExecutionObserver::ExecutingScriptsMap id_map;
81       id_map[extension_id_] = std::set<std::string>();
82       FOR_EACH_OBSERVER(TabHelper::ScriptExecutionObserver, *script_observers_,
83                         OnScriptsExecuted(web_contents(),
84                                           id_map,
85                                           on_page_id,
86                                           on_url));
87     }
88
89     callback_.Run(error, on_page_id, on_url, script_result);
90     delete this;
91   }
92
93   base::WeakPtr<ObserverList<TabHelper::ScriptExecutionObserver> >
94       script_observers_;
95   std::string extension_id_;
96   int request_id_;
97   ScriptExecutor::ExecuteScriptCallback callback_;
98 };
99
100 }  // namespace
101
102 ScriptExecutor::ScriptExecutor(
103     content::WebContents* web_contents,
104     ObserverList<TabHelper::ScriptExecutionObserver>* script_observers)
105     : next_request_id_(0),
106       web_contents_(web_contents),
107       script_observers_(script_observers) {}
108
109 ScriptExecutor::~ScriptExecutor() {}
110
111 void ScriptExecutor::ExecuteScript(const std::string& extension_id,
112                                    ScriptExecutor::ScriptType script_type,
113                                    const std::string& code,
114                                    ScriptExecutor::FrameScope frame_scope,
115                                    UserScript::RunLocation run_at,
116                                    ScriptExecutor::WorldType world_type,
117                                    ScriptExecutor::ProcessType process_type,
118                                    const GURL& webview_src,
119                                    const GURL& file_url,
120                                    bool user_gesture,
121                                    ScriptExecutor::ResultType result_type,
122                                    const ExecuteScriptCallback& callback) {
123   ExtensionMsg_ExecuteCode_Params params;
124   params.request_id = next_request_id_++;
125   params.extension_id = extension_id;
126   params.is_javascript = (script_type == JAVASCRIPT);
127   params.code = code;
128   params.all_frames = (frame_scope == ALL_FRAMES);
129   params.run_at = static_cast<int>(run_at);
130   params.in_main_world = (world_type == MAIN_WORLD);
131   params.is_web_view = (process_type == WEB_VIEW_PROCESS);
132   params.webview_src = webview_src;
133   params.file_url = file_url;
134   params.wants_result = (result_type == JSON_SERIALIZED_RESULT);
135   params.user_gesture = user_gesture;
136
137   // Handler handles IPCs and deletes itself on completion.
138   new Handler(script_observers_, web_contents_, params, callback);
139 }
140
141 }  // namespace extensions