| Index: content/browser/renderer_host/render_widget_host_view_aura.cc
 | 
| diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
 | 
| index c33e325cef30eaab1a331b7c0dcf7f6d7f8f6166..864d41dc046ee8a54188b29b8839f9e18932fdad 100644
 | 
| --- a/content/browser/renderer_host/render_widget_host_view_aura.cc
 | 
| +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
 | 
| @@ -97,10 +97,13 @@
 | 
|  #include "ui/wm/public/window_types.h"
 | 
|  
 | 
|  #if defined(OS_WIN)
 | 
| +#include "base/time/time.h"
 | 
|  #include "content/browser/accessibility/browser_accessibility_manager_win.h"
 | 
|  #include "content/browser/accessibility/browser_accessibility_win.h"
 | 
|  #include "content/browser/renderer_host/legacy_render_widget_host_win.h"
 | 
|  #include "ui/base/win/hidden_window.h"
 | 
| +#include "ui/base/win/osk_display_manager.h"
 | 
| +#include "ui/base/win/osk_display_observer.h"
 | 
|  #include "ui/display/win/screen_win.h"
 | 
|  #include "ui/gfx/gdi_util.h"
 | 
|  #endif
 | 
| @@ -212,6 +215,87 @@ void MarkUnchangedTouchPointsAsStationary(
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +#if defined(OS_WIN)
 | 
| +// This class implements the ui::OnScreenKeyboardObserver interface
 | 
| +// which provides notifications about the on screen keyboard on Windows getting
 | 
| +// displayed or hidden in response to taps on editable fields.
 | 
| +// It provides functionality to request blink to scroll the input field if it
 | 
| +// is obscured by the on screen keyboard.
 | 
| +class WinScreenKeyboardObserver : public ui::OnScreenKeyboardObserver {
 | 
| + public:
 | 
| +  WinScreenKeyboardObserver(RenderWidgetHostImpl* host,
 | 
| +                            const gfx::Point& location_in_screen,
 | 
| +                            float scale_factor,
 | 
| +                            aura::Window* window)
 | 
| +      : host_(host),
 | 
| +        location_in_screen_(location_in_screen),
 | 
| +        device_scale_factor_(scale_factor),
 | 
| +        window_(window) {
 | 
| +    host_->GetView()->SetInsets(gfx::Insets());
 | 
| +  }
 | 
| +
 | 
| +  // base::win::OnScreenKeyboardObserver overrides.
 | 
| +  void OnKeyboardVisible(const gfx::Rect& keyboard_rect_pixels) override {
 | 
| +    gfx::Point location_in_pixels =
 | 
| +        gfx::ConvertPointToPixel(device_scale_factor_, location_in_screen_);
 | 
| +
 | 
| +    // Restore the viewport.
 | 
| +    host_->GetView()->SetInsets(gfx::Insets());
 | 
| +
 | 
| +    if (keyboard_rect_pixels.Contains(location_in_pixels)) {
 | 
| +      aura::client::ScreenPositionClient* screen_position_client =
 | 
| +          aura::client::GetScreenPositionClient(window_->GetRootWindow());
 | 
| +      if (!screen_position_client)
 | 
| +        return;
 | 
| +
 | 
| +      DVLOG(1) << "OSK covering focus point.";
 | 
| +      gfx::Rect keyboard_rect =
 | 
| +          gfx::ConvertRectToDIP(device_scale_factor_, keyboard_rect_pixels);
 | 
| +      gfx::Rect bounds_in_screen = window_->GetBoundsInScreen();
 | 
| +
 | 
| +      DCHECK(bounds_in_screen.bottom() > keyboard_rect.y());
 | 
| +
 | 
| +      // Set the viewport of the window to be just above the on screen
 | 
| +      // keyboard.
 | 
| +      int viewport_bottom = bounds_in_screen.bottom() - keyboard_rect.y();
 | 
| +
 | 
| +      // If the viewport is bigger than the view, then we cannot handle it
 | 
| +      // with the current approach. Moving the window above the OSK is one way.
 | 
| +      // That for a later patchset.
 | 
| +      if (viewport_bottom > bounds_in_screen.height())
 | 
| +        return;
 | 
| +
 | 
| +      host_->GetView()->SetInsets(gfx::Insets(0, 0, viewport_bottom, 0));
 | 
| +
 | 
| +      gfx::Point origin(location_in_screen_);
 | 
| +      screen_position_client->ConvertPointFromScreen(window_, &origin);
 | 
| +
 | 
| +      // We want to scroll the node into a rectangle which originates from
 | 
| +      // the touch point and a small offset (10) in either direction.
 | 
| +      gfx::Rect node_rect(origin.x(), origin.y(), 10, 10);
 | 
| +      host_->ScrollFocusedEditableNodeIntoRect(node_rect);
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  void OnKeyboardHidden(const gfx::Rect& keyboard_rect_pixels) override {
 | 
| +    // Restore the viewport.
 | 
| +    host_->GetView()->SetInsets(gfx::Insets());
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  RenderWidgetHostImpl* host_;
 | 
| +  // The location in DIPs where the touch occurred.
 | 
| +  gfx::Point location_in_screen_;
 | 
| +  // The current device scale factor.
 | 
| +  float device_scale_factor_;
 | 
| +
 | 
| +  // The content Window.
 | 
| +  aura::Window* window_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(WinScreenKeyboardObserver);
 | 
| +};
 | 
| +#endif
 | 
| +
 | 
|  }  // namespace
 | 
|  
 | 
|  // We need to watch for mouse events outside a Web Popup or its parent
 | 
| @@ -383,6 +467,7 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host,
 | 
|  #if defined(OS_WIN)
 | 
|        legacy_render_widget_host_HWND_(nullptr),
 | 
|        legacy_window_destroyed_(false),
 | 
| +      virtual_keyboard_requested_(false),
 | 
|  #endif
 | 
|        has_snapped_to_boundary_(false),
 | 
|        is_guest_view_hack_(is_guest_view_hack),
 | 
| @@ -864,6 +949,29 @@ void RenderWidgetHostViewAura::SetInsets(const gfx::Insets& insets) {
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +void RenderWidgetHostViewAura::FocusedNodeTouched(
 | 
| +    const gfx::Point& location_dips_screen,
 | 
| +    bool editable) {
 | 
| +#if defined(OS_WIN)
 | 
| +  RenderViewHost* rvh = RenderViewHost::From(host_);
 | 
| +  if (rvh && rvh->GetDelegate())
 | 
| +    rvh->GetDelegate()->SetIsVirtualKeyboardRequested(editable);
 | 
| +
 | 
| +  ui::OnScreenKeyboardDisplayManager* osk_display_manager =
 | 
| +      ui::OnScreenKeyboardDisplayManager::GetInstance();
 | 
| +  DCHECK(osk_display_manager);
 | 
| +  if (editable && host_ && host_->GetView()) {
 | 
| +    keyboard_observer_.reset(new WinScreenKeyboardObserver(
 | 
| +        host_, location_dips_screen, device_scale_factor_, window_));
 | 
| +    virtual_keyboard_requested_ =
 | 
| +        osk_display_manager->DisplayVirtualKeyboard(keyboard_observer_.get());
 | 
| +  } else {
 | 
| +    virtual_keyboard_requested_ = false;
 | 
| +    osk_display_manager->DismissVirtualKeyboard();
 | 
| +  }
 | 
| +#endif
 | 
| +}
 | 
| +
 | 
|  void RenderWidgetHostViewAura::UpdateCursor(const WebCursor& cursor) {
 | 
|    current_cursor_ = cursor;
 | 
|    const display::Display display =
 | 
| @@ -2003,6 +2111,21 @@ void RenderWidgetHostViewAura::TransformPointToLocalCoordSpace(
 | 
|        gfx::ConvertPointToDIP(device_scale_factor_, *transformed_point);
 | 
|  }
 | 
|  
 | 
| +void RenderWidgetHostViewAura::FocusedNodeChanged(bool editable) {
 | 
| +#if defined(OS_WIN)
 | 
| +  if (!editable && virtual_keyboard_requested_) {
 | 
| +    virtual_keyboard_requested_ = false;
 | 
| +
 | 
| +    RenderViewHost* rvh = RenderViewHost::From(host_);
 | 
| +    if (rvh && rvh->GetDelegate())
 | 
| +      rvh->GetDelegate()->SetIsVirtualKeyboardRequested(false);
 | 
| +
 | 
| +    DCHECK(ui::OnScreenKeyboardDisplayManager::GetInstance());
 | 
| +    ui::OnScreenKeyboardDisplayManager::GetInstance()->DismissVirtualKeyboard();
 | 
| +  }
 | 
| +#endif
 | 
| +}
 | 
| +
 | 
|  void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) {
 | 
|    TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnScrollEvent");
 | 
|  
 | 
| @@ -2286,6 +2409,14 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
 | 
|    // RenderWidgetHostViewAura::OnWindowDestroying and the pointer should
 | 
|    // be set to NULL.
 | 
|    DCHECK(!legacy_render_widget_host_HWND_);
 | 
| +  if (virtual_keyboard_requested_) {
 | 
| +    DCHECK(keyboard_observer_.get());
 | 
| +    ui::OnScreenKeyboardDisplayManager* osk_display_manager =
 | 
| +        ui::OnScreenKeyboardDisplayManager::GetInstance();
 | 
| +    DCHECK(osk_display_manager);
 | 
| +    osk_display_manager->RemoveObserver(keyboard_observer_.get());
 | 
| +  }
 | 
| +
 | 
|  #endif
 | 
|  }
 | 
|  
 | 
| 
 |