// Copyright (c) 2012 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 "content/browser/web_contents/web_contents_view_aura.h"

#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/metrics/histogram.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/download/drag_download_util.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/renderer_host/dip_util.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/renderer_host/web_input_event_aura.h"
#include "content/browser/web_contents/aura/gesture_nav_simple.h"
#include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
#include "content/browser/web_contents/aura/shadow_layer_delegate.h"
#include "content/browser/web_contents/aura/window_slider.h"
#include "content/browser/web_contents/touch_editable_impl_aura.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/overscroll_configuration.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_view_delegate.h"
#include "content/public/browser/web_drag_dest_delegate.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/drop_data.h"
#include "net/base/filename_util.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/client/window_tree_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/aura/window_tree_host.h"
#include "ui/aura/window_tree_host_observer.h"
#include "ui/aura_extra/image_window_delegate.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/drag_utils.h"
#include "ui/base/dragdrop/drop_target_event.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/hit_test.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_png_rep.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/screen.h"
#include "ui/wm/public/drag_drop_client.h"
#include "ui/wm/public/drag_drop_delegate.h"

namespace content {
WebContentsView* CreateWebContentsView(
    WebContentsImpl* web_contents,
    WebContentsViewDelegate* delegate,
    RenderViewHostDelegateView** render_view_host_delegate_view) {
  WebContentsViewAura* rv = new WebContentsViewAura(web_contents, delegate);
  *render_view_host_delegate_view = rv;
  return rv;
}

namespace {

bool IsScrollEndEffectEnabled() {
  return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
      switches::kScrollEndEffect) == "1";
}

bool ShouldNavigateForward(const NavigationController& controller,
                           OverscrollMode mode) {
  return mode == (base::i18n::IsRTL() ? OVERSCROLL_EAST : OVERSCROLL_WEST) &&
         controller.CanGoForward();
}

bool ShouldNavigateBack(const NavigationController& controller,
                        OverscrollMode mode) {
  return mode == (base::i18n::IsRTL() ? OVERSCROLL_WEST : OVERSCROLL_EAST) &&
         controller.CanGoBack();
}

RenderWidgetHostViewAura* ToRenderWidgetHostViewAura(
    RenderWidgetHostView* view) {
  if (!view || RenderViewHostFactory::has_factory())
    return NULL;  // Can't cast to RenderWidgetHostViewAura in unit tests.

  RenderViewHost* rvh = RenderViewHost::From(view->GetRenderWidgetHost());
  WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
      rvh ? WebContents::FromRenderViewHost(rvh) : NULL);
  if (BrowserPluginGuest::IsGuest(web_contents))
    return NULL;
  return static_cast<RenderWidgetHostViewAura*>(view);
}

// The window delegate for the overscroll window. This redirects trackpad events
// to the web-contents window. The delegate destroys itself when the window is
// destroyed.
class OverscrollWindowDelegate : public aura_extra::ImageWindowDelegate {
 public:
  OverscrollWindowDelegate(WebContentsImpl* web_contents,
                           OverscrollMode overscroll_mode)
      : web_contents_(web_contents),
        forward_events_(true) {
    const NavigationControllerImpl& controller = web_contents->GetController();
    const NavigationEntryImpl* entry = NULL;
    if (ShouldNavigateForward(controller, overscroll_mode)) {
      entry = controller.GetEntryAtOffset(1);
    } else if (ShouldNavigateBack(controller, overscroll_mode)) {
      entry = controller.GetEntryAtOffset(-1);
    }

    gfx::Image image;
    if (entry && entry->screenshot().get()) {
      std::vector<gfx::ImagePNGRep> image_reps;
      image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(), 1.0f));
      image = gfx::Image(image_reps);
    }
    SetImage(image);
  }

  void stop_forwarding_events() { forward_events_ = false; }

 private:
  ~OverscrollWindowDelegate() override {}

  aura::Window* web_contents_window() {
    return web_contents_->GetView()->GetContentNativeView();
  }

  // Overridden from ui::EventHandler.
  void OnScrollEvent(ui::ScrollEvent* event) override {
    if (forward_events_ && web_contents_window())
      web_contents_window()->delegate()->OnScrollEvent(event);
  }

  void OnGestureEvent(ui::GestureEvent* event) override {
    if (forward_events_ && web_contents_window())
      web_contents_window()->delegate()->OnGestureEvent(event);
  }

  WebContentsImpl* web_contents_;

  // The window is displayed both during the gesture, and after the gesture
  // while the navigation is in progress. During the gesture, it is necessary to
  // forward input events to the content page (e.g. when the overscroll window
  // slides under the cursor and starts receiving scroll events). However, once
  // the gesture is complete, and the window is being displayed as an overlay
  // window during navigation, events should not be forwarded anymore.
  bool forward_events_;

  DISALLOW_COPY_AND_ASSIGN(OverscrollWindowDelegate);
};

// Listens to all mouse drag events during a drag and drop and sends them to
// the renderer.
class WebDragSourceAura : public NotificationObserver {
 public:
  WebDragSourceAura(aura::Window* window, WebContentsImpl* contents)
      : window_(window),
        contents_(contents) {
    registrar_.Add(this,
                   NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
                   Source<WebContents>(contents));
  }

  ~WebDragSourceAura() override {}

  // NotificationObserver:
  void Observe(int type,
               const NotificationSource& source,
               const NotificationDetails& details) override {
    if (type != NOTIFICATION_WEB_CONTENTS_DISCONNECTED)
      return;

    // Cancel the drag if it is still in progress.
    aura::client::DragDropClient* dnd_client =
        aura::client::GetDragDropClient(window_->GetRootWindow());
    if (dnd_client && dnd_client->IsDragDropInProgress())
      dnd_client->DragCancel();

    window_ = NULL;
    contents_ = NULL;
  }

  aura::Window* window() const { return window_; }

 private:
  aura::Window* window_;
  WebContentsImpl* contents_;
  NotificationRegistrar registrar_;

  DISALLOW_COPY_AND_ASSIGN(WebDragSourceAura);
};

#if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN)
// Fill out the OSExchangeData with a file contents, synthesizing a name if
// necessary.
void PrepareDragForFileContents(const DropData& drop_data,
                                ui::OSExchangeData::Provider* provider) {
  base::FilePath file_name =
      base::FilePath::FromUTF16Unsafe(drop_data.file_description_filename);
  // Images without ALT text will only have a file extension so we need to
  // synthesize one from the provided extension and URL.
  if (file_name.BaseName().RemoveExtension().empty()) {
    const base::FilePath::StringType extension = file_name.Extension();
    // Retrieve the name from the URL.
    file_name = net::GenerateFileName(drop_data.url, "", "", "", "", "")
                    .ReplaceExtension(extension);
  }
  provider->SetFileContents(file_name, drop_data.file_contents);
}
#endif

