- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / webui / web_ui_impl.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 "content/browser/webui/web_ui_impl.h"
6
7 #include "base/json/json_writer.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/values.h"
10 #include "content/browser/child_process_security_policy_impl.h"
11 #include "content/browser/renderer_host/dip_util.h"
12 #include "content/browser/renderer_host/render_process_host_impl.h"
13 #include "content/browser/renderer_host/render_view_host_impl.h"
14 #include "content/browser/web_contents/web_contents_impl.h"
15 #include "content/browser/webui/web_ui_controller_factory_registry.h"
16 #include "content/common/view_messages.h"
17 #include "content/public/browser/content_browser_client.h"
18 #include "content/public/browser/web_contents_delegate.h"
19 #include "content/public/browser/web_contents_view.h"
20 #include "content/public/browser/web_ui_controller.h"
21 #include "content/public/browser/web_ui_message_handler.h"
22 #include "content/public/common/bindings_policy.h"
23 #include "content/public/common/content_client.h"
24
25 namespace content {
26
27 const WebUI::TypeID WebUI::kNoWebUI = NULL;
28
29 // static
30 string16 WebUI::GetJavascriptCall(
31     const std::string& function_name,
32     const std::vector<const Value*>& arg_list) {
33   string16 parameters;
34   std::string json;
35   for (size_t i = 0; i < arg_list.size(); ++i) {
36     if (i > 0)
37       parameters += char16(',');
38
39     base::JSONWriter::Write(arg_list[i], &json);
40     parameters += UTF8ToUTF16(json);
41   }
42   return ASCIIToUTF16(function_name) +
43       char16('(') + parameters + char16(')') + char16(';');
44 }
45
46 WebUIImpl::WebUIImpl(WebContents* contents)
47     : link_transition_type_(PAGE_TRANSITION_LINK),
48       bindings_(BINDINGS_POLICY_WEB_UI),
49       web_contents_(contents) {
50   DCHECK(contents);
51 }
52
53 WebUIImpl::~WebUIImpl() {
54   // Delete the controller first, since it may also be keeping a pointer to some
55   // of the handlers and can call them at destruction.
56   controller_.reset();
57 }
58
59 // WebUIImpl, public: ----------------------------------------------------------
60
61 bool WebUIImpl::OnMessageReceived(const IPC::Message& message) {
62   bool handled = true;
63   IPC_BEGIN_MESSAGE_MAP(WebUIImpl, message)
64     IPC_MESSAGE_HANDLER(ViewHostMsg_WebUISend, OnWebUISend)
65     IPC_MESSAGE_UNHANDLED(handled = false)
66   IPC_END_MESSAGE_MAP()
67   return handled;
68 }
69
70 void WebUIImpl::OnWebUISend(const GURL& source_url,
71                             const std::string& message,
72                             const ListValue& args) {
73   WebContentsDelegate* delegate = web_contents_->GetDelegate();
74   bool data_urls_allowed = delegate && delegate->CanLoadDataURLsInWebUI();
75   if (!ChildProcessSecurityPolicyImpl::GetInstance()->
76           HasWebUIBindings(web_contents_->GetRenderProcessHost()->GetID()) ||
77       !WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI(
78           web_contents_->GetBrowserContext(), source_url, data_urls_allowed)) {
79     NOTREACHED() << "Blocked unauthorized use of WebUIBindings.";
80     return;
81   }
82
83   ProcessWebUIMessage(source_url, message, args);
84 }
85
86 void WebUIImpl::RenderViewCreated(RenderViewHost* render_view_host) {
87   controller_->RenderViewCreated(render_view_host);
88
89   // Do not attempt to set the toolkit property if WebUI is not enabled, e.g.,
90   // the bookmarks manager page.
91   if (!(bindings_ & BINDINGS_POLICY_WEB_UI))
92     return;
93
94 #if defined(TOOLKIT_VIEWS)
95   render_view_host->SetWebUIProperty("toolkit", "views");
96 #elif defined(TOOLKIT_GTK)
97   render_view_host->SetWebUIProperty("toolkit", "GTK");
98 #endif  // defined(TOOLKIT_VIEWS)
99 }
100
101 WebContents* WebUIImpl::GetWebContents() const {
102   return web_contents_;
103 }
104
105 ui::ScaleFactor WebUIImpl::GetDeviceScaleFactor() const {
106   return GetScaleFactorForView(web_contents_->GetRenderWidgetHostView());
107 }
108
109 const string16& WebUIImpl::GetOverriddenTitle() const {
110   return overridden_title_;
111 }
112
113 void WebUIImpl::OverrideTitle(const string16& title) {
114   overridden_title_ = title;
115 }
116
117 PageTransition WebUIImpl::GetLinkTransitionType() const {
118   return link_transition_type_;
119 }
120
121 void WebUIImpl::SetLinkTransitionType(PageTransition type) {
122   link_transition_type_ = type;
123 }
124
125 int WebUIImpl::GetBindings() const {
126   return bindings_;
127 }
128
129 void WebUIImpl::SetBindings(int bindings) {
130   bindings_ = bindings;
131 }
132
133 void WebUIImpl::SetFrameXPath(const std::string& xpath) {
134   frame_xpath_ = xpath;
135 }
136
137 WebUIController* WebUIImpl::GetController() const {
138   return controller_.get();
139 }
140
141 void WebUIImpl::SetController(WebUIController* controller) {
142   controller_.reset(controller);
143 }
144
145 void WebUIImpl::CallJavascriptFunction(const std::string& function_name) {
146   DCHECK(IsStringASCII(function_name));
147   string16 javascript = ASCIIToUTF16(function_name + "();");
148   ExecuteJavascript(javascript);
149 }
150
151 void WebUIImpl::CallJavascriptFunction(const std::string& function_name,
152                                        const Value& arg) {
153   DCHECK(IsStringASCII(function_name));
154   std::vector<const Value*> args;
155   args.push_back(&arg);
156   ExecuteJavascript(GetJavascriptCall(function_name, args));
157 }
158
159 void WebUIImpl::CallJavascriptFunction(
160     const std::string& function_name,
161     const Value& arg1, const Value& arg2) {
162   DCHECK(IsStringASCII(function_name));
163   std::vector<const Value*> args;
164   args.push_back(&arg1);
165   args.push_back(&arg2);
166   ExecuteJavascript(GetJavascriptCall(function_name, args));
167 }
168
169 void WebUIImpl::CallJavascriptFunction(
170     const std::string& function_name,
171     const Value& arg1, const Value& arg2, const Value& arg3) {
172   DCHECK(IsStringASCII(function_name));
173   std::vector<const Value*> args;
174   args.push_back(&arg1);
175   args.push_back(&arg2);
176   args.push_back(&arg3);
177   ExecuteJavascript(GetJavascriptCall(function_name, args));
178 }
179
180 void WebUIImpl::CallJavascriptFunction(
181     const std::string& function_name,
182     const Value& arg1,
183     const Value& arg2,
184     const Value& arg3,
185     const Value& arg4) {
186   DCHECK(IsStringASCII(function_name));
187   std::vector<const Value*> args;
188   args.push_back(&arg1);
189   args.push_back(&arg2);
190   args.push_back(&arg3);
191   args.push_back(&arg4);
192   ExecuteJavascript(GetJavascriptCall(function_name, args));
193 }
194
195 void WebUIImpl::CallJavascriptFunction(
196     const std::string& function_name,
197     const std::vector<const Value*>& args) {
198   DCHECK(IsStringASCII(function_name));
199   ExecuteJavascript(GetJavascriptCall(function_name, args));
200 }
201
202 void WebUIImpl::RegisterMessageCallback(const std::string &message,
203                                         const MessageCallback& callback) {
204   message_callbacks_.insert(std::make_pair(message, callback));
205 }
206
207 void WebUIImpl::ProcessWebUIMessage(const GURL& source_url,
208                                     const std::string& message,
209                                     const base::ListValue& args) {
210   if (controller_->OverrideHandleWebUIMessage(source_url, message, args))
211     return;
212
213   // Look up the callback for this message.
214   MessageCallbackMap::const_iterator callback =
215       message_callbacks_.find(message);
216   if (callback != message_callbacks_.end()) {
217     // Forward this message and content on.
218     callback->second.Run(&args);
219   } else {
220     NOTREACHED() << "Unhandled chrome.send(\"" << message << "\");";
221   }
222 }
223
224 // WebUIImpl, protected: -------------------------------------------------------
225
226 void WebUIImpl::AddMessageHandler(WebUIMessageHandler* handler) {
227   DCHECK(!handler->web_ui());
228   handler->set_web_ui(this);
229   handler->RegisterMessages();
230   handlers_.push_back(handler);
231 }
232
233 void WebUIImpl::ExecuteJavascript(const string16& javascript) {
234   static_cast<RenderViewHostImpl*>(
235       web_contents_->GetRenderViewHost())->ExecuteJavascriptInWebFrame(
236       ASCIIToUTF16(frame_xpath_), javascript);
237 }
238
239 }  // namespace content