// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/keyboard/keyboard_controller_proxy.h" #include "base/values.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_view.h" #include "content/public/browser/web_ui.h" #include "content/public/common/bindings_policy.h" #include "ui/aura/layout_manager.h" #include "ui/aura/window.h" #include "ui/keyboard/keyboard_constants.h" namespace { // Converts ui::TextInputType to string. std::string TextInputTypeToString(ui::TextInputType type) { switch (type) { case ui::TEXT_INPUT_TYPE_NONE: return "none"; case ui::TEXT_INPUT_TYPE_PASSWORD: return "password"; case ui::TEXT_INPUT_TYPE_EMAIL: return "email"; case ui::TEXT_INPUT_TYPE_NUMBER: return "number"; case ui::TEXT_INPUT_TYPE_TELEPHONE: return "tel"; case ui::TEXT_INPUT_TYPE_URL: return "url"; case ui::TEXT_INPUT_TYPE_DATE: return "date"; case ui::TEXT_INPUT_TYPE_TEXT: case ui::TEXT_INPUT_TYPE_SEARCH: case ui::TEXT_INPUT_TYPE_DATE_TIME: case ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL: case ui::TEXT_INPUT_TYPE_MONTH: case ui::TEXT_INPUT_TYPE_TIME: case ui::TEXT_INPUT_TYPE_WEEK: case ui::TEXT_INPUT_TYPE_TEXT_AREA: case ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE: case ui::TEXT_INPUT_TYPE_DATE_TIME_FIELD: return "text"; } NOTREACHED(); return ""; } // The WebContentsDelegate for the keyboard. // The delegate deletes itself when the keyboard is destroyed. class KeyboardContentsDelegate : public content::WebContentsDelegate, public content::WebContentsObserver { public: KeyboardContentsDelegate(keyboard::KeyboardControllerProxy* proxy) : proxy_(proxy) {} virtual ~KeyboardContentsDelegate() {} private: // Overridden from content::WebContentsDelegate: virtual content::WebContents* OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) OVERRIDE { source->GetController().LoadURL( params.url, params.referrer, params.transition, params.extra_headers); Observe(source); return source; } virtual bool IsPopupOrPanel( const content::WebContents* source) const OVERRIDE { return true; } virtual void MoveContents(content::WebContents* source, const gfx::Rect& pos) OVERRIDE { aura::Window* keyboard = proxy_->GetKeyboardWindow(); gfx::Rect bounds = keyboard->bounds(); int new_height = pos.height(); bounds.set_y(bounds.y() + bounds.height() - new_height); bounds.set_height(new_height); proxy_->set_resizing_from_contents(true); keyboard->SetBounds(bounds); proxy_->set_resizing_from_contents(false); } // Overridden from content::WebContentsDelegate: virtual void RequestMediaAccessPermission(content::WebContents* web_contents, const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) OVERRIDE { proxy_->RequestAudioInput(web_contents, request, callback); } // Overridden from content::WebContentsObserver: virtual void WebContentsDestroyed(content::WebContents* contents) OVERRIDE { delete this; } keyboard::KeyboardControllerProxy* proxy_; DISALLOW_COPY_AND_ASSIGN(KeyboardContentsDelegate); }; } // namespace namespace keyboard { KeyboardControllerProxy::KeyboardControllerProxy() : default_url_(kKeyboardWebUIURL), resizing_from_contents_(false) { } KeyboardControllerProxy::~KeyboardControllerProxy() { } const GURL& KeyboardControllerProxy::GetValidUrl() { return override_url_.is_valid() ? override_url_ : default_url_; } void KeyboardControllerProxy::SetOverrideContentUrl(const GURL& url) { if (override_url_ == url) return; override_url_ = url; // Restores the keyboard window size to default. aura::Window* container = GetKeyboardWindow()->parent(); CHECK(container); container->layout_manager()->OnWindowResized(); ReloadContents(); } void KeyboardControllerProxy::ReloadContents() { if (keyboard_contents_) { content::OpenURLParams params( GetValidUrl(), content::Referrer(), SINGLETON_TAB, content::PAGE_TRANSITION_AUTO_TOPLEVEL, false); keyboard_contents_->OpenURL(params); } } aura::Window* KeyboardControllerProxy::GetKeyboardWindow() { if (!keyboard_contents_) { content::BrowserContext* context = GetBrowserContext(); keyboard_contents_.reset(content::WebContents::Create( content::WebContents::CreateParams(context, content::SiteInstance::CreateForURL(context, GetValidUrl())))); keyboard_contents_->SetDelegate(new KeyboardContentsDelegate(this)); SetupWebContents(keyboard_contents_.get()); ReloadContents(); } return keyboard_contents_->GetView()->GetNativeView(); } void KeyboardControllerProxy::ShowKeyboardContainer(aura::Window* container) { GetKeyboardWindow()->Show(); container->Show(); } void KeyboardControllerProxy::HideKeyboardContainer(aura::Window* container) { container->Hide(); GetKeyboardWindow()->Hide(); } void KeyboardControllerProxy::SetUpdateInputType(ui::TextInputType type) { content::WebUI* webui = keyboard_contents_ ? keyboard_contents_->GetCommittedWebUI() : NULL; if (webui && (0 != (webui->GetBindings() & content::BINDINGS_POLICY_WEB_UI))) { // Only call OnTextInputBoxFocused function if it is a web ui keyboard, // not an extension based keyboard. base::DictionaryValue input_context; input_context.SetString("type", TextInputTypeToString(type)); webui->CallJavascriptFunction("OnTextInputBoxFocused", input_context); } } void KeyboardControllerProxy::SetupWebContents(content::WebContents* contents) { } } // namespace keyboard