#if defined(OS_WIN)
void PrepareDragForDownload(
    const DropData& drop_data,
    ui::OSExchangeData::Provider* provider,
    WebContentsImpl* web_contents) {
  const GURL& page_url = web_contents->GetLastCommittedURL();
  const std::string& page_encoding = web_contents->GetEncoding();

  // Parse the download metadata.
  base::string16 mime_type;
  base::FilePath file_name;
  GURL download_url;
  if (!ParseDownloadMetadata(drop_data.download_metadata,
                             &mime_type,
                             &file_name,
                             &download_url))
    return;

  // Generate the file name based on both mime type and proposed file name.
  std::string default_name =
      GetContentClient()->browser()->GetDefaultDownloadName();
  base::FilePath generated_download_file_name =
      net::GenerateFileName(download_url,
                            std::string(),
                            std::string(),
                            base::UTF16ToUTF8(file_name.value()),
                            base::UTF16ToUTF8(mime_type),
                            default_name);

  // http://crbug.com/332579
  base::ThreadRestrictions::ScopedAllowIO allow_file_operations;

  base::FilePath temp_dir_path;
  if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_drag"),
                                    &temp_dir_path))
    return;

  base::FilePath download_path =
      temp_dir_path.Append(generated_download_file_name);

  // We cannot know when the target application will be done using the temporary
  // file, so schedule it to be deleted after rebooting.
  base::DeleteFileAfterReboot(download_path);
  base::DeleteFileAfterReboot(temp_dir_path);

  // Provide the data as file (CF_HDROP). A temporary download file with the
  // Zone.Identifier ADS (Alternate Data Stream) attached will be created.
  scoped_refptr<DragDownloadFile> download_file =
      new DragDownloadFile(
          download_path,
          base::File(),
          download_url,
          Referrer(page_url, drop_data.referrer_policy),
          page_encoding,
          web_contents);
  ui::OSExchangeData::DownloadFileInfo file_download(base::FilePath(),
                                                     download_file.get());
  provider->SetDownloadFileInfo(file_download);
}
#endif  // defined(OS_WIN)

// Returns the CustomFormat to store file system files.
const ui::OSExchangeData::CustomFormat& GetFileSystemFileCustomFormat() {
  static const char kFormatString[] = "chromium/x-file-system-files";
  CR_DEFINE_STATIC_LOCAL(ui::OSExchangeData::CustomFormat,
                         format,
                         (ui::Clipboard::GetFormatType(kFormatString)));
  return format;
}

// Writes file system files to the pickle.
void WriteFileSystemFilesToPickle(
    const std::vector<DropData::FileSystemFileInfo>& file_system_files,
    Pickle* pickle) {
  pickle->WriteSizeT(file_system_files.size());
  for (size_t i = 0; i < file_system_files.size(); ++i) {
    pickle->WriteString(file_system_files[i].url.spec());
    pickle->WriteInt64(file_system_files[i].size);
  }
}

// Reads file system files from the pickle.
bool ReadFileSystemFilesFromPickle(
    const Pickle& pickle,
    std::vector<DropData::FileSystemFileInfo>* file_system_files) {
  PickleIterator iter(pickle);

  size_t num_files = 0;
  if (!iter.ReadSizeT(&num_files))
    return false;
  file_system_files->resize(num_files);

  for (size_t i = 0; i < num_files; ++i) {
    std::string url_string;
    int64 size = 0;
    if (!iter.ReadString(&url_string) || !iter.ReadInt64(&size))
      return false;

    GURL url(url_string);
    if (!url.is_valid())
      return false;

    (*file_system_files)[i].url = url;
    (*file_system_files)[i].size = size;
  }
  return true;
}

// Utility to fill a ui::OSExchangeDataProvider object from DropData.
void PrepareDragData(const DropData& drop_data,
                     ui::OSExchangeData::Provider* provider,
                     WebContentsImpl* web_contents) {
  provider->MarkOriginatedFromRenderer();
#if defined(OS_WIN)
  // Put download before file contents to prefer the download of a image over
  // its thumbnail link.
  if (!drop_data.download_metadata.empty())
    PrepareDragForDownload(drop_data, provider, web_contents);
#endif
#if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN)
  // We set the file contents before the URL because the URL also sets file
  // contents (to a .URL shortcut).  We want to prefer file content data over
  // a shortcut so we add it first.
  if (!drop_data.file_contents.empty())
    PrepareDragForFileContents(drop_data, provider);
#endif
  // Call SetString() before SetURL() when we actually have a custom string.
  // SetURL() will itself do SetString() when a string hasn't been set yet,
  // but we want to prefer drop_data.text.string() over the URL string if it
  // exists.
  if (!drop_data.text.string().empty())
    provider->SetString(drop_data.text.string());
  if (drop_data.url.is_valid())
    provider->SetURL(drop_data.url, drop_data.url_title);
  if (!drop_data.html.string().empty())
    provider->SetHtml(drop_data.html.string(), drop_data.html_base_url);
  if (!drop_data.filenames.empty())
    provider->SetFilenames(drop_data.filenames);
  if (!drop_data.file_system_files.empty()) {
    Pickle pickle;
    WriteFileSystemFilesToPickle(drop_data.file_system_files, &pickle);
    provider->SetPickledData(GetFileSystemFileCustomFormat(), pickle);
  }
  if (!drop_data.custom_data.empty()) {
    Pickle pickle;
    ui::WriteCustomDataToPickle(drop_data.custom_data, &pickle);
    provider->SetPickledData(ui::Clipboard::GetWebCustomDataFormatType(),
                             pickle);
  }
}

// Utility to fill a DropData object from ui::OSExchangeData.
void PrepareDropData(DropData* drop_data, const ui::OSExchangeData& data) {
  drop_data->did_originate_from_renderer = data.DidOriginateFromRenderer();

  base::string16 plain_text;
  data.GetString(&plain_text);
  if (!plain_text.empty())
    drop_data->text = base::NullableString16(plain_text, false);

  GURL url;
  base::string16 url_title;
  data.GetURLAndTitle(
      ui::OSExchangeData::DO_NOT_CONVERT_FILENAMES, &url, &url_title);
  if (url.is_valid()) {
    drop_data->url = url;
    drop_data->url_title = url_title;
  }

  base::string16 html;
  GURL html_base_url;
  data.GetHtml(&html, &html_base_url);
  if (!html.empty())
    drop_data->html = base::NullableString16(html, false);
  if (html_base_url.is_valid())
    drop_data->html_base_url = html_base_url;

  data.GetFilenames(&drop_data->filenames);

  Pickle pickle;
  std::vector<DropData::FileSystemFileInfo> file_system_files;
  if (data.GetPickledData(GetFileSystemFileCustomFormat(), &pickle) &&
      ReadFileSystemFilesFromPickle(pickle, &file_system_files))
    drop_data->file_system_files = file_system_files;

  if (data.GetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), &pickle))
    ui::ReadCustomDataIntoMap(
        pickle.data(), pickle.size(), &drop_data->custom_data);
}

// Utilities to convert between blink::WebDragOperationsMask and
// ui::DragDropTypes.
int ConvertFromWeb(blink::WebDragOperationsMask ops) {
  int drag_op = ui::DragDropTypes::DRAG_NONE;
  if (ops & blink::WebDragOperationCopy)
    drag_op |= ui::DragDropTypes::DRAG_COPY;
  if (ops & blink::WebDragOperationMove)
    drag_op |= ui::DragDropTypes::DRAG_MOVE;
  if (ops & blink::WebDragOperationLink)
    drag_op |= ui::DragDropTypes::DRAG_LINK;
  return drag_op;
}

