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. 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: 60 KeyboardContentsDelegate(keyboard::KeyboardControllerProxy* proxy) 61 : proxy_(proxy) {} 62 virtual ~KeyboardContentsDelegate() {} 63 64 private: 65 // Overridden from content::WebContentsDelegate: 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 75 virtual bool IsPopupOrPanel( 76 const content::WebContents* source) const OVERRIDE { 77 return true; 78 } 79 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: 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: 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 114 KeyboardControllerProxy::KeyboardControllerProxy() 115 : default_url_(kKeyboardWebUIURL), resizing_from_contents_(false) { 116 } 117 118 KeyboardControllerProxy::~KeyboardControllerProxy() { 119 } 120 121 const GURL& KeyboardControllerProxy::GetValidUrl() { 122 return override_url_.is_valid() ? override_url_ : default_url_; 123 } 124 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 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 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 164 void KeyboardControllerProxy::ShowKeyboardContainer(aura::Window* container) { 165 GetKeyboardWindow()->Show(); 166 container->Show(); 167 } 168 169 void KeyboardControllerProxy::HideKeyboardContainer(aura::Window* container) { 170 container->Hide(); 171 GetKeyboardWindow()->Hide(); 172 } 173 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 188 void KeyboardControllerProxy::SetupWebContents(content::WebContents* contents) { 189 } 190 191 } // namespace keyboard 192