Home | History | Annotate | Download | only in keyboard
      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