blink::WebDragOperationsMask ConvertToWeb(int drag_op) {
  int web_drag_op = blink::WebDragOperationNone;
  if (drag_op & ui::DragDropTypes::DRAG_COPY)
    web_drag_op |= blink::WebDragOperationCopy;
  if (drag_op & ui::DragDropTypes::DRAG_MOVE)
    web_drag_op |= blink::WebDragOperationMove;
  if (drag_op & ui::DragDropTypes::DRAG_LINK)
    web_drag_op |= blink::WebDragOperationLink;
  return (blink::WebDragOperationsMask) web_drag_op;
}

int ConvertAuraEventFlagsToWebInputEventModifiers(int aura_event_flags) {
  int web_input_event_modifiers = 0;
  if (aura_event_flags & ui::EF_SHIFT_DOWN)
    web_input_event_modifiers |= blink::WebInputEvent::ShiftKey;
  if (aura_event_flags & ui::EF_CONTROL_DOWN)
    web_input_event_modifiers |= blink::WebInputEvent::ControlKey;
  if (aura_event_flags & ui::EF_ALT_DOWN)
    web_input_event_modifiers |= blink::WebInputEvent::AltKey;
  if (aura_event_flags & ui::EF_COMMAND_DOWN)
    web_input_event_modifiers |= blink::WebInputEvent::MetaKey;
  return web_input_event_modifiers;
}

}  // namespace

class WebContentsViewAura::WindowObserver
    : public aura::WindowObserver, public aura::WindowTreeHostObserver {
 public:
  explicit WindowObserver(WebContentsViewAura* view)
      : view_(view),
        host_window_(NULL) {
    view_->window_->AddObserver(this);

#if defined(OS_WIN)
    if (view_->window_->GetRootWindow())
      view_->window_->GetRootWindow()->AddObserver(this);
#endif
  }

  ~WindowObserver() override {
    view_->window_->RemoveObserver(this);
    if (view_->window_->GetHost())
      view_->window_->GetHost()->RemoveObserver(this);
    if (host_window_)
      host_window_->RemoveObserver(this);
#if defined(OS_WIN)
    if (host_window_) {
      const aura::Window::Windows& children = host_window_->children();
      for (size_t i = 0; i < children.size(); ++i)
        children[i]->RemoveObserver(this);
    }

    aura::Window* root_window = view_->window_->GetRootWindow();
    if (root_window) {
      root_window->RemoveObserver(this);
      const aura::Window::Windows& root_children = root_window->children();
      for (size_t i = 0; i < root_children.size(); ++i)
        root_children[i]->RemoveObserver(this);
    }
#endif
  }

  // Overridden from aura::WindowObserver:
  void OnWindowHierarchyChanged(
      const aura::WindowObserver::HierarchyChangeParams& params) override {
    if (params.receiver != view_->window_.get() ||
        !params.target->Contains(view_->window_.get())) {
      return;
    }

    // Use the new parent's root window for calculating HiDPI subpixel offset.
    RenderWidgetHostViewAura* rwhv = ToRenderWidgetHostViewAura(
        view_->web_contents_->GetRenderWidgetHostView());
    if (rwhv)
      rwhv->SnapToPhysicalPixelBoundary();
  }

#if defined(OS_WIN)
  // Constrained windows are added as children of the parent's parent's view
  // which may overlap with windowed NPAPI plugins. In that case, tell the RWHV
  // so that it can update the plugins' cutout rects accordingly.
  // Note: this is hard coding how Chrome layer adds its dialogs. Since NPAPI is
  // going to be deprecated in a year, this is ok for now. The test for this is
  // PrintPreviewTest.WindowedNPAPIPluginHidden.
  virtual void OnWindowAdded(aura::Window* new_window) override {
    if (!new_window->Contains(view_->window_.get())) {
      // Skip the case when the parent moves to the root window.
      if (new_window != host_window_) {
        // Observe sibling windows of the WebContents, or children of the root
        // window.
        if (new_window->parent() == host_window_ ||
            new_window->parent() == view_->window_->GetRootWindow()) {
          new_window->AddObserver(this);
        }
      }
    }

    if (new_window->parent() == host_window_) {
      UpdateConstrainedWindows(NULL);
    }
  }

  virtual void OnWillRemoveWindow(aura::Window* window) override {
    if (window == view_->window_)
      return;

    window->RemoveObserver(this);
    UpdateConstrainedWindows(window);
  }

  virtual void OnWindowVisibilityChanged(aura::Window* window,
                                         bool visible) override {
    if (window == view_->window_ ||
        window->parent() == host_window_ ||
        window->parent() == view_->window_->GetRootWindow()) {
      UpdateConstrainedWindows(NULL);
    }
  }
#endif

  void OnWindowParentChanged(aura::Window* window,
                             aura::Window* parent) override {
    if (window != view_->window_)
      return;

    aura::Window* host_window =
        window->GetProperty(aura::client::kHostWindowKey);
    if (!host_window)
      host_window = parent;

    if (host_window_)
      host_window_->RemoveObserver(this);

#if defined(OS_WIN)
    if (host_window_) {
      const aura::Window::Windows& children = host_window_->children();
      for (size_t i = 0; i < children.size(); ++i)
        children[i]->RemoveObserver(this);
      RenderWidgetHostViewAura* rwhv = ToRenderWidgetHostViewAura(
          view_->web_contents_->GetRenderWidgetHostView());
      if (rwhv)
        rwhv->UpdateConstrainedWindowRects(std::vector<gfx::Rect>());
    }

    // When we get parented to the root window, the code below will watch the
    // host window, aka root window. Since we already watch the root window on
    // Windows, unregister first so that the debug check doesn't fire.
    if (host_window && host_window == window->GetRootWindow())
      host_window->RemoveObserver(this);

    // We need to undo the above if we were parented to the root window and then
    // got parented to another window. At that point, the code before the ifdef
    // would have stopped watching the root window.
    if (window->GetRootWindow() &&
        host_window != window->GetRootWindow() &&
        !window->GetRootWindow()->HasObserver(this)) {
      window->GetRootWindow()->AddObserver(this);
    }
#endif

    host_window_ = host_window;
    if (host_window) {
      host_window->AddObserver(this);
#if defined(OS_WIN)
      if (host_window != window->GetRootWindow()) {
        const aura::Window::Windows& children = host_window->children();
        for (size_t i = 0; i < children.size(); ++i) {
          if (!children[i]->Contains(view_->window_.get()))
            children[i]->AddObserver(this);
        }
      }
#endif
    }
  }

  void OnWindowBoundsChanged(aura::Window* window,
                             const gfx::Rect& old_bounds,
                             const gfx::Rect& new_bounds) override {
    if (window == host_window_ || window == view_->window_) {
      SendScreenRects();
      if (view_->touch_editable_)
        view_->touch_editable_->UpdateEditingController();
#if defined(OS_WIN)
    } else {
      UpdateConstrainedWindows(NULL);
#endif
    }
  }

  void OnWindowDestroying(aura::Window* window) override {
    if (window == host_window_) {
      host_window_->RemoveObserver(this);
      host_window_ = NULL;
    }
  }

  void OnWindowAddedToRootWindow(aura::Window* window) override {
    if (window == view_->window_) {
      window->GetHost()->AddObserver(this);
#if defined(OS_WIN)
      if (!window->GetRootWindow()->HasObserver(this))
        window->GetRootWindow()->AddObserver(this);
#endif
    }
  }

  void OnWindowRemovingFromRootWindow(aura::Window* window,
                                      aura::Window* new_root) override {
    if (window == view_->window_) {
      window->GetHost()->RemoveObserver(this);
#if defined(OS_WIN)
      window->GetRootWindow()->RemoveObserver(this);

      const aura::Window::Windows& root_children =
          window->GetRootWindow()->children();
      for (size_t i = 0; i < root_children.size(); ++i) {
        if (root_children[i] != view_->window_ &&
            root_children[i] != host_window_) {
          root_children[i]->RemoveObserver(this);
        }
      }
#endif
    }
  }

  // Overridden WindowTreeHostObserver:
  void OnHostMoved(const aura::WindowTreeHost* host,
                   const gfx::Point& new_origin) override {
    TRACE_EVENT1("ui",
                 "WebContentsViewAura::WindowObserver::OnHostMoved",
                 "new_origin", new_origin.ToString());

    // This is for the desktop case (i.e. Aura desktop).
    SendScreenRects();
  }

 private:
  void SendScreenRects() {
    RenderWidgetHostImpl::From(view_->web_contents_->GetRenderViewHost())->
        SendScreenRects();
  }

#if defined(OS_WIN)
  void UpdateConstrainedWindows(aura::Window* exclude) {
    RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
        view_->web_contents_->GetRenderWidgetHostView());
    if (!view)
      return;

    std::vector<gfx::Rect> constrained_windows;
    if (host_window_) {
      const aura::Window::Windows& children = host_window_->children();
      for (size_t i = 0; i < children.size(); ++i) {
        if (!children[i]->Contains(view_->window_.get()) &&
            children[i] != exclude &&
            children[i]->IsVisible()) {
          constrained_windows.push_back(children[i]->GetBoundsInRootWindow());
        }
      }
    }

    aura::Window* root_window = view_->window_->GetRootWindow();
    const aura::Window::Windows& root_children = root_window->children();
    if (root_window) {
      for (size_t i = 0; i < root_children.size(); ++i) {
        if (root_children[i]->IsVisible() &&
            !root_children[i]->Contains(view_->window_.get())) {
          constrained_windows.push_back(
              root_children[i]->GetBoundsInRootWindow());
        }
      }
    }

    view->UpdateConstrainedWindowRects(constrained_windows);
  }
