1 // Copyright (c) 2013 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 "ui/keyboard/keyboard_controller_proxy.h"
6
7 #include "base/values.h"
8 #include "content/public/browser/site_instance.h"
9 #include "content/public/browser/web_contents.h"
10 #include "content/public/browser/web_contents.h"
11 #include "content/public/browser/web_contents_delegate.h"
12 #include "content/public/browser/web_contents_observer.h"
13 #include "content/public/browser/web_contents_view.h"
14 #include "content/public/browser/web_ui.h"
15 #include "content/public/common/bindings_policy.h"
16 #include "ui/aura/layout_manager.h"
17 #include "ui/aura/window.h"
18 #include "ui/keyboard/keyboard_constants.h"
19
20 namespace {
21
22 // Converts ui::TextInputType to string.
TextInputTypeToString(ui::TextInputType type)23 std::string TextInputTypeToString(ui::TextInputType type) {
24 switch (type) {
25 case ui::TEXT_INPUT_TYPE_NONE:
26 return "none";
27 case ui::TEXT_INPUT_TYPE_PASSWORD:
28 return "password";
29 case ui::TEXT_INPUT_TYPE_EMAIL:
30 return "email";
31 case ui::TEXT_INPUT_TYPE_NUMBER:
32 return "number";
33 case ui::TEXT_INPUT_TYPE_TELEPHONE:
34 return "tel";
35 case ui::TEXT_INPUT_TYPE_URL:
36 return "url";
37 case ui::TEXT_INPUT_TYPE_DATE:
38 return "date";
39 case ui::TEXT_INPUT_TYPE_TEXT:
40 case ui::TEXT_INPUT_TYPE_SEARCH:
41 case ui::TEXT_INPUT_TYPE_DATE_TIME:
42 case ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL:
43 case ui::TEXT_INPUT_TYPE_MONTH:
44 case ui::TEXT_INPUT_TYPE_TIME:
45 case ui::TEXT_INPUT_TYPE_WEEK:
46 case ui::TEXT_INPUT_TYPE_TEXT_AREA:
47 case ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE:
48 case ui::TEXT_INPUT_TYPE_DATE_TIME_FIELD:
49 return "text";
50 }
51 NOTREACHED();
52 return "";
53 }
54
55 // The WebContentsDelegate for the keyboard.
56 // The delegate deletes itself when the keyboard is destroyed.
57 class KeyboardContentsDelegate : public content::WebContentsDelegate,
58 public content::WebContentsObserver {
59 public:
KeyboardContentsDelegate(keyboard::KeyboardControllerProxy * proxy)60 KeyboardContentsDelegate(keyboard::KeyboardControllerProxy* proxy)
61 : proxy_(proxy) {}
~KeyboardContentsDelegate()62 virtual ~KeyboardContentsDelegate() {}
63
64 private:
65 // Overridden from content::WebContentsDelegate:
OpenURLFromTab(content::WebContents * source,const content::OpenURLParams & params)66 virtual content::WebContents* OpenURLFromTab(
67 content::WebContents* source,
68 const content::OpenURLParams& params) OVERRIDE {
69 source->GetController().LoadURL(
70 params.url, params.referrer, params.transition, params.extra_headers);
71 Observe(source);
72 return source;
73 }
74
IsPopupOrPanel(const content::WebContents * source) const75 virtual bool IsPopupOrPanel(
76 const content::WebContents* source) const OVERRIDE {
77 return true;
78 }
79
MoveContents(content::WebContents * source,const gfx::Rect & pos)80 virtual void MoveContents(content::WebContents* source,
81 const gfx::Rect& pos) OVERRIDE {
82 aura::Window* keyboard = proxy_->GetKeyboardWindow();
83 gfx::Rect bounds = keyboard->bounds();
84 int new_height = pos.height();
85 bounds.set_y(bounds.y() + bounds.height() - new_height);
86 bounds.set_height(new_height);
87 proxy_->set_resizing_from_contents(true);
88 keyboard->SetBounds(bounds);
89 proxy_->set_resizing_from_contents(false);
90 }
91
92 // Overridden from content::WebContentsDelegate:
RequestMediaAccessPermission(content::WebContents * web_contents,const content::MediaStreamRequest & request,const content::MediaResponseCallback & callback)93 virtual void RequestMediaAccessPermission(content::WebContents* web_contents,
94 const content::MediaStreamRequest& request,
95 const content::MediaResponseCallback& callback) OVERRIDE {
96 proxy_->RequestAudioInput(web_contents, request, callback);
97 }
98
99
100 // Overridden from content::WebContentsObserver:
WebContentsDestroyed(content::WebContents * contents)101 virtual void WebContentsDestroyed(content::WebContents* contents) OVERRIDE {
102 delete this;
103 }
104
105 keyboard::KeyboardControllerProxy* proxy_;
106
107 DISALLOW_COPY_AND_ASSIGN(KeyboardContentsDelegate);
108 };
109
110 } // namespace
111
112 namespace keyboard {
113
KeyboardControllerProxy()114 KeyboardControllerProxy::KeyboardControllerProxy()
115 : default_url_(kKeyboardWebUIURL), resizing_from_contents_(false) {
116 }
117
~KeyboardControllerProxy()118 KeyboardControllerProxy::~KeyboardControllerProxy() {
119 }
120
GetValidUrl()121 const GURL& KeyboardControllerProxy::GetValidUrl() {
122 return override_url_.is_valid() ? override_url_ : default_url_;
123 }
124
SetOverrideContentUrl(const GURL & url)125 void KeyboardControllerProxy::SetOverrideContentUrl(const GURL& url) {
126 if (override_url_ == url)
127 return;
128
129 override_url_ = url;
130 // Restores the keyboard window size to default.
131 aura::Window* container = GetKeyboardWindow()->parent();
132 CHECK(container);
133 container->layout_manager()->OnWindowResized();
134
135 ReloadContents();
136 }
137
ReloadContents()138 void KeyboardControllerProxy::ReloadContents() {
139 if (keyboard_contents_) {
140 content::OpenURLParams params(
141 GetValidUrl(),
142 content::Referrer(),
143 SINGLETON_TAB,
144 content::PAGE_TRANSITION_AUTO_TOPLEVEL,
145 false);
146 keyboard_contents_->OpenURL(params);
147 }
148 }
149
GetKeyboardWindow()150 aura::Window* KeyboardControllerProxy::GetKeyboardWindow() {
151 if (!keyboard_contents_) {
152 content::BrowserContext* context = GetBrowserContext();
153 keyboard_contents_.reset(content::WebContents::Create(
154 content::WebContents::CreateParams(context,
155 content::SiteInstance::CreateForURL(context, GetValidUrl()))));
156 keyboard_contents_->SetDelegate(new KeyboardContentsDelegate(this));
157 SetupWebContents(keyboard_contents_.get());
158 ReloadContents();
159 }
160
161 return keyboard_contents_->GetView()->GetNativeView();
162 }
163
ShowKeyboardContainer(aura::Window * container)164 void KeyboardControllerProxy::ShowKeyboardContainer(aura::Window* container) {
165 GetKeyboardWindow()->Show();
166 container->Show();
167 }
168
HideKeyboardContainer(aura::Window * container)169 void KeyboardControllerProxy::HideKeyboardContainer(aura::Window* container) {
170 container->Hide();
171 GetKeyboardWindow()->Hide();
172 }
173
SetUpdateInputType(ui::TextInputType type)174 void KeyboardControllerProxy::SetUpdateInputType(ui::TextInputType type) {
175 content::WebUI* webui = keyboard_contents_ ?
176 keyboard_contents_->GetCommittedWebUI() : NULL;
177
178 if (webui &&
179 (0 != (webui->GetBindings() & content::BINDINGS_POLICY_WEB_UI))) {
180 // Only call OnTextInputBoxFocused function if it is a web ui keyboard,
181 // not an extension based keyboard.
182 base::DictionaryValue input_context;
183 input_context.SetString("type", TextInputTypeToString(type));
184 webui->CallJavascriptFunction("OnTextInputBoxFocused", input_context);
185 }
186 }
187
SetupWebContents(content::WebContents * contents)188 void KeyboardControllerProxy::SetupWebContents(content::WebContents* contents) {
189 }
190
191 } // namespace keyboard
192