Clean up check for dependency_info.
[chromium-blink-merge.git] / content / browser / webui / web_ui_impl.cc
blobc3ed17b34fdb32bf2538eaa231857e6f58d9be87
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.
5 #include "content/browser/webui/web_ui_impl.h"
7 #include "base/debug/dump_without_crashing.h"
8 #include "base/json/json_writer.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/values.h"
11 #include "content/browser/child_process_security_policy_impl.h"
12 #include "content/browser/renderer_host/dip_util.h"
13 #include "content/browser/renderer_host/render_process_host_impl.h"
14 #include "content/browser/web_contents/web_contents_impl.h"
15 #include "content/browser/web_contents/web_contents_view.h"
16 #include "content/browser/webui/web_ui_controller_factory_registry.h"
17 #include "content/common/view_messages.h"
18 #include "content/public/browser/content_browser_client.h"
19 #include "content/public/browser/render_frame_host.h"
20 #include "content/public/browser/render_view_host.h"
21 #include "content/public/browser/web_ui_controller.h"
22 #include "content/public/browser/web_ui_message_handler.h"
23 #include "content/public/common/bindings_policy.h"
24 #include "content/public/common/content_client.h"
26 namespace content {
28 const WebUI::TypeID WebUI::kNoWebUI = NULL;
30 // static
31 base::string16 WebUI::GetJavascriptCall(
32 const std::string& function_name,
33 const std::vector<const base::Value*>& arg_list) {
34 base::string16 parameters;
35 std::string json;
36 for (size_t i = 0; i < arg_list.size(); ++i) {
37 if (i > 0)
38 parameters += base::char16(',');
40 base::JSONWriter::Write(*arg_list[i], &json);
41 parameters += base::UTF8ToUTF16(json);
43 return base::ASCIIToUTF16(function_name) +
44 base::char16('(') + parameters + base::char16(')') + base::char16(';');
47 WebUIImpl::WebUIImpl(WebContents* contents, const std::string& frame_name)
48 : link_transition_type_(ui::PAGE_TRANSITION_LINK),
49 bindings_(BINDINGS_POLICY_WEB_UI),
50 web_contents_(contents),
51 frame_name_(frame_name) {
52 DCHECK(contents);
55 WebUIImpl::~WebUIImpl() {
56 // Delete the controller first, since it may also be keeping a pointer to some
57 // of the handlers and can call them at destruction.
58 controller_.reset();
61 // WebUIImpl, public: ----------------------------------------------------------
63 bool WebUIImpl::OnMessageReceived(const IPC::Message& message) {
64 bool handled = true;
65 IPC_BEGIN_MESSAGE_MAP(WebUIImpl, message)
66 IPC_MESSAGE_HANDLER(ViewHostMsg_WebUISend, OnWebUISend)
67 IPC_MESSAGE_UNHANDLED(handled = false)
68 IPC_END_MESSAGE_MAP()
69 return handled;
72 void WebUIImpl::OnWebUISend(const GURL& source_url,
73 const std::string& message,
74 const base::ListValue& args) {
75 if (!ChildProcessSecurityPolicyImpl::GetInstance()->
76 HasWebUIBindings(web_contents_->GetRenderProcessHost()->GetID()) ||
77 !WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI(
78 web_contents_->GetBrowserContext(), source_url)) {
79 NOTREACHED() << "Blocked unauthorized use of WebUIBindings.";
80 return;
83 ProcessWebUIMessage(source_url, message, args);
86 void WebUIImpl::RenderViewCreated(RenderViewHost* render_view_host) {
87 controller_->RenderViewCreated(render_view_host);
90 WebContents* WebUIImpl::GetWebContents() const {
91 return web_contents_;
94 float WebUIImpl::GetDeviceScaleFactor() const {
95 return GetScaleFactorForView(web_contents_->GetRenderWidgetHostView());
98 const base::string16& WebUIImpl::GetOverriddenTitle() const {
99 return overridden_title_;
102 void WebUIImpl::OverrideTitle(const base::string16& title) {
103 overridden_title_ = title;
106 ui::PageTransition WebUIImpl::GetLinkTransitionType() const {
107 return link_transition_type_;
110 void WebUIImpl::SetLinkTransitionType(ui::PageTransition type) {
111 link_transition_type_ = type;
114 int WebUIImpl::GetBindings() const {
115 return bindings_;
118 void WebUIImpl::SetBindings(int bindings) {
119 bindings_ = bindings;
122 WebUIController* WebUIImpl::GetController() const {
123 return controller_.get();
126 void WebUIImpl::SetController(WebUIController* controller) {
127 controller_.reset(controller);
130 void WebUIImpl::CallJavascriptFunction(const std::string& function_name) {
131 DCHECK(base::IsStringASCII(function_name));
132 base::string16 javascript = base::ASCIIToUTF16(function_name + "();");
133 ExecuteJavascript(javascript);
136 void WebUIImpl::CallJavascriptFunction(const std::string& function_name,
137 const base::Value& arg) {
138 DCHECK(base::IsStringASCII(function_name));
139 std::vector<const base::Value*> args;
140 args.push_back(&arg);
141 ExecuteJavascript(GetJavascriptCall(function_name, args));
144 void WebUIImpl::CallJavascriptFunction(
145 const std::string& function_name,
146 const base::Value& arg1, const base::Value& arg2) {
147 DCHECK(base::IsStringASCII(function_name));
148 std::vector<const base::Value*> args;
149 args.push_back(&arg1);
150 args.push_back(&arg2);
151 ExecuteJavascript(GetJavascriptCall(function_name, args));
154 void WebUIImpl::CallJavascriptFunction(
155 const std::string& function_name,
156 const base::Value& arg1, const base::Value& arg2, const base::Value& arg3) {
157 DCHECK(base::IsStringASCII(function_name));
158 std::vector<const base::Value*> args;
159 args.push_back(&arg1);
160 args.push_back(&arg2);
161 args.push_back(&arg3);
162 ExecuteJavascript(GetJavascriptCall(function_name, args));
165 void WebUIImpl::CallJavascriptFunction(
166 const std::string& function_name,
167 const base::Value& arg1,
168 const base::Value& arg2,
169 const base::Value& arg3,
170 const base::Value& arg4) {
171 DCHECK(base::IsStringASCII(function_name));
172 std::vector<const base::Value*> args;
173 args.push_back(&arg1);
174 args.push_back(&arg2);
175 args.push_back(&arg3);
176 args.push_back(&arg4);
177 ExecuteJavascript(GetJavascriptCall(function_name, args));
180 void WebUIImpl::CallJavascriptFunction(
181 const std::string& function_name,
182 const std::vector<const base::Value*>& args) {
183 DCHECK(base::IsStringASCII(function_name));
184 ExecuteJavascript(GetJavascriptCall(function_name, args));
187 void WebUIImpl::RegisterMessageCallback(const std::string &message,
188 const MessageCallback& callback) {
189 message_callbacks_.insert(std::make_pair(message, callback));
192 void WebUIImpl::ProcessWebUIMessage(const GURL& source_url,
193 const std::string& message,
194 const base::ListValue& args) {
195 if (controller_->OverrideHandleWebUIMessage(source_url, message, args))
196 return;
198 // Look up the callback for this message.
199 MessageCallbackMap::const_iterator callback =
200 message_callbacks_.find(message);
201 if (callback != message_callbacks_.end()) {
202 // Forward this message and content on.
203 callback->second.Run(&args);
204 } else {
205 NOTREACHED() << "Unhandled chrome.send(\"" << message << "\");";
209 // WebUIImpl, protected: -------------------------------------------------------
211 void WebUIImpl::AddMessageHandler(WebUIMessageHandler* handler) {
212 DCHECK(!handler->web_ui());
213 handler->set_web_ui(this);
214 handler->RegisterMessages();
215 handlers_.push_back(handler);
218 void WebUIImpl::ExecuteJavascript(const base::string16& javascript) {
219 RenderFrameHost* target_frame = TargetFrame();
220 if (target_frame) {
221 if (!(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
222 target_frame->GetProcess()->GetID()) ||
223 // It's possible to load about:blank in a Web UI renderer.
224 // See http://crbug.com/42547
225 target_frame->GetLastCommittedURL().spec() == url::kAboutBlankURL)) {
226 // Don't crash when we try to inject JavaScript into a non-WebUI page, but
227 // upload a crash report anyways. http://crbug.com/516690
228 base::debug::DumpWithoutCrashing();
229 return;
231 target_frame->ExecuteJavaScript(javascript);
235 RenderFrameHost* WebUIImpl::TargetFrame() {
236 if (frame_name_.empty())
237 return web_contents_->GetMainFrame();
239 std::set<RenderFrameHost*> frame_set;
240 web_contents_->ForEachFrame(base::Bind(&WebUIImpl::AddToSetIfFrameNameMatches,
241 base::Unretained(this),
242 &frame_set));
244 // It happens that some sub-pages attempt to send JavaScript messages before
245 // their frames are loaded.
246 DCHECK_GE(1U, frame_set.size());
247 if (frame_set.empty())
248 return NULL;
249 return *frame_set.begin();
252 void WebUIImpl::AddToSetIfFrameNameMatches(
253 std::set<RenderFrameHost*>* frame_set,
254 RenderFrameHost* host) {
255 if (host->GetFrameName() == frame_name_)
256 frame_set->insert(host);
259 } // namespace content