#endif

  WebContentsViewAura* view_;

  // The parent window that hosts the constrained windows. We cache the old host
  // view so that we can unregister when it's not the parent anymore.
  aura::Window* host_window_;

  DISALLOW_COPY_AND_ASSIGN(WindowObserver);
};

////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, public:

WebContentsViewAura::WebContentsViewAura(
    WebContentsImpl* web_contents,
    WebContentsViewDelegate* delegate)
    : web_contents_(web_contents),
      delegate_(delegate),
      current_drag_op_(blink::WebDragOperationNone),
      drag_dest_delegate_(NULL),
      current_rvh_for_drag_(NULL),
      overscroll_change_brightness_(false),
      current_overscroll_gesture_(OVERSCROLL_NONE),
      completed_overscroll_gesture_(OVERSCROLL_NONE),
      touch_editable_(TouchEditableImplAura::Create()),
      is_or_was_visible_(false) {
}

////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, private:

WebContentsViewAura::~WebContentsViewAura() {
  if (!window_)
    return;

  window_observer_.reset();
  window_->RemoveObserver(this);

  // Window needs a valid delegate during its destructor, so we explicitly
  // delete it here.
  window_.reset();
}

void WebContentsViewAura::SetTouchEditableForTest(
    TouchEditableImplAura* touch_editable) {
  touch_editable_.reset(touch_editable);
  AttachTouchEditableToRenderView();
}

void WebContentsViewAura::SizeChangedCommon(const gfx::Size& size) {
  if (web_contents_->GetInterstitialPage())
    web_contents_->GetInterstitialPage()->SetSize(size);
  RenderWidgetHostView* rwhv =
      web_contents_->GetRenderWidgetHostView();
  if (rwhv)
    rwhv->SetSize(size);
}

void WebContentsViewAura::EndDrag(blink::WebDragOperationsMask ops) {
  aura::Window* root_window = GetNativeView()->GetRootWindow();
  gfx::Point screen_loc =
      gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
  gfx::Point client_loc = screen_loc;
  RenderViewHost* rvh = web_contents_->GetRenderViewHost();
  aura::Window* window = rvh->GetView()->GetNativeView();
  aura::Window::ConvertPointToTarget(root_window, window, &client_loc);
  if (!web_contents_)
    return;
  web_contents_->DragSourceEndedAt(client_loc.x(), client_loc.y(),
      screen_loc.x(), screen_loc.y(), ops);
}

void WebContentsViewAura::InstallOverscrollControllerDelegate(
    RenderWidgetHostViewAura* view) {
  const std::string value = base::CommandLine::ForCurrentProcess()->
      GetSwitchValueASCII(switches::kOverscrollHistoryNavigation);
  if (value == "0") {
    navigation_overlay_.reset();
    return;
  }
  if (value == "2") {
    navigation_overlay_.reset();
    if (!gesture_nav_simple_)
      gesture_nav_simple_.reset(new GestureNavSimple(web_contents_));
    view->overscroll_controller()->set_delegate(gesture_nav_simple_.get());
    return;
  }
  view->overscroll_controller()->set_delegate(this);
  if (!navigation_overlay_)
    navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_));
}

void WebContentsViewAura::PrepareOverscrollWindow() {
  // If there is an existing |overscroll_window_| which is in the middle of an
  // animation, then destroying the window here causes the animation to be
  // completed immediately, which triggers |OnImplicitAnimationsCompleted()|
  // callback, and that tries to reset |overscroll_window_| again, causing a
  // double-free. So use a temporary variable here.
  if (overscroll_window_) {
    base::AutoReset<OverscrollMode> reset_state(&current_overscroll_gesture_,
                                                current_overscroll_gesture_);
    scoped_ptr<aura::Window> reset_window(overscroll_window_.release());
  }

  OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate(
      web_contents_,
      current_overscroll_gesture_);
  overscroll_window_.reset(new aura::Window(overscroll_delegate));
  overscroll_window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
  overscroll_window_->SetTransparent(true);
  overscroll_window_->Init(aura::WINDOW_LAYER_TEXTURED);
  overscroll_window_->layer()->SetMasksToBounds(false);
  overscroll_window_->SetName("OverscrollOverlay");

  overscroll_change_brightness_ = overscroll_delegate->has_image();
  window_->AddChild(overscroll_window_.get());

  gfx::Rect bounds = gfx::Rect(window_->bounds().size());
  if (ShouldNavigateForward(web_contents_->GetController(),
                            current_overscroll_gesture_)) {
    // The overlay will be sliding in from the right edge towards the left in
    // non-RTL, or sliding in from the left edge towards the right in RTL.
    // So position the overlay window accordingly.
    bounds.Offset(base::i18n::IsRTL() ? -bounds.width() : bounds.width(), 0);
  }

  aura::Window* animate_window = GetWindowToAnimateForOverscroll();
  if (animate_window == overscroll_window_)
    window_->StackChildAbove(overscroll_window_.get(), GetContentNativeView());
  else
    window_->StackChildBelow(overscroll_window_.get(), GetContentNativeView());

  UpdateOverscrollWindowBrightness(0.f);

  overscroll_window_->SetBounds(bounds);
  overscroll_window_->Show();

  overscroll_shadow_.reset(new ShadowLayerDelegate(animate_window->layer()));
}

