15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/web_contents/web_contents_view_aura.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/auto_reset.h"
8bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/command_line.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/histogram.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/browser_plugin/browser_plugin_guest.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/download/drag_download_util.h"
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/interstitial_page_impl.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/navigation_entry_impl.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/dip_util.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/renderer_host/overscroll_controller.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_factory.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/renderer_host/render_view_host_impl.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/renderer_host/render_widget_host_impl.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/renderer_host/render_widget_host_view_aura.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/browser/renderer_host/web_input_event_aura.h"
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/web_contents/aura/gesture_nav_simple.h"
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/web_contents/aura/image_window_delegate.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/web_contents/aura/shadow_layer_delegate.h"
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/browser/web_contents/aura/window_slider.h"
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/web_contents/touch_editable_impl_aura.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/web_contents/web_contents_impl.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/content_browser_client.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/overscroll_configuration.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view_delegate.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_drag_dest_delegate.h"
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/content_client.h"
44bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/public/common/content_switches.h"
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/common/drop_data.h"
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "net/base/filename_util.h"
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/aura_constants.h"
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/aura/client/window_tree_client.h"
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/aura/env.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h"
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window_observer.h"
5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/aura/window_tree_host.h"
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_tree_host_observer.h"
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/clipboard/clipboard.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/clipboard/custom_data_helper.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/drag_drop_types.h"
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/dragdrop/drag_utils.h"
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/base/dragdrop/drop_target_event.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/os_exchange_data.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/hit_test.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h"
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h"
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_utils.h"
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/canvas.h"
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image.h"
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image_png_rep.h"
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image_skia.h"
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/drag_drop_client.h"
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/drag_drop_delegate.h"
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)WebContentsView* CreateWebContentsView(
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContentsImpl* web_contents,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContentsViewDelegate* delegate,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewHostDelegateView** render_view_host_delegate_view) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebContentsViewAura* rv = new WebContentsViewAura(web_contents, delegate);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *render_view_host_delegate_view = rv;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rv;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochbool IsScrollEndEffectEnabled() {
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
88bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      switches::kScrollEndEffect) == "1";
89bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
90bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShouldNavigateForward(const NavigationController& controller,
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           OverscrollMode mode) {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return mode == (base::i18n::IsRTL() ? OVERSCROLL_EAST : OVERSCROLL_WEST) &&
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         controller.CanGoForward();
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShouldNavigateBack(const NavigationController& controller,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OverscrollMode mode) {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return mode == (base::i18n::IsRTL() ? OVERSCROLL_WEST : OVERSCROLL_EAST) &&
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         controller.CanGoBack();
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RenderWidgetHostViewAura* ToRenderWidgetHostViewAura(
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RenderWidgetHostView* view) {
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!view || RenderViewHostFactory::has_factory())
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;  // Can't cast to RenderWidgetHostViewAura in unit tests.
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RenderViewHost* rvh = RenderViewHost::From(view->GetRenderWidgetHost());
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      rvh ? WebContents::FromRenderViewHost(rvh) : NULL);
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (BrowserPluginGuest::IsGuest(web_contents))
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return static_cast<RenderWidgetHostViewAura*>(view);
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The window delegate for the overscroll window. This redirects trackpad events
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// to the web-contents window. The delegate destroys itself when the window is
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// destroyed.
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class OverscrollWindowDelegate : public ImageWindowDelegate {
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OverscrollWindowDelegate(WebContentsImpl* web_contents,
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           OverscrollMode overscroll_mode)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : web_contents_(web_contents),
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        forward_events_(true) {
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const NavigationControllerImpl& controller = web_contents->GetController();
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const NavigationEntryImpl* entry = NULL;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (ShouldNavigateForward(controller, overscroll_mode)) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      entry = NavigationEntryImpl::FromNavigationEntry(
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          controller.GetEntryAtOffset(1));
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (ShouldNavigateBack(controller, overscroll_mode)) {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      entry = NavigationEntryImpl::FromNavigationEntry(
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          controller.GetEntryAtOffset(-1));
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    gfx::Image image;
1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (entry && entry->screenshot().get()) {
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::vector<gfx::ImagePNGRep> image_reps;
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(), 1.0f));
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      image = gfx::Image(image_reps);
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetImage(image);
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void stop_forwarding_events() { forward_events_ = false; }
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~OverscrollWindowDelegate() {}
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* web_contents_window() {
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return web_contents_->GetView()->GetContentNativeView();
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler.
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (forward_events_ && web_contents_window())
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents_window()->delegate()->OnScrollEvent(event);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (forward_events_ && web_contents_window())
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents_window()->delegate()->OnGestureEvent(event);
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  WebContentsImpl* web_contents_;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The window is displayed both during the gesture, and after the gesture
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // while the navigation is in progress. During the gesture, it is necessary to
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // forward input events to the content page (e.g. when the overscroll window
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // slides under the cursor and starts receiving scroll events). However, once
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the gesture is complete, and the window is being displayed as an overlay
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // window during navigation, events should not be forwarded anymore.
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool forward_events_;
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OverscrollWindowDelegate);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Listens to all mouse drag events during a drag and drop and sends them to
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the renderer.
179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass WebDragSourceAura : public NotificationObserver {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebDragSourceAura(aura::Window* window, WebContentsImpl* contents)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : window_(window),
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        contents_(contents) {
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    registrar_.Add(this,
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   Source<WebContents>(contents));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WebDragSourceAura() {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // NotificationObserver:
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const NotificationSource& source,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const NotificationDetails& details) OVERRIDE {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (type != NOTIFICATION_WEB_CONTENTS_DISCONNECTED)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Cancel the drag if it is still in progress.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aura::client::DragDropClient* dnd_client =
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        aura::client::GetDragDropClient(window_->GetRootWindow());
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dnd_client && dnd_client->IsDragDropInProgress())
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dnd_client->DragCancel();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_ = NULL;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    contents_ = NULL;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::Window* window() const { return window_; }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::Window* window_;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebContentsImpl* contents_;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationRegistrar registrar_;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WebDragSourceAura);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
219effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN)
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Fill out the OSExchangeData with a file contents, synthesizing a name if
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// necessary.
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PrepareDragForFileContents(const DropData& drop_data,
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                ui::OSExchangeData::Provider* provider) {
224effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::FilePath file_name =
225effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::FilePath::FromUTF16Unsafe(drop_data.file_description_filename);
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Images without ALT text will only have a file extension so we need to
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // synthesize one from the provided extension and URL.
22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (file_name.BaseName().RemoveExtension().empty()) {
229effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const base::FilePath::StringType extension = file_name.Extension();
23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Retrieve the name from the URL.
231effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    file_name = net::GenerateFileName(drop_data.url, "", "", "", "", "")
232effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                    .ReplaceExtension(extension);
23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  provider->SetFileContents(file_name, drop_data.file_contents);
23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
236effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_WIN)
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PrepareDragForDownload(
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const DropData& drop_data,
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ui::OSExchangeData::Provider* provider,
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    WebContentsImpl* web_contents) {
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL& page_url = web_contents->GetLastCommittedURL();
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::string& page_encoding = web_contents->GetEncoding();
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Parse the download metadata.
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 mime_type;
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath file_name;
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL download_url;
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!ParseDownloadMetadata(drop_data.download_metadata,
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             &mime_type,
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             &file_name,
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             &download_url))
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Generate the file name based on both mime type and proposed file name.
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string default_name =
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetContentClient()->browser()->GetDefaultDownloadName();
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath generated_download_file_name =
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      net::GenerateFileName(download_url,
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            std::string(),
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            std::string(),
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            base::UTF16ToUTF8(file_name.value()),
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            base::UTF16ToUTF8(mime_type),
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            default_name);
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // http://crbug.com/332579
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ThreadRestrictions::ScopedAllowIO allow_file_operations;
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath temp_dir_path;
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_drag"),
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    &temp_dir_path))
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath download_path =
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      temp_dir_path.Append(generated_download_file_name);
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We cannot know when the target application will be done using the temporary
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // file, so schedule it to be deleted after rebooting.
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DeleteFileAfterReboot(download_path);
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DeleteFileAfterReboot(temp_dir_path);
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Provide the data as file (CF_HDROP). A temporary download file with the
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Zone.Identifier ADS (Alternate Data Stream) attached will be created.
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<DragDownloadFile> download_file =
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new DragDownloadFile(
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          download_path,
288c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          base::File(),
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          download_url,
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          Referrer(page_url, drop_data.referrer_policy),
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          page_encoding,
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          web_contents);
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::OSExchangeData::DownloadFileInfo file_download(base::FilePath(),
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                     download_file.get());
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  provider->SetDownloadFileInfo(file_download);
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
297effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif  // defined(OS_WIN)
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Returns the CustomFormat to store file system files.
3000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst ui::OSExchangeData::CustomFormat& GetFileSystemFileCustomFormat() {
3010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  static const char kFormatString[] = "chromium/x-file-system-files";
3020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  CR_DEFINE_STATIC_LOCAL(ui::OSExchangeData::CustomFormat,
3030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                         format,
3040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                         (ui::Clipboard::GetFormatType(kFormatString)));
3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return format;
3060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Writes file system files to the pickle.
3090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WriteFileSystemFilesToPickle(
3100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::vector<DropData::FileSystemFileInfo>& file_system_files,
3110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    Pickle* pickle) {
3120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  pickle->WriteUInt64(file_system_files.size());
3130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (size_t i = 0; i < file_system_files.size(); ++i) {
3140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    pickle->WriteString(file_system_files[i].url.spec());
3150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    pickle->WriteInt64(file_system_files[i].size);
3160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Reads file system files from the pickle.
3200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool ReadFileSystemFilesFromPickle(
3210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const Pickle& pickle,
3220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    std::vector<DropData::FileSystemFileInfo>* file_system_files) {
3230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  PickleIterator iter(pickle);
3240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  uint64 num_files = 0;
3260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!pickle.ReadUInt64(&iter, &num_files))
3270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return false;
3280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  file_system_files->resize(num_files);
3290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (uint64 i = 0; i < num_files; ++i) {
3310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    std::string url_string;
3320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int64 size = 0;
3330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!pickle.ReadString(&iter, &url_string) ||
3340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        !pickle.ReadInt64(&iter, &size))
3350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return false;
3360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    GURL url(url_string);
3380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!url.is_valid())
3390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return false;
3400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    (*file_system_files)[i].url = url;
3420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    (*file_system_files)[i].size = size;
3430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return true;
3450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Utility to fill a ui::OSExchangeDataProvider object from DropData.
348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid PrepareDragData(const DropData& drop_data,
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     ui::OSExchangeData::Provider* provider,
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     WebContentsImpl* web_contents) {
351effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  provider->MarkOriginatedFromRenderer();
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_WIN)
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Put download before file contents to prefer the download of a image over
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // its thumbnail link.
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!drop_data.download_metadata.empty())
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PrepareDragForDownload(drop_data, provider, web_contents);
357effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif
358effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN)
35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // We set the file contents before the URL because the URL also sets file
36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // contents (to a .URL shortcut).  We want to prefer file content data over
36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // a shortcut so we add it first.
36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!drop_data.file_contents.empty())
36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    PrepareDragForFileContents(drop_data, provider);
36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif
365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Call SetString() before SetURL() when we actually have a custom string.
366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // SetURL() will itself do SetString() when a string hasn't been set yet,
367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // but we want to prefer drop_data.text.string() over the URL string if it
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // exists.
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!drop_data.text.string().empty())
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    provider->SetString(drop_data.text.string());
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (drop_data.url.is_valid())
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    provider->SetURL(drop_data.url, drop_data.url_title);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!drop_data.html.string().empty())
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    provider->SetHtml(drop_data.html.string(), drop_data.html_base_url);
375effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!drop_data.filenames.empty())
376effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    provider->SetFilenames(drop_data.filenames);
3770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!drop_data.file_system_files.empty()) {
3780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    Pickle pickle;
3790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    WriteFileSystemFilesToPickle(drop_data.file_system_files, &pickle);
3800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    provider->SetPickledData(GetFileSystemFileCustomFormat(), pickle);
3810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!drop_data.custom_data.empty()) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Pickle pickle;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::WriteCustomDataToPickle(drop_data.custom_data, &pickle);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    provider->SetPickledData(ui::Clipboard::GetWebCustomDataFormatType(),
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             pickle);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Utility to fill a DropData object from ui::OSExchangeData.
391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid PrepareDropData(DropData* drop_data, const ui::OSExchangeData& data) {
392effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  drop_data->did_originate_from_renderer = data.DidOriginateFromRenderer();
393effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 plain_text;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.GetString(&plain_text);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!plain_text.empty())
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    drop_data->text = base::NullableString16(plain_text, false);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url;
400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 url_title;
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data.GetURLAndTitle(
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui::OSExchangeData::DO_NOT_CONVERT_FILENAMES, &url, &url_title);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (url.is_valid()) {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    drop_data->url = url;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    drop_data->url_title = url_title;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 html;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL html_base_url;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.GetHtml(&html, &html_base_url);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!html.empty())
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    drop_data->html = base::NullableString16(html, false);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (html_base_url.is_valid())
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    drop_data->html_base_url = html_base_url;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
416effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  data.GetFilenames(&drop_data->filenames);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pickle pickle;
4190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<DropData::FileSystemFileInfo> file_system_files;
4200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (data.GetPickledData(GetFileSystemFileCustomFormat(), &pickle) &&
4210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ReadFileSystemFilesFromPickle(pickle, &file_system_files))
4220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    drop_data->file_system_files = file_system_files;
4230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (data.GetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), &pickle))
42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ui::ReadCustomDataIntoMap(
42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        pickle.data(), pickle.size(), &drop_data->custom_data);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Utilities to convert between blink::WebDragOperationsMask and
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ui::DragDropTypes.
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int ConvertFromWeb(blink::WebDragOperationsMask ops) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int drag_op = ui::DragDropTypes::DRAG_NONE;
433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (ops & blink::WebDragOperationCopy)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    drag_op |= ui::DragDropTypes::DRAG_COPY;
435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (ops & blink::WebDragOperationMove)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    drag_op |= ui::DragDropTypes::DRAG_MOVE;
437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (ops & blink::WebDragOperationLink)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    drag_op |= ui::DragDropTypes::DRAG_LINK;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return drag_op;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)blink::WebDragOperationsMask ConvertToWeb(int drag_op) {
443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int web_drag_op = blink::WebDragOperationNone;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (drag_op & ui::DragDropTypes::DRAG_COPY)
445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    web_drag_op |= blink::WebDragOperationCopy;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (drag_op & ui::DragDropTypes::DRAG_MOVE)
447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    web_drag_op |= blink::WebDragOperationMove;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (drag_op & ui::DragDropTypes::DRAG_LINK)
449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    web_drag_op |= blink::WebDragOperationLink;
450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return (blink::WebDragOperationsMask) web_drag_op;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ConvertAuraEventFlagsToWebInputEventModifiers(int aura_event_flags) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int web_input_event_modifiers = 0;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (aura_event_flags & ui::EF_SHIFT_DOWN)
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    web_input_event_modifiers |= blink::WebInputEvent::ShiftKey;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (aura_event_flags & ui::EF_CONTROL_DOWN)
458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    web_input_event_modifiers |= blink::WebInputEvent::ControlKey;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (aura_event_flags & ui::EF_ALT_DOWN)
460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    web_input_event_modifiers |= blink::WebInputEvent::AltKey;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (aura_event_flags & ui::EF_COMMAND_DOWN)
462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    web_input_event_modifiers |= blink::WebInputEvent::MetaKey;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return web_input_event_modifiers;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WebContentsViewAura::WindowObserver
469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : public aura::WindowObserver, public aura::WindowTreeHostObserver {
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit WindowObserver(WebContentsViewAura* view)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : view_(view),
473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        host_window_(NULL) {
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    view_->window_->AddObserver(this);
475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN)
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (view_->window_->GetRootWindow())
478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      view_->window_->GetRootWindow()->AddObserver(this);
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~WindowObserver() {
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    view_->window_->RemoveObserver(this);
484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (view_->window_->GetHost())
485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      view_->window_->GetHost()->RemoveObserver(this);
486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (host_window_)
487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      host_window_->RemoveObserver(this);
488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN)
489116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (host_window_) {
490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const aura::Window::Windows& children = host_window_->children();
491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      for (size_t i = 0; i < children.size(); ++i)
492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        children[i]->RemoveObserver(this);
493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    aura::Window* root_window = view_->window_->GetRootWindow();
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (root_window) {
497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      root_window->RemoveObserver(this);
498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const aura::Window::Windows& root_children = root_window->children();
499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      for (size_t i = 0; i < root_children.size(); ++i)
500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        root_children[i]->RemoveObserver(this);
501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from aura::WindowObserver:
5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnWindowHierarchyChanged(
5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const aura::WindowObserver::HierarchyChangeParams& params) OVERRIDE {
5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (params.receiver != view_->window_.get() ||
5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        !params.target->Contains(view_->window_.get())) {
5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return;
5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Use the new parent's root window for calculating HiDPI subpixel offset.
5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RenderWidgetHostViewAura* rwhv = ToRenderWidgetHostViewAura(
5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        view_->web_contents_->GetRenderWidgetHostView());
5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (rwhv)
5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      rwhv->SnapToPhysicalPixelBoundary();
5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN)
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Constrained windows are added as children of the parent's parent's view
522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // which may overlap with windowed NPAPI plugins. In that case, tell the RWHV
523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // so that it can update the plugins' cutout rects accordingly.
524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Note: this is hard coding how Chrome layer adds its dialogs. Since NPAPI is
525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // going to be deprecated in a year, this is ok for now. The test for this is
526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // PrintPreviewTest.WindowedNPAPIPluginHidden.
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnWindowAdded(aura::Window* new_window) OVERRIDE {
528116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!new_window->Contains(view_->window_.get())) {
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Skip the case when the parent moves to the root window.
530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (new_window != host_window_) {
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Observe sibling windows of the WebContents, or children of the root
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // window.
533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        if (new_window->parent() == host_window_ ||
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            new_window->parent() == view_->window_->GetRootWindow()) {
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          new_window->AddObserver(this);
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
540116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (new_window->parent() == host_window_) {
541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      UpdateConstrainedWindows(NULL);
542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE {
546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (window == view_->window_)
547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    window->RemoveObserver(this);
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    UpdateConstrainedWindows(window);
551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnWindowVisibilityChanged(aura::Window* window,
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                         bool visible) OVERRIDE {
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (window == view_->window_ ||
556116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        window->parent() == host_window_ ||
557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window->parent() == view_->window_->GetRootWindow()) {
558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      UpdateConstrainedWindows(NULL);
559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowParentChanged(aura::Window* window,
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     aura::Window* parent) OVERRIDE {
565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (window != view_->window_)
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
567116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
568116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    aura::Window* host_window =
569116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        window->GetProperty(aura::client::kHostWindowKey);
570116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!host_window)
571116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      host_window = parent;
572116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
573116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (host_window_)
574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      host_window_->RemoveObserver(this);
575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN)
577116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (host_window_) {
578116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const aura::Window::Windows& children = host_window_->children();
579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      for (size_t i = 0; i < children.size(); ++i)
580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        children[i]->RemoveObserver(this);
5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      RenderWidgetHostViewAura* rwhv = ToRenderWidgetHostViewAura(
5825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          view_->web_contents_->GetRenderWidgetHostView());
583116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (rwhv)
584116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        rwhv->UpdateConstrainedWindowRects(std::vector<gfx::Rect>());
585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // When we get parented to the root window, the code below will watch the
588116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // host window, aka root window. Since we already watch the root window on
589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Windows, unregister first so that the debug check doesn't fire.
590116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (host_window && host_window == window->GetRootWindow())
591116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      host_window->RemoveObserver(this);
592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // We need to undo the above if we were parented to the root window and then
594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // got parented to another window. At that point, the code before the ifdef
595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // would have stopped watching the root window.
596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (window->GetRootWindow() &&
597116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        host_window != window->GetRootWindow() &&
598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        !window->GetRootWindow()->HasObserver(this)) {
599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window->GetRootWindow()->AddObserver(this);
600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
603116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    host_window_ = host_window;
604116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (host_window) {
605116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      host_window->AddObserver(this);
606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN)
607116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (host_window != window->GetRootWindow()) {
608116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        const aura::Window::Windows& children = host_window->children();
609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        for (size_t i = 0; i < children.size(); ++i) {
610116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          if (!children[i]->Contains(view_->window_.get()))
611f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            children[i]->AddObserver(this);
612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowBoundsChanged(aura::Window* window,
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const gfx::Rect& old_bounds,
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const gfx::Rect& new_bounds) OVERRIDE {
621116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (window == host_window_ || window == view_->window_) {
622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SendScreenRects();
623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (view_->touch_editable_)
624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        view_->touch_editable_->UpdateEditingController();
625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN)
626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else {
627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      UpdateConstrainedWindows(NULL);
628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
629f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
633116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (window == host_window_) {
634116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      host_window_->RemoveObserver(this);
635116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      host_window_ = NULL;
636116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
637116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
638116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE {
640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (window == view_->window_) {
641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      window->GetHost()->AddObserver(this);
642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN)
643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (!window->GetRootWindow()->HasObserver(this))
644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window->GetRootWindow()->AddObserver(this);
645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
649effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void OnWindowRemovingFromRootWindow(aura::Window* window,
650effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                              aura::Window* new_root) OVERRIDE {
651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (window == view_->window_) {
652a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      window->GetHost()->RemoveObserver(this);
653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN)
654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window->GetRootWindow()->RemoveObserver(this);
655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const aura::Window::Windows& root_children =
657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          window->GetRootWindow()->children();
658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      for (size_t i = 0; i < root_children.size(); ++i) {
659116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        if (root_children[i] != view_->window_ &&
660116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            root_children[i] != host_window_) {
661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          root_children[i]->RemoveObserver(this);
662116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        }
663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Overridden WindowTreeHostObserver:
669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnHostMoved(const aura::WindowTreeHost* host,
670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           const gfx::Point& new_origin) OVERRIDE {
671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TRACE_EVENT1("ui",
672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 "WebContentsViewAura::WindowObserver::OnHostMoved",
673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 "new_origin", new_origin.ToString());
674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This is for the desktop case (i.e. Aura desktop).
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SendScreenRects();
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SendScreenRects() {
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RenderWidgetHostImpl::From(view_->web_contents_->GetRenderViewHost())->
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SendScreenRects();
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateConstrainedWindows(aura::Window* exclude) {
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        view_->web_contents_->GetRenderWidgetHostView());
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!view)
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<gfx::Rect> constrained_windows;
693116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (host_window_) {
694116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const aura::Window::Windows& children = host_window_->children();
695f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      for (size_t i = 0; i < children.size(); ++i) {
696116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        if (!children[i]->Contains(view_->window_.get()) &&
697f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            children[i] != exclude &&
698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            children[i]->IsVisible()) {
699f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          constrained_windows.push_back(children[i]->GetBoundsInRootWindow());
700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
702f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    aura::Window* root_window = view_->window_->GetRootWindow();
705f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const aura::Window::Windows& root_children = root_window->children();
706f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (root_window) {
707f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      for (size_t i = 0; i < root_children.size(); ++i) {
708f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        if (root_children[i]->IsVisible() &&
709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            !root_children[i]->Contains(view_->window_.get())) {
710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          constrained_windows.push_back(
711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              root_children[i]->GetBoundsInRootWindow());
712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    view->UpdateConstrainedWindowRects(constrained_windows);
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
718f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContentsViewAura* view_;
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The parent window that hosts the constrained windows. We cache the old host
723116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // view so that we can unregister when it's not the parent anymore.
724116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  aura::Window* host_window_;
725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WindowObserver);
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebContentsViewAura, public:
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebContentsViewAura::WebContentsViewAura(
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContentsImpl* web_contents,
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContentsViewDelegate* delegate)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : web_contents_(web_contents),
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate),
737f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      current_drag_op_(blink::WebDragOperationNone),
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      drag_dest_delegate_(NULL),
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      current_rvh_for_drag_(NULL),
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      overscroll_change_brightness_(false),
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      current_overscroll_gesture_(OVERSCROLL_NONE),
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      completed_overscroll_gesture_(OVERSCROLL_NONE),
743116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      touch_editable_(TouchEditableImplAura::Create()),
744116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      is_or_was_visible_(false) {
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebContentsViewAura, private:
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebContentsViewAura::~WebContentsViewAura() {
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!window_)
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_observer_.reset();
755cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  window_->RemoveObserver(this);
756f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Window needs a valid delegate during its destructor, so we explicitly
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // delete it here.
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_.reset();
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebContentsViewAura::SetTouchEditableForTest(
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TouchEditableImplAura* touch_editable) {
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  touch_editable_.reset(touch_editable);
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AttachTouchEditableToRenderView();
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebContentsViewAura::SizeChangedCommon(const gfx::Size& size) {
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_->GetInterstitialPage())
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_contents_->GetInterstitialPage()->SetSize(size);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderWidgetHostView* rwhv =
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents_->GetRenderWidgetHostView();
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rwhv)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rwhv->SetSize(size);
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
777f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WebContentsViewAura::EndDrag(blink::WebDragOperationsMask ops) {
7781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root_window = GetNativeView()->GetRootWindow();
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point screen_loc =
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point client_loc = screen_loc;
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* rvh = web_contents_->GetRenderViewHost();
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::Window* window = rvh->GetView()->GetNativeView();
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::Window::ConvertPointToTarget(root_window, window, &client_loc);
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!web_contents_)
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  web_contents_->DragSourceEndedAt(client_loc.x(), client_loc.y(),
788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      screen_loc.x(), screen_loc.y(), ops);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
791a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebContentsViewAura::InstallOverscrollControllerDelegate(
79246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    RenderWidgetHostViewAura* view) {
7936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const std::string value = base::CommandLine::ForCurrentProcess()->
794a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetSwitchValueASCII(switches::kOverscrollHistoryNavigation);
795a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (value == "0") {
796a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    navigation_overlay_.reset();
797a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
798a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
799a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (value == "2") {
800a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    navigation_overlay_.reset();
801a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!gesture_nav_simple_)
802a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      gesture_nav_simple_.reset(new GestureNavSimple(web_contents_));
80346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    view->overscroll_controller()->set_delegate(gesture_nav_simple_.get());
804a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
805a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
80646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  view->overscroll_controller()->set_delegate(this);
807a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!navigation_overlay_)
808a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_));
809a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
810a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebContentsViewAura::PrepareOverscrollWindow() {
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there is an existing |overscroll_window_| which is in the middle of an
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // animation, then destroying the window here causes the animation to be
8141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // completed immediately, which triggers |OnImplicitAnimationsCompleted()|
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // callback, and that tries to reset |overscroll_window_| again, causing a
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // double-free. So use a temporary variable here.
817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (overscroll_window_) {
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::AutoReset<OverscrollMode> reset_state(&current_overscroll_gesture_,
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                current_overscroll_gesture_);
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<aura::Window> reset_window(overscroll_window_.release());
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate(
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents_,
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      current_overscroll_gesture_);
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  overscroll_window_.reset(new aura::Window(overscroll_delegate));
8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  overscroll_window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  overscroll_window_->SetTransparent(true);
8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  overscroll_window_->Init(aura::WINDOW_LAYER_TEXTURED);
830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  overscroll_window_->layer()->SetMasksToBounds(false);
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  overscroll_window_->SetName("OverscrollOverlay");
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  overscroll_change_brightness_ = overscroll_delegate->has_image();
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->AddChild(overscroll_window_.get());
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect bounds = gfx::Rect(window_->bounds().size());
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ShouldNavigateForward(web_contents_->GetController(),
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            current_overscroll_gesture_)) {
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The overlay will be sliding in from the right edge towards the left in
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // non-RTL, or sliding in from the left edge towards the right in RTL.
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // So position the overlay window accordingly.
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bounds.Offset(base::i18n::IsRTL() ? -bounds.width() : bounds.width(), 0);
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* animate_window = GetWindowToAnimateForOverscroll();
846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (animate_window == overscroll_window_)
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    window_->StackChildAbove(overscroll_window_.get(), GetContentNativeView());
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    window_->StackChildBelow(overscroll_window_.get(), GetContentNativeView());
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateOverscrollWindowBrightness(0.f);
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  overscroll_window_->SetBounds(bounds);
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  overscroll_window_->Show();
855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  overscroll_shadow_.reset(new ShadowLayerDelegate(animate_window->layer()));
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebContentsViewAura::PrepareContentWindowForOverscroll() {
860b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  StopObservingImplicitAnimations();
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* content = GetContentNativeView();
862b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  content->layer()->GetAnimator()->AbortAllAnimations();
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content->SetTransform(gfx::Transform());
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content->layer()->SetLayerBrightness(0.f);
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebContentsViewAura::ResetOverscrollTransform() {
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!web_contents_->GetRenderWidgetHostView())
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* target = GetWindowToAnimateForOverscroll();
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!target)
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    settings.SetPreemptionStrategy(
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
877d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    settings.SetTweenType(gfx::Tween::EASE_OUT);
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    settings.AddObserver(this);
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    target->SetTransform(gfx::Transform());
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    settings.SetPreemptionStrategy(
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
885d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    settings.SetTweenType(gfx::Tween::EASE_OUT);
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateOverscrollWindowBrightness(0.f);
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebContentsViewAura::CompleteOverscrollNavigation(OverscrollMode mode) {
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!web_contents_->GetRenderWidgetHostView())
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Animate out the current view first. Navigate to the requested history at
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the end of the animation.
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (current_overscroll_gesture_ == OVERSCROLL_NONE)
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Overscroll.Navigated",
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            current_overscroll_gesture_, OVERSCROLL_COUNT);
901b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>(
902b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      overscroll_window_->delegate());
903b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  delegate->stop_forwarding_events();
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completed_overscroll_gesture_ = mode;
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* target = GetWindowToAnimateForOverscroll();
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.SetPreemptionStrategy(
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
910d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  settings.SetTweenType(gfx::Tween::EASE_OUT);
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.AddObserver(this);
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform transform;
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int content_width =
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents_->GetRenderWidgetHostView()->GetViewBounds().width();
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int translate_x = mode == OVERSCROLL_WEST ? -content_width : content_width;
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.Translate(translate_x, 0);
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target->SetTransform(transform);
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateOverscrollWindowBrightness(translate_x);
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)aura::Window* WebContentsViewAura::GetWindowToAnimateForOverscroll() {
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (current_overscroll_gesture_ == OVERSCROLL_NONE)
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ShouldNavigateForward(web_contents_->GetController(),
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               current_overscroll_gesture_) ?
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      overscroll_window_.get() : GetContentNativeView();
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Vector2d WebContentsViewAura::GetTranslationForOverscroll(int delta_x,
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                               int delta_y) {
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (current_overscroll_gesture_ == OVERSCROLL_NORTH ||
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      current_overscroll_gesture_ == OVERSCROLL_SOUTH) {
934bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    return gfx::Vector2d(0, delta_y);
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For horizontal overscroll, scroll freely if a navigation is possible. Do a
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // resistive scroll otherwise.
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const NavigationControllerImpl& controller = web_contents_->GetController();
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Rect& bounds = GetViewBounds();
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ShouldNavigateForward(controller, current_overscroll_gesture_))
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gfx::Vector2d(std::max(-bounds.width(), delta_x), 0);
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (ShouldNavigateBack(controller, current_overscroll_gesture_))
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gfx::Vector2d(std::min(bounds.width(), delta_x), 0);
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::Vector2d();
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebContentsViewAura::PrepareOverscrollNavigationOverlay() {
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>(
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      overscroll_window_->delegate());
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  overscroll_window_->SchedulePaintInRect(
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(overscroll_window_->bounds().size()));
952eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  overscroll_window_->SetBounds(gfx::Rect(window_->bounds().size()));
953eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  overscroll_window_->SetTransform(gfx::Transform());
954