void WebContentsViewAura::PrepareContentWindowForOverscroll() {
  StopObservingImplicitAnimations();
  aura::Window* content = GetContentNativeView();
  content->layer()->GetAnimator()->AbortAllAnimations();
  content->SetTransform(gfx::Transform());
  content->layer()->SetLayerBrightness(0.f);
}

void WebContentsViewAura::ResetOverscrollTransform() {
  if (!web_contents_->GetRenderWidgetHostView())
    return;
  aura::Window* target = GetWindowToAnimateForOverscroll();
  if (!target)
    return;
  {
    ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
    settings.SetPreemptionStrategy(
        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
    settings.SetTweenType(gfx::Tween::EASE_OUT);
    settings.AddObserver(this);
    target->SetTransform(gfx::Transform());
  }
  {
    ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
    settings.SetPreemptionStrategy(
        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
    settings.SetTweenType(gfx::Tween::EASE_OUT);
    UpdateOverscrollWindowBrightness(0.f);
  }
}

void WebContentsViewAura::CompleteOverscrollNavigation(OverscrollMode mode) {
  if (!web_contents_->GetRenderWidgetHostView())
    return;

  // Animate out the current view first. Navigate to the requested history at
  // the end of the animation.
  if (current_overscroll_gesture_ == OVERSCROLL_NONE)
    return;

  UMA_HISTOGRAM_ENUMERATION("Overscroll.Navigated",
                            current_overscroll_gesture_, OVERSCROLL_COUNT);
  OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>(
      overscroll_window_->delegate());
  delegate->stop_forwarding_events();

  completed_overscroll_gesture_ = mode;
  aura::Window* target = GetWindowToAnimateForOverscroll();
  ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
  settings.SetPreemptionStrategy(
      ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
  settings.SetTweenType(gfx::Tween::EASE_OUT);
  settings.AddObserver(this);
  gfx::Transform transform;
  int content_width =
      web_contents_->GetRenderWidgetHostView()->GetViewBounds().width();
  float translate_x = static_cast<float>(mode == OVERSCROLL_WEST ?
      -content_width : content_width);
  transform.Translate(translate_x, 0);
  target->SetTransform(transform);
  UpdateOverscrollWindowBrightness(translate_x);
}

aura::Window* WebContentsViewAura::GetWindowToAnimateForOverscroll() {
  if (current_overscroll_gesture_ == OVERSCROLL_NONE)
    return NULL;

  return ShouldNavigateForward(web_contents_->GetController(),
                               current_overscroll_gesture_) ?
      overscroll_window_.get() : GetContentNativeView();
}

gfx::Vector2dF WebContentsViewAura::GetTranslationForOverscroll(float delta_x,
                                                                float delta_y) {
  if (current_overscroll_gesture_ == OVERSCROLL_NORTH ||
      current_overscroll_gesture_ == OVERSCROLL_SOUTH) {
    return gfx::Vector2dF(0, delta_y);
  }
  // For horizontal overscroll, scroll freely if a navigation is possible. Do a
  // resistive scroll otherwise.
  const NavigationControllerImpl& controller = web_contents_->GetController();
  const gfx::Rect& bounds = GetViewBounds();
  const float bounds_width = static_cast<float>(bounds.width());
  if (ShouldNavigateForward(controller, current_overscroll_gesture_))
    return gfx::Vector2dF(std::max(-bounds_width, delta_x), 0);
  else if (ShouldNavigateBack(controller, current_overscroll_gesture_))
    return gfx::Vector2dF(std::min(bounds_width, delta_x), 0);
  return gfx::Vector2dF();
}

void WebContentsViewAura::PrepareOverscrollNavigationOverlay() {
  OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>(
      overscroll_window_->delegate());
  overscroll_window_->SchedulePaintInRect(
      gfx::Rect(overscroll_window_->bounds().size()));
  overscroll_window_->SetBounds(gfx::Rect(window_->bounds().size()));
  overscroll_window_->SetTransform(gfx::Transform());
  navigation_overlay_->SetOverlayWindow(overscroll_window_.Pass(),
                                        delegate);
  navigation_overlay_->StartObserving();
}

void WebContentsViewAura::UpdateOverscrollWindowBrightness(float delta_x) {
  if (!overscroll_change_brightness_)
    return;

  const float kBrightnessMin = -.1f;
  const float kBrightnessMax = -.01f;

  float ratio = fabs(delta_x) / GetViewBounds().width();
  ratio = std::min(1.f, ratio);
  if (base::i18n::IsRTL())
    ratio = 1.f - ratio;
  float brightness = current_overscroll_gesture_ == OVERSCROLL_WEST ?
      kBrightnessMin + ratio * (kBrightnessMax - kBrightnessMin) :
      kBrightnessMax - ratio * (kBrightnessMax - kBrightnessMin);
  brightness = std::max(kBrightnessMin, brightness);
  brightness = std::min(kBrightnessMax, brightness);
  aura::Window* window = GetWindowToAnimateForOverscroll();
  window->layer()->SetLayerBrightness(brightness);
}

void WebContentsViewAura::AttachTouchEditableToRenderView() {
  if (!touch_editable_)
    return;
  RenderWidgetHostViewAura* rwhva = ToRenderWidgetHostViewAura(
      web_contents_->GetRenderWidgetHostView());
  touch_editable_->AttachToView(rwhva);
}

void WebContentsViewAura::OverscrollUpdateForWebContentsDelegate(
    float delta_y) {
  if (web_contents_->GetDelegate() && IsScrollEndEffectEnabled())
    web_contents_->GetDelegate()->OverscrollUpdate(delta_y);
}

////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, WebContentsView implementation:

gfx::NativeView WebContentsViewAura::GetNativeView() const {
  return window_.get();
}

gfx::NativeView WebContentsViewAura::GetContentNativeView() const {
  RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
  return rwhv ? rwhv->GetNativeView() : NULL;
}

gfx::NativeWindow WebContentsViewAura::GetTopLevelNativeWindow() const {
  gfx::NativeWindow window = window_->GetToplevelWindow();
  return window ? window : delegate_->GetNativeWindow();
}

void WebContentsViewAura::GetContainerBounds(gfx::Rect *out) const {
  *out = window_->GetBoundsInScreen();
}

void WebContentsViewAura::SizeContents(const gfx::Size& size) {
  gfx::Rect bounds = window_->bounds();
  if (bounds.size() != size) {
    bounds.set_size(size);
    window_->SetBounds(bounds);
  } else {
    // Our size matches what we want but the renderers size may not match.
    // Pretend we were resized so that the renderers size is updated too.
    SizeChangedCommon(size);
  }
}

void WebContentsViewAura::Focus() {
  if (web_contents_->GetInterstitialPage()) {
    web_contents_->GetInterstitialPage()->Focus();
    return;
  }

  if (delegate_.get() && delegate_->Focus())
    return;

  RenderWidgetHostView* rwhv =
      web_contents_->GetFullscreenRenderWidgetHostView();
  if (!rwhv)
    rwhv = web_contents_->GetRenderWidgetHostView();
  if (rwhv)
    rwhv->Focus();
}

void WebContentsViewAura::SetInitialFocus() {
  if (web_contents_->FocusLocationBarByDefault())
    web_contents_->SetFocusToLocationBar(false);
  else
    Focus();
}

void WebContentsViewAura::StoreFocus() {
  if (delegate_)
    delegate_->StoreFocus();
}

void WebContentsViewAura::RestoreFocus() {
  if (delegate_)
    delegate_->RestoreFocus();
}

DropData* WebContentsViewAura::GetDropData() const {
  return current_drop_data_.get();
}

gfx::Rect WebContentsViewAura::GetViewBounds() const {
  return window_->GetBoundsInScreen();
}

////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, WebContentsView implementation:

void WebContentsViewAura::CreateView(
    const gfx::Size& initial_size, gfx::NativeView context) {
  // NOTE: we ignore |initial_size| since in some cases it's wrong (such as
  // if the bookmark bar is not shown and you create a new tab). The right
  // value is set shortly after this, so its safe to ignore.

  aura::Env::CreateInstance(true);
  window_.reset(new aura::Window(this));
  window_->set_owned_by_parent(false);
  window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
  window_->SetTransparent(false);
  window_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
  window_->AddObserver(this);
  aura::Window* root_window = context ? context->GetRootWindow() : NULL;
  if (root_window) {
    // There are places where there is no context currently because object
    // hierarchies are built before they're attached to a Widget. (See
    // views::WebView as an example; GetWidget() returns NULL at the point
    // where we are created.)
    //
    // It should be OK to not set a default parent since such users will
    // explicitly add this WebContentsViewAura to their tree after they create
    // us.
    if (root_window) {
      aura::client::ParentWindowWithContext(
          window_.get(), root_window, root_window->GetBoundsInScreen());
    }
  }
  window_->layer()->SetMasksToBounds(true);
  window_->SetName("WebContentsViewAura");

  // WindowObserver is not interesting and is problematic for Browser Plugin
  // guests.
  // The use cases for WindowObserver do not apply to Browser Plugins:
  // 1) guests do not support NPAPI plugins.
  // 2) guests' window bounds are supposed to come from its embedder.
  if (!BrowserPluginGuest::IsGuest(web_contents_))
    window_observer_.reset(new WindowObserver(this));

  // delegate_->GetDragDestDelegate() creates a new delegate on every call.
  // Hence, we save a reference to it locally. Similar model is used on other
  // platforms as well.
  if (delegate_)
    drag_dest_delegate_ = delegate_->GetDragDestDelegate();
}

RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget(
    RenderWidgetHost* render_widget_host, bool is_guest_view_hack) {
  if (render_widget_host->GetView()) {
    // During testing, the view will already be set up in most cases to the
    // test view, so we don't want to clobber it with a real one. To verify that
    // this actually is happening (and somebody isn't accidentally creating the
    // view twice), we check for the RVH Factory, which will be set when we're
    // making special ones (which go along with the special views).
    DCHECK(RenderViewHostFactory::has_factory());
    return static_cast<RenderWidgetHostViewBase*>(
        render_widget_host->GetView());
  }

  RenderWidgetHostViewAura* view =
      new RenderWidgetHostViewAura(render_widget_host, is_guest_view_hack);
  view->InitAsChild(NULL);
  GetNativeView()->AddChild(view->GetNativeView());

  if (navigation_overlay_.get() && navigation_overlay_->has_window()) {
    navigation_overlay_->StartObserving();
  }

  RenderWidgetHostImpl* host_impl =
      RenderWidgetHostImpl::From(render_widget_host);

  if (!host_impl->is_hidden())
    view->Show();

  // We listen to drag drop events in the newly created view's window.
  aura::client::SetDragDropDelegate(view->GetNativeView(), this);

  if (view->overscroll_controller() &&
      (!web_contents_->GetDelegate() ||
       web_contents_->GetDelegate()->CanOverscrollContent())) {
    InstallOverscrollControllerDelegate(view);
  }

  AttachTouchEditableToRenderView();
  return view;
}

RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForPopupWidget(
    RenderWidgetHost* render_widget_host) {
  return new RenderWidgetHostViewAura(render_widget_host, false);
}

void WebContentsViewAura::SetPageTitle(const base::string16& title) {
  window_->SetTitle(title);
}

void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) {
}

void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) {
  if (navigation_overlay_.get() && navigation_overlay_->has_window())
    navigation_overlay_->StartObserving();
  AttachTouchEditableToRenderView();
}

void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) {
  RenderWidgetHostViewAura* view =
      ToRenderWidgetHostViewAura(web_contents_->GetRenderWidgetHostView());
  if (view) {
    view->SetOverscrollControllerEnabled(enabled);
    if (enabled)
      InstallOverscrollControllerDelegate(view);
  }

  if (!enabled)
    navigation_overlay_.reset();
  else if (!navigation_overlay_)
    navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_));
}

////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, RenderViewHostDelegateView implementation:

void WebContentsViewAura::ShowContextMenu(RenderFrameHost* render_frame_host,
                                          const ContextMenuParams& params) {
  if (touch_editable_) {
    touch_editable_->EndTouchEditing(false);
  }
  if (delegate_) {
    delegate_->ShowContextMenu(render_frame_host, params);
    // WARNING: we may have been deleted during the call to ShowContextMenu().
  }
}

void WebContentsViewAura::StartDragging(
    const DropData& drop_data,
    blink::WebDragOperationsMask operations,
    const gfx::ImageSkia& image,
    const gfx::Vector2d& image_offset,
    const DragEventSourceInfo& event_info) {
  aura::Window* root_window = GetNativeView()->GetRootWindow();
  if (!aura::client::GetDragDropClient(root_window)) {
    web_contents_->SystemDragEnded();
    return;
  }

  if (touch_editable_)
    touch_editable_->EndTouchEditing(false);

  ui::OSExchangeData::Provider* provider = ui::OSExchangeData::CreateProvider();
  PrepareDragData(drop_data, provider, web_contents_);

  ui::OSExchangeData data(provider);  // takes ownership of |provider|.

  if (!image.isNull())
    drag_utils::SetDragImageOnDataObject(image, image_offset, &data);

  scoped_ptr<WebDragSourceAura> drag_source(
      new WebDragSourceAura(GetNativeView(), web_contents_));

  // We need to enable recursive tasks on the message loop so we can get
  // updates while in the system DoDragDrop loop.
  int result_op = 0;
  {
    gfx::NativeView content_native_view = GetContentNativeView();
    base::MessageLoop::ScopedNestableTaskAllower allow(
        base::MessageLoop::current());

    gfx::Point root_point(event_info.event_location);
    aura::client::ScreenPositionClient* spc =
        aura::client::GetScreenPositionClient(root_window);
    if (spc)
      spc->ConvertPointFromScreen(root_window, &root_point);

    result_op = aura::client::GetDragDropClient(root_window)
        ->StartDragAndDrop(data,
                           root_window,
                           content_native_view,
                           root_point,
                           ConvertFromWeb(operations),
                           event_info.event_source);
  }

  // Bail out immediately if the contents view window is gone. Note that it is
  // not safe to access any class members in this case since |this| may already
  // be destroyed. The local variable |drag_source| will still be valid though,
  // so we can use it to determine if the window is gone.
  if (!drag_source->window()) {
    // Note that in this case, we don't need to call SystemDragEnded() since the
    // renderer is going away.
    return;
  }

  EndDrag(ConvertToWeb(result_op));
  web_contents_->SystemDragEnded();
}

void WebContentsViewAura::UpdateDragCursor(blink::WebDragOperation operation) {
  current_drag_op_ = operation;
}

void WebContentsViewAura::GotFocus() {
  if (web_contents_->GetDelegate())
    web_contents_->GetDelegate()->WebContentsFocused(web_contents_);
}

void WebContentsViewAura::TakeFocus(bool reverse) {
  if (web_contents_->GetDelegate() &&
      !web_contents_->GetDelegate()->TakeFocus(web_contents_, reverse) &&
      delegate_.get()) {
    delegate_->TakeFocus(reverse);
  }
}

void WebContentsViewAura::ShowDisambiguationPopup(
    const gfx::Rect& target_rect,
    const SkBitmap& zoomed_bitmap,
    const base::Callback<void(ui::GestureEvent*)>& gesture_cb,
    const base::Callback<void(ui::MouseEvent*)>& mouse_cb) {
  if (delegate_) {
    delegate_->ShowDisambiguationPopup(target_rect, zoomed_bitmap,
        window_.get(), gesture_cb, mouse_cb);
  }
}

void WebContentsViewAura::HideDisambiguationPopup() {
  if (delegate_)
    delegate_->HideDisambiguationPopup();
}

////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, OverscrollControllerDelegate implementation:

gfx::Rect WebContentsViewAura::GetVisibleBounds() const {
  RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
  if (!rwhv || !rwhv->IsShowing())
    return gfx::Rect();

  return rwhv->GetViewBounds();
}

bool WebContentsViewAura::OnOverscrollUpdate(float delta_x, float delta_y) {
  if (current_overscroll_gesture_ == OVERSCROLL_NONE)
    return false;

  aura::Window* target = GetWindowToAnimateForOverscroll();
  gfx::Vector2dF translate = GetTranslationForOverscroll(delta_x, delta_y);
  gfx::Transform transform;

  if (current_overscroll_gesture_ == OVERSCROLL_NORTH ||
      current_overscroll_gesture_ == OVERSCROLL_SOUTH) {
    OverscrollUpdateForWebContentsDelegate(translate.y());
  } else {
    // Only horizontal overscrolls participate in the navigation gesture.
    transform.Translate(translate.x(), translate.y());
    target->SetTransform(transform);
    UpdateOverscrollWindowBrightness(delta_x);
  }

  return !translate.IsZero();
}

void WebContentsViewAura::OnOverscrollComplete(OverscrollMode mode) {
  UMA_HISTOGRAM_ENUMERATION("Overscroll.Completed", mode, OVERSCROLL_COUNT);
  if (web_contents_->GetDelegate() &&
      IsScrollEndEffectEnabled() &&
      (mode == OVERSCROLL_NORTH || mode == OVERSCROLL_SOUTH)) {
    web_contents_->GetDelegate()->OverscrollComplete();
  }
  NavigationControllerImpl& controller = web_contents_->GetController();
  if (ShouldNavigateForward(controller, mode) ||
      ShouldNavigateBack(controller, mode)) {
    CompleteOverscrollNavigation(mode);
    return;
  }

  ResetOverscrollTransform();
}

void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode,
                                                 OverscrollMode new_mode) {
  // Reset any in-progress overscroll animation first.
  ResetOverscrollTransform();

  if (old_mode == OVERSCROLL_NORTH || old_mode == OVERSCROLL_SOUTH)
    OverscrollUpdateForWebContentsDelegate(0);

  if (new_mode != OVERSCROLL_NONE && touch_editable_)
    touch_editable_->OverscrollStarted();

  if (new_mode == OVERSCROLL_NONE ||
      !GetContentNativeView() ||
      ((new_mode == OVERSCROLL_EAST || new_mode == OVERSCROLL_WEST) &&
       navigation_overlay_.get() && navigation_overlay_->has_window())) {
    current_overscroll_gesture_ = OVERSCROLL_NONE;
  } else {
    aura::Window* target = GetWindowToAnimateForOverscroll();
    if (target) {
      StopObservingImplicitAnimations();
      target->layer()->GetAnimator()->AbortAllAnimations();
    }
    // Cleanup state of the content window first, because that can reset the
    // value of |current_overscroll_gesture_|.
    PrepareContentWindowForOverscroll();

    current_overscroll_gesture_ = new_mode;
    if (current_overscroll_gesture_ == OVERSCROLL_EAST ||
        current_overscroll_gesture_ == OVERSCROLL_WEST)
      PrepareOverscrollWindow();

    UMA_HISTOGRAM_ENUMERATION("Overscroll.Started", new_mode, OVERSCROLL_COUNT);
  }
  completed_overscroll_gesture_ = OVERSCROLL_NONE;
}

////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, ui::ImplicitAnimationObserver implementation:

void WebContentsViewAura::OnImplicitAnimationsCompleted() {
  overscroll_shadow_.reset();

  if (ShouldNavigateForward(web_contents_->GetController(),
                            completed_overscroll_gesture_)) {
    web_contents_->GetController().GoForward();
    PrepareOverscrollNavigationOverlay();
  } else if (ShouldNavigateBack(web_contents_->GetController(),
                                completed_overscroll_gesture_)) {
    web_contents_->GetController().GoBack();
    PrepareOverscrollNavigationOverlay();
  } else {
    if (touch_editable_)
      touch_editable_->OverscrollCompleted();
  }

  aura::Window* content = GetContentNativeView();
  if (content) {
    content->SetTransform(gfx::Transform());
    content->layer()->SetLayerBrightness(0.f);
  }
  current_overscroll_gesture_ = OVERSCROLL_NONE;
  completed_overscroll_gesture_ = OVERSCROLL_NONE;
  overscroll_window_.reset();
}

////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, aura::WindowDelegate implementation:

gfx::Size WebContentsViewAura::GetMinimumSize() const {
  return gfx::Size();
}

gfx::Size WebContentsViewAura::GetMaximumSize() const {
  return gfx::Size();
}

void WebContentsViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
                                          const gfx::Rect& new_bounds) {
  SizeChangedCommon(new_bounds.size());
  if (delegate_)
    delegate_->SizeChanged(new_bounds.size());

  // Constrained web dialogs, need to be kept centered over our content area.
  for (size_t i = 0; i < window_->children().size(); i++) {
    if (window_->children()[i]->GetProperty(
            aura::client::kConstrainedWindowKey)) {
      gfx::Rect bounds = window_->children()[i]->bounds();
      bounds.set_origin(
          gfx::Point((new_bounds.width() - bounds.width()) / 2,
                     (new_bounds.height() - bounds.height()) / 2));
      window_->children()[i]->SetBounds(bounds);
    }
  }
}

ui::TextInputClient* WebContentsViewAura::GetFocusedTextInputClient() {
  return nullptr;
}

gfx::NativeCursor WebContentsViewAura::GetCursor(const gfx::Point& point) {
  return gfx::kNullCursor;
}

int WebContentsViewAura::GetNonClientComponent(const gfx::Point& point) const {
  return HTCLIENT;
}

bool WebContentsViewAura::ShouldDescendIntoChildForEventHandling(
    aura::Window* child,
    const gfx::Point& location) {
  return true;
}

bool WebContentsViewAura::CanFocus() {
  // Do not take the focus if the render widget host view aura is gone or
  // is in the process of shutting down because neither the view window nor
  // this window can handle key events.
  RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
      web_contents_->GetRenderWidgetHostView());
  if (view != NULL && !view->IsClosing())
    return true;

  return false;
}

void WebContentsViewAura::OnCaptureLost() {
}

void WebContentsViewAura::OnPaint(gfx::Canvas* canvas) {
}

void WebContentsViewAura::OnDeviceScaleFactorChanged(
    float device_scale_factor) {
}

void WebContentsViewAura::OnWindowDestroying(aura::Window* window) {
  // This means the destructor is going to be called soon. If there is an
  // overscroll gesture in progress (i.e. |overscroll_window_| is not NULL),
  // then destroying it in the WebContentsViewAura destructor can trigger other
  // virtual functions to be called (e.g. OnImplicitAnimationsCompleted()). So
  // destroy the overscroll window here.
  navigation_overlay_.reset();
  overscroll_window_.reset();
}

void WebContentsViewAura::OnWindowDestroyed(aura::Window* window) {
}

void WebContentsViewAura::OnWindowTargetVisibilityChanged(bool visible) {
}

bool WebContentsViewAura::HasHitTestMask() const {
  return false;
}

void WebContentsViewAura::GetHitTestMask(gfx::Path* mask) const {
}

////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, ui::EventHandler implementation:

void WebContentsViewAura::OnKeyEvent(ui::KeyEvent* event) {
}

void WebContentsViewAura::OnMouseEvent(ui::MouseEvent* event) {
  if (!web_contents_->GetDelegate())
    return;

  switch (event->type()) {
    case ui::ET_MOUSE_PRESSED:
      web_contents_->GetDelegate()->ActivateContents(web_contents_);
      break;
    case ui::ET_MOUSE_MOVED:
    case ui::ET_MOUSE_EXITED:
      web_contents_->GetDelegate()->ContentsMouseEvent(
          web_contents_,
          gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(),
          event->type() == ui::ET_MOUSE_MOVED);
      break;
    default:
      break;
  }
}

////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, aura::client::DragDropDelegate implementation:

void WebContentsViewAura::OnDragEntered(const ui::DropTargetEvent& event) {
  current_rvh_for_drag_ = web_contents_->GetRenderViewHost();
  current_drop_data_.reset(new DropData());

  PrepareDropData(current_drop_data_.get(), event.data());
  blink::WebDragOperationsMask op = ConvertToWeb(event.source_operations());

  // Give the delegate an opportunity to cancel the drag.
  if (web_contents_->GetDelegate() &&
      !web_contents_->GetDelegate()->CanDragEnter(
          web_contents_, *current_drop_data_.get(), op)) {
    current_drop_data_.reset(NULL);
    return;
  }

  if (drag_dest_delegate_)
    drag_dest_delegate_->DragInitialize(web_contents_);

  gfx::Point screen_pt =
      gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
  web_contents_->GetRenderViewHost()->DragTargetDragEnter(
      *current_drop_data_.get(), event.location(), screen_pt, op,
      ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));

  if (drag_dest_delegate_) {
    drag_dest_delegate_->OnReceiveDragData(event.data());
    drag_dest_delegate_->OnDragEnter();
  }
}

int WebContentsViewAura::OnDragUpdated(const ui::DropTargetEvent& event) {
  DCHECK(current_rvh_for_drag_);
  if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost())
    OnDragEntered(event);

  if (!current_drop_data_)
    return ui::DragDropTypes::DRAG_NONE;

  blink::WebDragOperationsMask op = ConvertToWeb(event.source_operations());
  gfx::Point screen_pt =
      gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
  web_contents_->GetRenderViewHost()->DragTargetDragOver(
      event.location(), screen_pt, op,
      ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));

  if (drag_dest_delegate_)
    drag_dest_delegate_->OnDragOver();

  return ConvertFromWeb(current_drag_op_);
}

void WebContentsViewAura::OnDragExited() {
  DCHECK(current_rvh_for_drag_);
  if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost())
    return;

  if (!current_drop_data_)
    return;

  web_contents_->GetRenderViewHost()->DragTargetDragLeave();
  if (drag_dest_delegate_)
    drag_dest_delegate_->OnDragLeave();

  current_drop_data_.reset();
}

int WebContentsViewAura::OnPerformDrop(const ui::DropTargetEvent& event) {
  DCHECK(current_rvh_for_drag_);
  if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost())
    OnDragEntered(event);

  if (!current_drop_data_)
    return ui::DragDropTypes::DRAG_NONE;

  web_contents_->GetRenderViewHost()->DragTargetDrop(
      event.location(),
      gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(),
      ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
  if (drag_dest_delegate_)
    drag_dest_delegate_->OnDrop();
  current_drop_data_.reset();
  return ConvertFromWeb(current_drag_op_);
}

void WebContentsViewAura::OnWindowVisibilityChanged(aura::Window* window,
                                                    bool visible) {
  // Ignore any visibility changes in the hierarchy below.
  if (window != window_.get() && window_->Contains(window))
    return;

  UpdateWebContentsVisibility(visible);
}

void WebContentsViewAura::UpdateWebContentsVisibility(bool visible) {
  if (!is_or_was_visible_) {
    // We should not hide the web contents before it was shown the first time,
    // since resources would immediately be destroyed and only re-created after
    // content got loaded. In this state the window content is undefined and can
    // show garbage.
    // However - the page load mechanism requires an activation call through a
    // visibility call to (re)load.
    if (visible) {
      is_or_was_visible_ = true;
      web_contents_->WasShown();
    }
    return;
  }
  if (visible) {
    if (!web_contents_->should_normally_be_visible())
      web_contents_->WasShown();
  } else {
    if (web_contents_->should_normally_be_visible())
      web_contents_->WasHidden();
  }
}

}  // namespace content
