Home | History | Annotate | Download | only in web_contents
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/web_contents/web_contents_view_aura.h"
      6 
      7 #include "base/auto_reset.h"
      8 #include "base/command_line.h"
      9 #include "base/files/file_util.h"
     10 #include "base/metrics/histogram.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "content/browser/browser_plugin/browser_plugin_guest.h"
     13 #include "content/browser/download/drag_download_util.h"
     14 #include "content/browser/frame_host/interstitial_page_impl.h"
     15 #include "content/browser/frame_host/navigation_entry_impl.h"
     16 #include "content/browser/renderer_host/dip_util.h"
     17 #include "content/browser/renderer_host/overscroll_controller.h"
     18 #include "content/browser/renderer_host/render_view_host_factory.h"
     19 #include "content/browser/renderer_host/render_view_host_impl.h"
     20 #include "content/browser/renderer_host/render_widget_host_impl.h"
     21 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
     22 #include "content/browser/renderer_host/web_input_event_aura.h"
     23 #include "content/browser/web_contents/aura/gesture_nav_simple.h"
     24 #include "content/browser/web_contents/aura/image_window_delegate.h"
     25 #include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
     26 #include "content/browser/web_contents/aura/shadow_layer_delegate.h"
     27 #include "content/browser/web_contents/aura/window_slider.h"
     28 #include "content/browser/web_contents/touch_editable_impl_aura.h"
     29 #include "content/browser/web_contents/web_contents_impl.h"
     30 #include "content/public/browser/content_browser_client.h"
     31 #include "content/public/browser/notification_observer.h"
     32 #include "content/public/browser/notification_registrar.h"
     33 #include "content/public/browser/notification_source.h"
     34 #include "content/public/browser/notification_types.h"
     35 #include "content/public/browser/overscroll_configuration.h"
     36 #include "content/public/browser/render_view_host.h"
     37 #include "content/public/browser/render_widget_host.h"
     38 #include "content/public/browser/render_widget_host_view.h"
     39 #include "content/public/browser/web_contents_delegate.h"
     40 #include "content/public/browser/web_contents_observer.h"
     41 #include "content/public/browser/web_contents_view_delegate.h"
     42 #include "content/public/browser/web_drag_dest_delegate.h"
     43 #include "content/public/common/content_client.h"
     44 #include "content/public/common/content_switches.h"
     45 #include "content/public/common/drop_data.h"
     46 #include "net/base/filename_util.h"
     47 #include "third_party/WebKit/public/web/WebInputEvent.h"
     48 #include "ui/aura/client/aura_constants.h"
     49 #include "ui/aura/client/window_tree_client.h"
     50 #include "ui/aura/env.h"
     51 #include "ui/aura/window.h"
     52 #include "ui/aura/window_observer.h"
     53 #include "ui/aura/window_tree_host.h"
     54 #include "ui/aura/window_tree_host_observer.h"
     55 #include "ui/base/clipboard/clipboard.h"
     56 #include "ui/base/clipboard/custom_data_helper.h"
     57 #include "ui/base/dragdrop/drag_drop_types.h"
     58 #include "ui/base/dragdrop/drag_utils.h"
     59 #include "ui/base/dragdrop/drop_target_event.h"
     60 #include "ui/base/dragdrop/os_exchange_data.h"
     61 #include "ui/base/hit_test.h"
     62 #include "ui/compositor/layer.h"
     63 #include "ui/compositor/scoped_layer_animation_settings.h"
     64 #include "ui/events/event.h"
     65 #include "ui/events/event_utils.h"
     66 #include "ui/gfx/canvas.h"
     67 #include "ui/gfx/image/image.h"
     68 #include "ui/gfx/image/image_png_rep.h"
     69 #include "ui/gfx/image/image_skia.h"
     70 #include "ui/gfx/screen.h"
     71 #include "ui/wm/public/drag_drop_client.h"
     72 #include "ui/wm/public/drag_drop_delegate.h"
     73 
     74 namespace content {
     75 WebContentsView* CreateWebContentsView(
     76     WebContentsImpl* web_contents,
     77     WebContentsViewDelegate* delegate,
     78     RenderViewHostDelegateView** render_view_host_delegate_view) {
     79   WebContentsViewAura* rv = new WebContentsViewAura(web_contents, delegate);
     80   *render_view_host_delegate_view = rv;
     81   return rv;
     82 }
     83 
     84 namespace {
     85 
     86 bool IsScrollEndEffectEnabled() {
     87   return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
     88       switches::kScrollEndEffect) == "1";
     89 }
     90 
     91 bool ShouldNavigateForward(const NavigationController& controller,
     92                            OverscrollMode mode) {
     93   return mode == (base::i18n::IsRTL() ? OVERSCROLL_EAST : OVERSCROLL_WEST) &&
     94          controller.CanGoForward();
     95 }
     96 
     97 bool ShouldNavigateBack(const NavigationController& controller,
     98                         OverscrollMode mode) {
     99   return mode == (base::i18n::IsRTL() ? OVERSCROLL_WEST : OVERSCROLL_EAST) &&
    100          controller.CanGoBack();
    101 }
    102 
    103 RenderWidgetHostViewAura* ToRenderWidgetHostViewAura(
    104     RenderWidgetHostView* view) {
    105   if (!view || RenderViewHostFactory::has_factory())
    106     return NULL;  // Can't cast to RenderWidgetHostViewAura in unit tests.
    107 
    108   RenderViewHost* rvh = RenderViewHost::From(view->GetRenderWidgetHost());
    109   WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
    110       rvh ? WebContents::FromRenderViewHost(rvh) : NULL);
    111   if (BrowserPluginGuest::IsGuest(web_contents))
    112     return NULL;
    113   return static_cast<RenderWidgetHostViewAura*>(view);
    114 }
    115 
    116 // The window delegate for the overscroll window. This redirects trackpad events
    117 // to the web-contents window. The delegate destroys itself when the window is
    118 // destroyed.
    119 class OverscrollWindowDelegate : public ImageWindowDelegate {
    120  public:
    121   OverscrollWindowDelegate(WebContentsImpl* web_contents,
    122                            OverscrollMode overscroll_mode)
    123       : web_contents_(web_contents),
    124         forward_events_(true) {
    125     const NavigationControllerImpl& controller = web_contents->GetController();
    126     const NavigationEntryImpl* entry = NULL;
    127     if (ShouldNavigateForward(controller, overscroll_mode)) {
    128       entry = NavigationEntryImpl::FromNavigationEntry(
    129           controller.GetEntryAtOffset(1));
    130     } else if (ShouldNavigateBack(controller, overscroll_mode)) {
    131       entry = NavigationEntryImpl::FromNavigationEntry(
    132           controller.GetEntryAtOffset(-1));
    133     }
    134 
    135     gfx::Image image;
    136     if (entry && entry->screenshot().get()) {
    137       std::vector<gfx::ImagePNGRep> image_reps;
    138       image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(), 1.0f));
    139       image = gfx::Image(image_reps);
    140     }
    141     SetImage(image);
    142   }
    143 
    144   void stop_forwarding_events() { forward_events_ = false; }
    145 
    146  private:
    147   virtual ~OverscrollWindowDelegate() {}
    148 
    149   aura::Window* web_contents_window() {
    150     return web_contents_->GetView()->GetContentNativeView();
    151   }
    152 
    153   // Overridden from ui::EventHandler.
    154   virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
    155     if (forward_events_ && web_contents_window())
    156       web_contents_window()->delegate()->OnScrollEvent(event);
    157   }
    158 
    159   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
    160     if (forward_events_ && web_contents_window())
    161       web_contents_window()->delegate()->OnGestureEvent(event);
    162   }
    163 
    164   WebContentsImpl* web_contents_;
    165 
    166   // The window is displayed both during the gesture, and after the gesture
    167   // while the navigation is in progress. During the gesture, it is necessary to
    168   // forward input events to the content page (e.g. when the overscroll window
    169   // slides under the cursor and starts receiving scroll events). However, once
    170   // the gesture is complete, and the window is being displayed as an overlay
    171   // window during navigation, events should not be forwarded anymore.
    172   bool forward_events_;
    173 
    174   DISALLOW_COPY_AND_ASSIGN(OverscrollWindowDelegate);
    175 };
    176 
    177 // Listens to all mouse drag events during a drag and drop and sends them to
    178 // the renderer.
    179 class WebDragSourceAura : public NotificationObserver {
    180  public:
    181   WebDragSourceAura(aura::Window* window, WebContentsImpl* contents)
    182       : window_(window),
    183         contents_(contents) {
    184     registrar_.Add(this,
    185                    NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
    186                    Source<WebContents>(contents));
    187   }
    188 
    189   virtual ~WebDragSourceAura() {
    190   }
    191 
    192   // NotificationObserver:
    193   virtual void Observe(int type,
    194       const NotificationSource& source,
    195       const NotificationDetails& details) OVERRIDE {
    196     if (type != NOTIFICATION_WEB_CONTENTS_DISCONNECTED)
    197       return;
    198 
    199     // Cancel the drag if it is still in progress.
    200     aura::client::DragDropClient* dnd_client =
    201         aura::client::GetDragDropClient(window_->GetRootWindow());
    202     if (dnd_client && dnd_client->IsDragDropInProgress())
    203       dnd_client->DragCancel();
    204 
    205     window_ = NULL;
    206     contents_ = NULL;
    207   }
    208 
    209   aura::Window* window() const { return window_; }
    210 
    211  private:
    212   aura::Window* window_;
    213   WebContentsImpl* contents_;
    214   NotificationRegistrar registrar_;
    215 
    216   DISALLOW_COPY_AND_ASSIGN(WebDragSourceAura);
    217 };
    218 
    219 #if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN)
    220 // Fill out the OSExchangeData with a file contents, synthesizing a name if
    221 // necessary.
    222 void PrepareDragForFileContents(const DropData& drop_data,
    223                                 ui::OSExchangeData::Provider* provider) {
    224   base::FilePath file_name =
    225       base::FilePath::FromUTF16Unsafe(drop_data.file_description_filename);
    226   // Images without ALT text will only have a file extension so we need to
    227   // synthesize one from the provided extension and URL.
    228   if (file_name.BaseName().RemoveExtension().empty()) {
    229     const base::FilePath::StringType extension = file_name.Extension();
    230     // Retrieve the name from the URL.
    231     file_name = net::GenerateFileName(drop_data.url, "", "", "", "", "")
    232                     .ReplaceExtension(extension);
    233   }
    234   provider->SetFileContents(file_name, drop_data.file_contents);
    235 }
    236 #endif
    237 
    238 #if defined(OS_WIN)
    239 void PrepareDragForDownload(
    240     const DropData& drop_data,
    241     ui::OSExchangeData::Provider* provider,
    242     WebContentsImpl* web_contents) {
    243   const GURL& page_url = web_contents->GetLastCommittedURL();
    244   const std::string& page_encoding = web_contents->GetEncoding();
    245 
    246   // Parse the download metadata.
    247   base::string16 mime_type;
    248   base::FilePath file_name;
    249   GURL download_url;
    250   if (!ParseDownloadMetadata(drop_data.download_metadata,
    251                              &mime_type,
    252                              &file_name,
    253                              &download_url))
    254     return;
    255 
    256   // Generate the file name based on both mime type and proposed file name.
    257   std::string default_name =
    258       GetContentClient()->browser()->GetDefaultDownloadName();
    259   base::FilePath generated_download_file_name =
    260       net::GenerateFileName(download_url,
    261                             std::string(),
    262                             std::string(),
    263                             base::UTF16ToUTF8(file_name.value()),
    264                             base::UTF16ToUTF8(mime_type),
    265                             default_name);
    266 
    267   // http://crbug.com/332579
    268   base::ThreadRestrictions::ScopedAllowIO allow_file_operations;
    269 
    270   base::FilePath temp_dir_path;
    271   if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_drag"),
    272                                     &temp_dir_path))
    273     return;
    274 
    275   base::FilePath download_path =
    276       temp_dir_path.Append(generated_download_file_name);
    277 
    278   // We cannot know when the target application will be done using the temporary
    279   // file, so schedule it to be deleted after rebooting.
    280   base::DeleteFileAfterReboot(download_path);
    281   base::DeleteFileAfterReboot(temp_dir_path);
    282 
    283   // Provide the data as file (CF_HDROP). A temporary download file with the
    284   // Zone.Identifier ADS (Alternate Data Stream) attached will be created.
    285   scoped_refptr<DragDownloadFile> download_file =
    286       new DragDownloadFile(
    287           download_path,
    288           base::File(),
    289           download_url,
    290           Referrer(page_url, drop_data.referrer_policy),
    291           page_encoding,
    292           web_contents);
    293   ui::OSExchangeData::DownloadFileInfo file_download(base::FilePath(),
    294                                                      download_file.get());
    295   provider->SetDownloadFileInfo(file_download);
    296 }
    297 #endif  // defined(OS_WIN)
    298 
    299 // Returns the CustomFormat to store file system files.
    300 const ui::OSExchangeData::CustomFormat& GetFileSystemFileCustomFormat() {
    301   static const char kFormatString[] = "chromium/x-file-system-files";
    302   CR_DEFINE_STATIC_LOCAL(ui::OSExchangeData::CustomFormat,
    303                          format,
    304                          (ui::Clipboard::GetFormatType(kFormatString)));
    305   return format;
    306 }
    307 
    308 // Writes file system files to the pickle.
    309 void WriteFileSystemFilesToPickle(
    310     const std::vector<DropData::FileSystemFileInfo>& file_system_files,
    311     Pickle* pickle) {
    312   pickle->WriteUInt64(file_system_files.size());
    313   for (size_t i = 0; i < file_system_files.size(); ++i) {
    314     pickle->WriteString(file_system_files[i].url.spec());
    315     pickle->WriteInt64(file_system_files[i].size);
    316   }
    317 }
    318 
    319 // Reads file system files from the pickle.
    320 bool ReadFileSystemFilesFromPickle(
    321     const Pickle& pickle,
    322     std::vector<DropData::FileSystemFileInfo>* file_system_files) {
    323   PickleIterator iter(pickle);
    324 
    325   uint64 num_files = 0;
    326   if (!pickle.ReadUInt64(&iter, &num_files))
    327     return false;
    328   file_system_files->resize(num_files);
    329 
    330   for (uint64 i = 0; i < num_files; ++i) {
    331     std::string url_string;
    332     int64 size = 0;
    333     if (!pickle.ReadString(&iter, &url_string) ||
    334         !pickle.ReadInt64(&iter, &size))
    335       return false;
    336 
    337     GURL url(url_string);
    338     if (!url.is_valid())
    339       return false;
    340 
    341     (*file_system_files)[i].url = url;
    342     (*file_system_files)[i].size = size;
    343   }
    344   return true;
    345 }
    346 
    347 // Utility to fill a ui::OSExchangeDataProvider object from DropData.
    348 void PrepareDragData(const DropData& drop_data,
    349                      ui::OSExchangeData::Provider* provider,
    350                      WebContentsImpl* web_contents) {
    351   provider->MarkOriginatedFromRenderer();
    352 #if defined(OS_WIN)
    353   // Put download before file contents to prefer the download of a image over
    354   // its thumbnail link.
    355   if (!drop_data.download_metadata.empty())
    356     PrepareDragForDownload(drop_data, provider, web_contents);
    357 #endif
    358 #if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN)
    359   // We set the file contents before the URL because the URL also sets file
    360   // contents (to a .URL shortcut).  We want to prefer file content data over
    361   // a shortcut so we add it first.
    362   if (!drop_data.file_contents.empty())
    363     PrepareDragForFileContents(drop_data, provider);
    364 #endif
    365   // Call SetString() before SetURL() when we actually have a custom string.
    366   // SetURL() will itself do SetString() when a string hasn't been set yet,
    367   // but we want to prefer drop_data.text.string() over the URL string if it
    368   // exists.
    369   if (!drop_data.text.string().empty())
    370     provider->SetString(drop_data.text.string());
    371   if (drop_data.url.is_valid())
    372     provider->SetURL(drop_data.url, drop_data.url_title);
    373   if (!drop_data.html.string().empty())
    374     provider->SetHtml(drop_data.html.string(), drop_data.html_base_url);
    375   if (!drop_data.filenames.empty())
    376     provider->SetFilenames(drop_data.filenames);
    377   if (!drop_data.file_system_files.empty()) {
    378     Pickle pickle;
    379     WriteFileSystemFilesToPickle(drop_data.file_system_files, &pickle);
    380     provider->SetPickledData(GetFileSystemFileCustomFormat(), pickle);
    381   }
    382   if (!drop_data.custom_data.empty()) {
    383     Pickle pickle;
    384     ui::WriteCustomDataToPickle(drop_data.custom_data, &pickle);
    385     provider->SetPickledData(ui::Clipboard::GetWebCustomDataFormatType(),
    386                              pickle);
    387   }
    388 }
    389 
    390 // Utility to fill a DropData object from ui::OSExchangeData.
    391 void PrepareDropData(DropData* drop_data, const ui::OSExchangeData& data) {
    392   drop_data->did_originate_from_renderer = data.DidOriginateFromRenderer();
    393 
    394   base::string16 plain_text;
    395   data.GetString(&plain_text);
    396   if (!plain_text.empty())
    397     drop_data->text = base::NullableString16(plain_text, false);
    398 
    399   GURL url;
    400   base::string16 url_title;
    401   data.GetURLAndTitle(
    402       ui::OSExchangeData::DO_NOT_CONVERT_FILENAMES, &url, &url_title);
    403   if (url.is_valid()) {
    404     drop_data->url = url;
    405     drop_data->url_title = url_title;
    406   }
    407 
    408   base::string16 html;
    409   GURL html_base_url;
    410   data.GetHtml(&html, &html_base_url);
    411   if (!html.empty())
    412     drop_data->html = base::NullableString16(html, false);
    413   if (html_base_url.is_valid())
    414     drop_data->html_base_url = html_base_url;
    415 
    416   data.GetFilenames(&drop_data->filenames);
    417 
    418   Pickle pickle;
    419   std::vector<DropData::FileSystemFileInfo> file_system_files;
    420   if (data.GetPickledData(GetFileSystemFileCustomFormat(), &pickle) &&
    421       ReadFileSystemFilesFromPickle(pickle, &file_system_files))
    422     drop_data->file_system_files = file_system_files;
    423 
    424   if (data.GetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), &pickle))
    425     ui::ReadCustomDataIntoMap(
    426         pickle.data(), pickle.size(), &drop_data->custom_data);
    427 }
    428 
    429 // Utilities to convert between blink::WebDragOperationsMask and
    430 // ui::DragDropTypes.
    431 int ConvertFromWeb(blink::WebDragOperationsMask ops) {
    432   int drag_op = ui::DragDropTypes::DRAG_NONE;
    433   if (ops & blink::WebDragOperationCopy)
    434     drag_op |= ui::DragDropTypes::DRAG_COPY;
    435   if (ops & blink::WebDragOperationMove)
    436     drag_op |= ui::DragDropTypes::DRAG_MOVE;
    437   if (ops & blink::WebDragOperationLink)
    438     drag_op |= ui::DragDropTypes::DRAG_LINK;
    439   return drag_op;
    440 }
    441 
    442 blink::WebDragOperationsMask ConvertToWeb(int drag_op) {
    443   int web_drag_op = blink::WebDragOperationNone;
    444   if (drag_op & ui::DragDropTypes::DRAG_COPY)
    445     web_drag_op |= blink::WebDragOperationCopy;
    446   if (drag_op & ui::DragDropTypes::DRAG_MOVE)
    447     web_drag_op |= blink::WebDragOperationMove;
    448   if (drag_op & ui::DragDropTypes::DRAG_LINK)
    449     web_drag_op |= blink::WebDragOperationLink;
    450   return (blink::WebDragOperationsMask) web_drag_op;
    451 }
    452 
    453 int ConvertAuraEventFlagsToWebInputEventModifiers(int aura_event_flags) {
    454   int web_input_event_modifiers = 0;
    455   if (aura_event_flags & ui::EF_SHIFT_DOWN)
    456     web_input_event_modifiers |= blink::WebInputEvent::ShiftKey;
    457   if (aura_event_flags & ui::EF_CONTROL_DOWN)
    458     web_input_event_modifiers |= blink::WebInputEvent::ControlKey;
    459   if (aura_event_flags & ui::EF_ALT_DOWN)
    460     web_input_event_modifiers |= blink::WebInputEvent::AltKey;
    461   if (aura_event_flags & ui::EF_COMMAND_DOWN)
    462     web_input_event_modifiers |= blink::WebInputEvent::MetaKey;
    463   return web_input_event_modifiers;
    464 }
    465 
    466 }  // namespace
    467 
    468 class WebContentsViewAura::WindowObserver
    469     : public aura::WindowObserver, public aura::WindowTreeHostObserver {
    470  public:
    471   explicit WindowObserver(WebContentsViewAura* view)
    472       : view_(view),
    473         host_window_(NULL) {
    474     view_->window_->AddObserver(this);
    475 
    476 #if defined(OS_WIN)
    477     if (view_->window_->GetRootWindow())
    478       view_->window_->GetRootWindow()->AddObserver(this);
    479 #endif
    480   }
    481 
    482   virtual ~WindowObserver() {
    483     view_->window_->RemoveObserver(this);
    484     if (view_->window_->GetHost())
    485       view_->window_->GetHost()->RemoveObserver(this);
    486     if (host_window_)
    487       host_window_->RemoveObserver(this);
    488 #if defined(OS_WIN)
    489     if (host_window_) {
    490       const aura::Window::Windows& children = host_window_->children();
    491       for (size_t i = 0; i < children.size(); ++i)
    492         children[i]->RemoveObserver(this);
    493     }
    494 
    495     aura::Window* root_window = view_->window_->GetRootWindow();
    496     if (root_window) {
    497       root_window->RemoveObserver(this);
    498       const aura::Window::Windows& root_children = root_window->children();
    499       for (size_t i = 0; i < root_children.size(); ++i)
    500         root_children[i]->RemoveObserver(this);
    501     }
    502 #endif
    503   }
    504 
    505   // Overridden from aura::WindowObserver:
    506   virtual void OnWindowHierarchyChanged(
    507       const aura::WindowObserver::HierarchyChangeParams& params) OVERRIDE {
    508     if (params.receiver != view_->window_.get() ||
    509         !params.target->Contains(view_->window_.get())) {
    510       return;
    511     }
    512 
    513     // Use the new parent's root window for calculating HiDPI subpixel offset.
    514     RenderWidgetHostViewAura* rwhv = ToRenderWidgetHostViewAura(
    515         view_->web_contents_->GetRenderWidgetHostView());
    516     if (rwhv)
    517       rwhv->SnapToPhysicalPixelBoundary();
    518   }
    519 
    520 #if defined(OS_WIN)
    521   // Constrained windows are added as children of the parent's parent's view
    522   // which may overlap with windowed NPAPI plugins. In that case, tell the RWHV
    523   // so that it can update the plugins' cutout rects accordingly.
    524   // Note: this is hard coding how Chrome layer adds its dialogs. Since NPAPI is
    525   // going to be deprecated in a year, this is ok for now. The test for this is
    526   // PrintPreviewTest.WindowedNPAPIPluginHidden.
    527   virtual void OnWindowAdded(aura::Window* new_window) OVERRIDE {
    528     if (!new_window->Contains(view_->window_.get())) {
    529       // Skip the case when the parent moves to the root window.
    530       if (new_window != host_window_) {
    531         // Observe sibling windows of the WebContents, or children of the root
    532         // window.
    533         if (new_window->parent() == host_window_ ||
    534             new_window->parent() == view_->window_->GetRootWindow()) {
    535           new_window->AddObserver(this);
    536         }
    537       }
    538     }
    539 
    540     if (new_window->parent() == host_window_) {
    541       UpdateConstrainedWindows(NULL);
    542     }
    543   }
    544 
    545   virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE {
    546     if (window == view_->window_)
    547       return;
    548 
    549     window->RemoveObserver(this);
    550     UpdateConstrainedWindows(window);
    551   }
    552 
    553   virtual void OnWindowVisibilityChanged(aura::Window* window,
    554                                          bool visible) OVERRIDE {
    555     if (window == view_->window_ ||
    556         window->parent() == host_window_ ||
    557         window->parent() == view_->window_->GetRootWindow()) {
    558       UpdateConstrainedWindows(NULL);
    559     }
    560   }
    561 #endif
    562 
    563   virtual void OnWindowParentChanged(aura::Window* window,
    564                                      aura::Window* parent) OVERRIDE {
    565     if (window != view_->window_)
    566       return;
    567 
    568     aura::Window* host_window =
    569         window->GetProperty(aura::client::kHostWindowKey);
    570     if (!host_window)
    571       host_window = parent;
    572 
    573     if (host_window_)
    574       host_window_->RemoveObserver(this);
    575 
    576 #if defined(OS_WIN)
    577     if (host_window_) {
    578       const aura::Window::Windows& children = host_window_->children();
    579       for (size_t i = 0; i < children.size(); ++i)
    580         children[i]->RemoveObserver(this);
    581       RenderWidgetHostViewAura* rwhv = ToRenderWidgetHostViewAura(
    582           view_->web_contents_->GetRenderWidgetHostView());
    583       if (rwhv)
    584         rwhv->UpdateConstrainedWindowRects(std::vector<gfx::Rect>());
    585     }
    586 
    587     // When we get parented to the root window, the code below will watch the
    588     // host window, aka root window. Since we already watch the root window on
    589     // Windows, unregister first so that the debug check doesn't fire.
    590     if (host_window && host_window == window->GetRootWindow())
    591       host_window->RemoveObserver(this);
    592 
    593     // We need to undo the above if we were parented to the root window and then
    594     // got parented to another window. At that point, the code before the ifdef
    595     // would have stopped watching the root window.
    596     if (window->GetRootWindow() &&
    597         host_window != window->GetRootWindow() &&
    598         !window->GetRootWindow()->HasObserver(this)) {
    599       window->GetRootWindow()->AddObserver(this);
    600     }
    601 #endif
    602 
    603     host_window_ = host_window;
    604     if (host_window) {
    605       host_window->AddObserver(this);
    606 #if defined(OS_WIN)
    607       if (host_window != window->GetRootWindow()) {
    608         const aura::Window::Windows& children = host_window->children();
    609         for (size_t i = 0; i < children.size(); ++i) {
    610           if (!children[i]->Contains(view_->window_.get()))
    611             children[i]->AddObserver(this);
    612         }
    613       }
    614 #endif
    615     }
    616   }
    617 
    618   virtual void OnWindowBoundsChanged(aura::Window* window,
    619                                      const gfx::Rect& old_bounds,
    620                                      const gfx::Rect& new_bounds) OVERRIDE {
    621     if (window == host_window_ || window == view_->window_) {
    622       SendScreenRects();
    623       if (view_->touch_editable_)
    624         view_->touch_editable_->UpdateEditingController();
    625 #if defined(OS_WIN)
    626     } else {
    627       UpdateConstrainedWindows(NULL);
    628 #endif
    629     }
    630   }
    631 
    632   virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
    633     if (window == host_window_) {
    634       host_window_->RemoveObserver(this);
    635       host_window_ = NULL;
    636     }
    637   }
    638 
    639   virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE {
    640     if (window == view_->window_) {
    641       window->GetHost()->AddObserver(this);
    642 #if defined(OS_WIN)
    643       if (!window->GetRootWindow()->HasObserver(this))
    644         window->GetRootWindow()->AddObserver(this);
    645 #endif
    646     }
    647   }
    648 
    649   virtual void OnWindowRemovingFromRootWindow(aura::Window* window,
    650                                               aura::Window* new_root) OVERRIDE {
    651     if (window == view_->window_) {
    652       window->GetHost()->RemoveObserver(this);
    653 #if defined(OS_WIN)
    654       window->GetRootWindow()->RemoveObserver(this);
    655 
    656       const aura::Window::Windows& root_children =
    657           window->GetRootWindow()->children();
    658       for (size_t i = 0; i < root_children.size(); ++i) {
    659         if (root_children[i] != view_->window_ &&
    660             root_children[i] != host_window_) {
    661           root_children[i]->RemoveObserver(this);
    662         }
    663       }
    664 #endif
    665     }
    666   }
    667 
    668   // Overridden WindowTreeHostObserver:
    669   virtual void OnHostMoved(const aura::WindowTreeHost* host,
    670                            const gfx::Point& new_origin) OVERRIDE {
    671     TRACE_EVENT1("ui",
    672                  "WebContentsViewAura::WindowObserver::OnHostMoved",
    673                  "new_origin", new_origin.ToString());
    674 
    675     // This is for the desktop case (i.e. Aura desktop).
    676     SendScreenRects();
    677   }
    678 
    679  private:
    680   void SendScreenRects() {
    681     RenderWidgetHostImpl::From(view_->web_contents_->GetRenderViewHost())->
    682         SendScreenRects();
    683   }
    684 
    685 #if defined(OS_WIN)
    686   void UpdateConstrainedWindows(aura::Window* exclude) {
    687     RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
    688         view_->web_contents_->GetRenderWidgetHostView());
    689     if (!view)
    690       return;
    691 
    692     std::vector<gfx::Rect> constrained_windows;
    693     if (host_window_) {
    694       const aura::Window::Windows& children = host_window_->children();
    695       for (size_t i = 0; i < children.size(); ++i) {
    696         if (!children[i]->Contains(view_->window_.get()) &&
    697             children[i] != exclude &&
    698             children[i]->IsVisible()) {
    699           constrained_windows.push_back(children[i]->GetBoundsInRootWindow());
    700         }
    701       }
    702     }
    703 
    704     aura::Window* root_window = view_->window_->GetRootWindow();
    705     const aura::Window::Windows& root_children = root_window->children();
    706     if (root_window) {
    707       for (size_t i = 0; i < root_children.size(); ++i) {
    708         if (root_children[i]->IsVisible() &&
    709             !root_children[i]->Contains(view_->window_.get())) {
    710           constrained_windows.push_back(
    711               root_children[i]->GetBoundsInRootWindow());
    712         }
    713       }
    714     }
    715 
    716     view->UpdateConstrainedWindowRects(constrained_windows);
    717   }
    718 #endif
    719 
    720   WebContentsViewAura* view_;
    721 
    722   // The parent window that hosts the constrained windows. We cache the old host
    723   // view so that we can unregister when it's not the parent anymore.
    724   aura::Window* host_window_;
    725 
    726   DISALLOW_COPY_AND_ASSIGN(WindowObserver);
    727 };
    728 
    729 ////////////////////////////////////////////////////////////////////////////////
    730 // WebContentsViewAura, public:
    731 
    732 WebContentsViewAura::WebContentsViewAura(
    733     WebContentsImpl* web_contents,
    734     WebContentsViewDelegate* delegate)
    735     : web_contents_(web_contents),
    736       delegate_(delegate),
    737       current_drag_op_(blink::WebDragOperationNone),
    738       drag_dest_delegate_(NULL),
    739       current_rvh_for_drag_(NULL),
    740       overscroll_change_brightness_(false),
    741       current_overscroll_gesture_(OVERSCROLL_NONE),
    742       completed_overscroll_gesture_(OVERSCROLL_NONE),
    743       touch_editable_(TouchEditableImplAura::Create()),
    744       is_or_was_visible_(false) {
    745 }
    746 
    747 ////////////////////////////////////////////////////////////////////////////////
    748 // WebContentsViewAura, private:
    749 
    750 WebContentsViewAura::~WebContentsViewAura() {
    751   if (!window_)
    752     return;
    753 
    754   window_observer_.reset();
    755   window_->RemoveObserver(this);
    756 
    757   // Window needs a valid delegate during its destructor, so we explicitly
    758   // delete it here.
    759   window_.reset();
    760 }
    761 
    762 void WebContentsViewAura::SetTouchEditableForTest(
    763     TouchEditableImplAura* touch_editable) {
    764   touch_editable_.reset(touch_editable);
    765   AttachTouchEditableToRenderView();
    766 }
    767 
    768 void WebContentsViewAura::SizeChangedCommon(const gfx::Size& size) {
    769   if (web_contents_->GetInterstitialPage())
    770     web_contents_->GetInterstitialPage()->SetSize(size);
    771   RenderWidgetHostView* rwhv =
    772       web_contents_->GetRenderWidgetHostView();
    773   if (rwhv)
    774     rwhv->SetSize(size);
    775 }
    776 
    777 void WebContentsViewAura::EndDrag(blink::WebDragOperationsMask ops) {
    778   aura::Window* root_window = GetNativeView()->GetRootWindow();
    779   gfx::Point screen_loc =
    780       gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
    781   gfx::Point client_loc = screen_loc;
    782   RenderViewHost* rvh = web_contents_->GetRenderViewHost();
    783   aura::Window* window = rvh->GetView()->GetNativeView();
    784   aura::Window::ConvertPointToTarget(root_window, window, &client_loc);
    785   if (!web_contents_)
    786     return;
    787   web_contents_->DragSourceEndedAt(client_loc.x(), client_loc.y(),
    788       screen_loc.x(), screen_loc.y(), ops);
    789 }
    790 
    791 void WebContentsViewAura::InstallOverscrollControllerDelegate(
    792     RenderWidgetHostViewAura* view) {
    793   const std::string value = base::CommandLine::ForCurrentProcess()->
    794       GetSwitchValueASCII(switches::kOverscrollHistoryNavigation);
    795   if (value == "0") {
    796     navigation_overlay_.reset();
    797     return;
    798   }
    799   if (value == "2") {
    800     navigation_overlay_.reset();
    801     if (!gesture_nav_simple_)
    802       gesture_nav_simple_.reset(new GestureNavSimple(web_contents_));
    803     view->overscroll_controller()->set_delegate(gesture_nav_simple_.get());
    804     return;
    805   }
    806   view->overscroll_controller()->set_delegate(this);
    807   if (!navigation_overlay_)
    808     navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_));
    809 }
    810 
    811 void WebContentsViewAura::PrepareOverscrollWindow() {
    812   // If there is an existing |overscroll_window_| which is in the middle of an
    813   // animation, then destroying the window here causes the animation to be
    814   // completed immediately, which triggers |OnImplicitAnimationsCompleted()|
    815   // callback, and that tries to reset |overscroll_window_| again, causing a
    816   // double-free. So use a temporary variable here.
    817   if (overscroll_window_) {
    818     base::AutoReset<OverscrollMode> reset_state(&current_overscroll_gesture_,
    819                                                 current_overscroll_gesture_);
    820     scoped_ptr<aura::Window> reset_window(overscroll_window_.release());
    821   }
    822 
    823   OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate(
    824       web_contents_,
    825       current_overscroll_gesture_);
    826   overscroll_window_.reset(new aura::Window(overscroll_delegate));
    827   overscroll_window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
    828   overscroll_window_->SetTransparent(true);
    829   overscroll_window_->Init(aura::WINDOW_LAYER_TEXTURED);
    830   overscroll_window_->layer()->SetMasksToBounds(false);
    831   overscroll_window_->SetName("OverscrollOverlay");
    832 
    833   overscroll_change_brightness_ = overscroll_delegate->has_image();
    834   window_->AddChild(overscroll_window_.get());
    835 
    836   gfx::Rect bounds = gfx::Rect(window_->bounds().size());
    837   if (ShouldNavigateForward(web_contents_->GetController(),
    838                             current_overscroll_gesture_)) {
    839     // The overlay will be sliding in from the right edge towards the left in
    840     // non-RTL, or sliding in from the left edge towards the right in RTL.
    841     // So position the overlay window accordingly.
    842     bounds.Offset(base::i18n::IsRTL() ? -bounds.width() : bounds.width(), 0);
    843   }
    844 
    845   aura::Window* animate_window = GetWindowToAnimateForOverscroll();
    846   if (animate_window == overscroll_window_)
    847     window_->StackChildAbove(overscroll_window_.get(), GetContentNativeView());
    848   else
    849     window_->StackChildBelow(overscroll_window_.get(), GetContentNativeView());
    850 
    851   UpdateOverscrollWindowBrightness(0.f);
    852 
    853   overscroll_window_->SetBounds(bounds);
    854   overscroll_window_->Show();
    855 
    856   overscroll_shadow_.reset(new ShadowLayerDelegate(animate_window->layer()));
    857 }
    858 
    859 void WebContentsViewAura::PrepareContentWindowForOverscroll() {
    860   StopObservingImplicitAnimations();
    861   aura::Window* content = GetContentNativeView();
    862   content->layer()->GetAnimator()->AbortAllAnimations();
    863   content->SetTransform(gfx::Transform());
    864   content->layer()->SetLayerBrightness(0.f);
    865 }
    866 
    867 void WebContentsViewAura::ResetOverscrollTransform() {
    868   if (!web_contents_->GetRenderWidgetHostView())
    869     return;
    870   aura::Window* target = GetWindowToAnimateForOverscroll();
    871   if (!target)
    872     return;
    873   {
    874     ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
    875     settings.SetPreemptionStrategy(
    876         ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
    877     settings.SetTweenType(gfx::Tween::EASE_OUT);
    878     settings.AddObserver(this);
    879     target->SetTransform(gfx::Transform());
    880   }
    881   {
    882     ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
    883     settings.SetPreemptionStrategy(
    884         ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
    885     settings.SetTweenType(gfx::Tween::EASE_OUT);
    886     UpdateOverscrollWindowBrightness(0.f);
    887   }
    888 }
    889 
    890 void WebContentsViewAura::CompleteOverscrollNavigation(OverscrollMode mode) {
    891   if (!web_contents_->GetRenderWidgetHostView())
    892     return;
    893 
    894   // Animate out the current view first. Navigate to the requested history at
    895   // the end of the animation.
    896   if (current_overscroll_gesture_ == OVERSCROLL_NONE)
    897     return;
    898 
    899   UMA_HISTOGRAM_ENUMERATION("Overscroll.Navigated",
    900                             current_overscroll_gesture_, OVERSCROLL_COUNT);
    901   OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>(
    902       overscroll_window_->delegate());
    903   delegate->stop_forwarding_events();
    904 
    905   completed_overscroll_gesture_ = mode;
    906   aura::Window* target = GetWindowToAnimateForOverscroll();
    907   ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
    908   settings.SetPreemptionStrategy(
    909       ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
    910   settings.SetTweenType(gfx::Tween::EASE_OUT);
    911   settings.AddObserver(this);
    912   gfx::Transform transform;
    913   int content_width =
    914       web_contents_->GetRenderWidgetHostView()->GetViewBounds().width();
    915   int translate_x = mode == OVERSCROLL_WEST ? -content_width : content_width;
    916   transform.Translate(translate_x, 0);
    917   target->SetTransform(transform);
    918   UpdateOverscrollWindowBrightness(translate_x);
    919 }
    920 
    921 aura::Window* WebContentsViewAura::GetWindowToAnimateForOverscroll() {
    922   if (current_overscroll_gesture_ == OVERSCROLL_NONE)
    923     return NULL;
    924 
    925   return ShouldNavigateForward(web_contents_->GetController(),
    926                                current_overscroll_gesture_) ?
    927       overscroll_window_.get() : GetContentNativeView();
    928 }
    929 
    930 gfx::Vector2d WebContentsViewAura::GetTranslationForOverscroll(int delta_x,
    931                                                                int delta_y) {
    932   if (current_overscroll_gesture_ == OVERSCROLL_NORTH ||
    933       current_overscroll_gesture_ == OVERSCROLL_SOUTH) {
    934     return gfx::Vector2d(0, delta_y);
    935   }
    936   // For horizontal overscroll, scroll freely if a navigation is possible. Do a
    937   // resistive scroll otherwise.
    938   const NavigationControllerImpl& controller = web_contents_->GetController();
    939   const gfx::Rect& bounds = GetViewBounds();
    940   if (ShouldNavigateForward(controller, current_overscroll_gesture_))
    941     return gfx::Vector2d(std::max(-bounds.width(), delta_x), 0);
    942   else if (ShouldNavigateBack(controller, current_overscroll_gesture_))
    943     return gfx::Vector2d(std::min(bounds.width(), delta_x), 0);
    944   return gfx::Vector2d();
    945 }
    946 
    947 void WebContentsViewAura::PrepareOverscrollNavigationOverlay() {
    948   OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>(
    949       overscroll_window_->delegate());
    950   overscroll_window_->SchedulePaintInRect(
    951       gfx::Rect(overscroll_window_->bounds().size()));
    952   overscroll_window_->SetBounds(gfx::Rect(window_->bounds().size()));
    953   overscroll_window_->SetTransform(gfx::Transform());
    954   navigation_overlay_->SetOverlayWindow(overscroll_window_.Pass(),
    955                                         delegate);
    956   navigation_overlay_->StartObserving();
    957 }
    958 
    959 void WebContentsViewAura::UpdateOverscrollWindowBrightness(float delta_x) {
    960   if (!overscroll_change_brightness_)
    961     return;
    962 
    963   const float kBrightnessMin = -.1f;
    964   const float kBrightnessMax = -.01f;
    965 
    966   float ratio = fabs(delta_x) / GetViewBounds().width();
    967   ratio = std::min(1.f, ratio);
    968   if (base::i18n::IsRTL())
    969     ratio = 1.f - ratio;
    970   float brightness = current_overscroll_gesture_ == OVERSCROLL_WEST ?
    971       kBrightnessMin + ratio * (kBrightnessMax - kBrightnessMin) :
    972       kBrightnessMax - ratio * (kBrightnessMax - kBrightnessMin);
    973   brightness = std::max(kBrightnessMin, brightness);
    974   brightness = std::min(kBrightnessMax, brightness);
    975   aura::Window* window = GetWindowToAnimateForOverscroll();
    976   window->layer()->SetLayerBrightness(brightness);
    977 }
    978 
    979 void WebContentsViewAura::AttachTouchEditableToRenderView() {
    980   if (!touch_editable_)
    981     return;
    982   RenderWidgetHostViewAura* rwhva = ToRenderWidgetHostViewAura(
    983       web_contents_->GetRenderWidgetHostView());
    984   touch_editable_->AttachToView(rwhva);
    985 }
    986 
    987 void WebContentsViewAura::OverscrollUpdateForWebContentsDelegate(int delta_y) {
    988   if (web_contents_->GetDelegate() && IsScrollEndEffectEnabled())
    989     web_contents_->GetDelegate()->OverscrollUpdate(delta_y);
    990 }
    991 
    992 ////////////////////////////////////////////////////////////////////////////////
    993 // WebContentsViewAura, WebContentsView implementation:
    994 
    995 gfx::NativeView WebContentsViewAura::GetNativeView() const {
    996   return window_.get();
    997 }
    998 
    999 gfx::NativeView WebContentsViewAura::GetContentNativeView() const {
   1000   RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
   1001   return rwhv ? rwhv->GetNativeView() : NULL;
   1002 }
   1003 
   1004 gfx::NativeWindow WebContentsViewAura::GetTopLevelNativeWindow() const {
   1005   return window_->GetToplevelWindow();
   1006 }
   1007 
   1008 void WebContentsViewAura::GetContainerBounds(gfx::Rect *out) const {
   1009   *out = window_->GetBoundsInScreen();
   1010 }
   1011 
   1012 void WebContentsViewAura::SizeContents(const gfx::Size& size) {
   1013   gfx::Rect bounds = window_->bounds();
   1014   if (bounds.size() != size) {
   1015     bounds.set_size(size);
   1016     window_->SetBounds(bounds);
   1017   } else {
   1018     // Our size matches what we want but the renderers size may not match.
   1019     // Pretend we were resized so that the renderers size is updated too.
   1020     SizeChangedCommon(size);
   1021   }
   1022 }
   1023 
   1024 void WebContentsViewAura::Focus() {
   1025   if (web_contents_->GetInterstitialPage()) {
   1026     web_contents_->GetInterstitialPage()->Focus();
   1027     return;
   1028   }
   1029 
   1030   if (delegate_.get() && delegate_->Focus())
   1031     return;
   1032 
   1033   RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
   1034   if (rwhv)
   1035     rwhv->Focus();
   1036 }
   1037 
   1038 void WebContentsViewAura::SetInitialFocus() {
   1039   if (web_contents_->FocusLocationBarByDefault())
   1040     web_contents_->SetFocusToLocationBar(false);
   1041   else
   1042     Focus();
   1043 }
   1044 
   1045 void WebContentsViewAura::StoreFocus() {
   1046   if (delegate_)
   1047     delegate_->StoreFocus();
   1048 }
   1049 
   1050 void WebContentsViewAura::RestoreFocus() {
   1051   if (delegate_)
   1052     delegate_->RestoreFocus();
   1053 }
   1054 
   1055 DropData* WebContentsViewAura::GetDropData() const {
   1056   return current_drop_data_.get();
   1057 }
   1058 
   1059 gfx::Rect WebContentsViewAura::GetViewBounds() const {
   1060   return window_->GetBoundsInScreen();
   1061 }
   1062 
   1063 ////////////////////////////////////////////////////////////////////////////////
   1064 // WebContentsViewAura, WebContentsView implementation:
   1065 
   1066 void WebContentsViewAura::CreateView(
   1067     const gfx::Size& initial_size, gfx::NativeView context) {
   1068   // NOTE: we ignore |initial_size| since in some cases it's wrong (such as
   1069   // if the bookmark bar is not shown and you create a new tab). The right
   1070   // value is set shortly after this, so its safe to ignore.
   1071 
   1072   aura::Env::CreateInstance(true);
   1073   window_.reset(new aura::Window(this));
   1074   window_->set_owned_by_parent(false);
   1075   window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
   1076   window_->SetTransparent(false);
   1077   window_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
   1078   window_->AddObserver(this);
   1079   aura::Window* root_window = context ? context->GetRootWindow() : NULL;
   1080   if (root_window) {
   1081     // There are places where there is no context currently because object
   1082     // hierarchies are built before they're attached to a Widget. (See
   1083     // views::WebView as an example; GetWidget() returns NULL at the point
   1084     // where we are created.)
   1085     //
   1086     // It should be OK to not set a default parent since such users will
   1087     // explicitly add this WebContentsViewAura to their tree after they create
   1088     // us.
   1089     if (root_window) {
   1090       aura::client::ParentWindowWithContext(
   1091           window_.get(), root_window, root_window->GetBoundsInScreen());
   1092     }
   1093   }
   1094   window_->layer()->SetMasksToBounds(true);
   1095   window_->SetName("WebContentsViewAura");
   1096 
   1097   // WindowObserver is not interesting and is problematic for Browser Plugin
   1098   // guests.
   1099   // The use cases for WindowObserver do not apply to Browser Plugins:
   1100   // 1) guests do not support NPAPI plugins.
   1101   // 2) guests' window bounds are supposed to come from its embedder.
   1102   if (!BrowserPluginGuest::IsGuest(web_contents_))
   1103     window_observer_.reset(new WindowObserver(this));
   1104 
   1105   // delegate_->GetDragDestDelegate() creates a new delegate on every call.
   1106   // Hence, we save a reference to it locally. Similar model is used on other
   1107   // platforms as well.
   1108   if (delegate_)
   1109     drag_dest_delegate_ = delegate_->GetDragDestDelegate();
   1110 }
   1111 
   1112 RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget(
   1113     RenderWidgetHost* render_widget_host) {
   1114   if (render_widget_host->GetView()) {
   1115     // During testing, the view will already be set up in most cases to the
   1116     // test view, so we don't want to clobber it with a real one. To verify that
   1117     // this actually is happening (and somebody isn't accidentally creating the
   1118     // view twice), we check for the RVH Factory, which will be set when we're
   1119     // making special ones (which go along with the special views).
   1120     DCHECK(RenderViewHostFactory::has_factory());
   1121     return static_cast<RenderWidgetHostViewBase*>(
   1122         render_widget_host->GetView());
   1123   }
   1124 
   1125   RenderWidgetHostViewAura* view =
   1126       new RenderWidgetHostViewAura(render_widget_host);
   1127   view->InitAsChild(NULL);
   1128   GetNativeView()->AddChild(view->GetNativeView());
   1129 
   1130   if (navigation_overlay_.get() && navigation_overlay_->has_window()) {
   1131     navigation_overlay_->StartObserving();
   1132   }
   1133 
   1134   RenderWidgetHostImpl* host_impl =
   1135       RenderWidgetHostImpl::From(render_widget_host);
   1136 
   1137   if (!host_impl->is_hidden())
   1138     view->Show();
   1139 
   1140   // We listen to drag drop events in the newly created view's window.
   1141   aura::client::SetDragDropDelegate(view->GetNativeView(), this);
   1142 
   1143   if (view->overscroll_controller() &&
   1144       (!web_contents_->GetDelegate() ||
   1145        web_contents_->GetDelegate()->CanOverscrollContent())) {
   1146     InstallOverscrollControllerDelegate(view);
   1147   }
   1148 
   1149   AttachTouchEditableToRenderView();
   1150   return view;
   1151 }
   1152 
   1153 RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForPopupWidget(
   1154     RenderWidgetHost* render_widget_host) {
   1155   return new RenderWidgetHostViewAura(render_widget_host);
   1156 }
   1157 
   1158 void WebContentsViewAura::SetPageTitle(const base::string16& title) {
   1159   window_->SetTitle(title);
   1160 }
   1161 
   1162 void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) {
   1163 }
   1164 
   1165 void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) {
   1166   if (navigation_overlay_.get() && navigation_overlay_->has_window())
   1167     navigation_overlay_->StartObserving();
   1168   AttachTouchEditableToRenderView();
   1169 }
   1170 
   1171 void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) {
   1172   RenderWidgetHostViewAura* view =
   1173       ToRenderWidgetHostViewAura(web_contents_->GetRenderWidgetHostView());
   1174   if (view) {
   1175     view->SetOverscrollControllerEnabled(enabled);
   1176     if (enabled)
   1177       InstallOverscrollControllerDelegate(view);
   1178   }
   1179 
   1180   if (!enabled)
   1181     navigation_overlay_.reset();
   1182   else if (!navigation_overlay_)
   1183     navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_));
   1184 }
   1185 
   1186 ////////////////////////////////////////////////////////////////////////////////
   1187 // WebContentsViewAura, RenderViewHostDelegateView implementation:
   1188 
   1189 void WebContentsViewAura::ShowContextMenu(RenderFrameHost* render_frame_host,
   1190                                           const ContextMenuParams& params) {
   1191   if (touch_editable_) {
   1192     touch_editable_->EndTouchEditing(false);
   1193   }
   1194   if (delegate_) {
   1195     delegate_->ShowContextMenu(render_frame_host, params);
   1196     // WARNING: we may have been deleted during the call to ShowContextMenu().
   1197   }
   1198 }
   1199 
   1200 void WebContentsViewAura::StartDragging(
   1201     const DropData& drop_data,
   1202     blink::WebDragOperationsMask operations,
   1203     const gfx::ImageSkia& image,
   1204     const gfx::Vector2d& image_offset,
   1205     const DragEventSourceInfo& event_info) {
   1206   aura::Window* root_window = GetNativeView()->GetRootWindow();
   1207   if (!aura::client::GetDragDropClient(root_window)) {
   1208     web_contents_->SystemDragEnded();
   1209     return;
   1210   }
   1211 
   1212   if (touch_editable_)
   1213     touch_editable_->EndTouchEditing(false);
   1214 
   1215   ui::OSExchangeData::Provider* provider = ui::OSExchangeData::CreateProvider();
   1216   PrepareDragData(drop_data, provider, web_contents_);
   1217 
   1218   ui::OSExchangeData data(provider);  // takes ownership of |provider|.
   1219 
   1220   if (!image.isNull())
   1221     drag_utils::SetDragImageOnDataObject(image, image_offset, &data);
   1222 
   1223   scoped_ptr<WebDragSourceAura> drag_source(
   1224       new WebDragSourceAura(GetNativeView(), web_contents_));
   1225 
   1226   // We need to enable recursive tasks on the message loop so we can get
   1227   // updates while in the system DoDragDrop loop.
   1228   int result_op = 0;
   1229   {
   1230     gfx::NativeView content_native_view = GetContentNativeView();
   1231     base::MessageLoop::ScopedNestableTaskAllower allow(
   1232         base::MessageLoop::current());
   1233     result_op = aura::client::GetDragDropClient(root_window)
   1234         ->StartDragAndDrop(data,
   1235                            root_window,
   1236                            content_native_view,
   1237                            event_info.event_location,
   1238                            ConvertFromWeb(operations),
   1239                            event_info.event_source);
   1240   }
   1241 
   1242   // Bail out immediately if the contents view window is gone. Note that it is
   1243   // not safe to access any class members in this case since |this| may already
   1244   // be destroyed. The local variable |drag_source| will still be valid though,
   1245   // so we can use it to determine if the window is gone.
   1246   if (!drag_source->window()) {
   1247     // Note that in this case, we don't need to call SystemDragEnded() since the
   1248     // renderer is going away.
   1249     return;
   1250   }
   1251 
   1252   EndDrag(ConvertToWeb(result_op));
   1253   web_contents_->SystemDragEnded();
   1254 }
   1255 
   1256 void WebContentsViewAura::UpdateDragCursor(blink::WebDragOperation operation) {
   1257   current_drag_op_ = operation;
   1258 }
   1259 
   1260 void WebContentsViewAura::GotFocus() {
   1261   if (web_contents_->GetDelegate())
   1262     web_contents_->GetDelegate()->WebContentsFocused(web_contents_);
   1263 }
   1264 
   1265 void WebContentsViewAura::TakeFocus(bool reverse) {
   1266   if (web_contents_->GetDelegate() &&
   1267       !web_contents_->GetDelegate()->TakeFocus(web_contents_, reverse) &&
   1268       delegate_.get()) {
   1269     delegate_->TakeFocus(reverse);
   1270   }
   1271 }
   1272 
   1273 void WebContentsViewAura::ShowDisambiguationPopup(
   1274     const gfx::Rect& target_rect,
   1275     const SkBitmap& zoomed_bitmap,
   1276     const base::Callback<void(ui::GestureEvent*)>& gesture_cb,
   1277     const base::Callback<void(ui::MouseEvent*)>& mouse_cb) {
   1278   if (delegate_) {
   1279     delegate_->ShowDisambiguationPopup(target_rect, zoomed_bitmap,
   1280         window_.get(), gesture_cb, mouse_cb);
   1281   }
   1282 }
   1283 
   1284 void WebContentsViewAura::HideDisambiguationPopup() {
   1285   if (delegate_)
   1286     delegate_->HideDisambiguationPopup();
   1287 }
   1288 
   1289 ////////////////////////////////////////////////////////////////////////////////
   1290 // WebContentsViewAura, OverscrollControllerDelegate implementation:
   1291 
   1292 gfx::Rect WebContentsViewAura::GetVisibleBounds() const {
   1293   RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
   1294   if (!rwhv || !rwhv->IsShowing())
   1295     return gfx::Rect();
   1296 
   1297   return rwhv->GetViewBounds();
   1298 }
   1299 
   1300 bool WebContentsViewAura::OnOverscrollUpdate(float delta_x, float delta_y) {
   1301   if (current_overscroll_gesture_ == OVERSCROLL_NONE)
   1302     return false;
   1303 
   1304   aura::Window* target = GetWindowToAnimateForOverscroll();
   1305   gfx::Vector2d translate = GetTranslationForOverscroll(delta_x, delta_y);
   1306   gfx::Transform transform;
   1307 
   1308   if (current_overscroll_gesture_ == OVERSCROLL_NORTH ||
   1309       current_overscroll_gesture_ == OVERSCROLL_SOUTH) {
   1310     OverscrollUpdateForWebContentsDelegate(translate.y());
   1311   } else {
   1312     // Only horizontal overscrolls participate in the navigation gesture.
   1313     transform.Translate(translate.x(), translate.y());
   1314     target->SetTransform(transform);
   1315     UpdateOverscrollWindowBrightness(delta_x);
   1316   }
   1317 
   1318   return !translate.IsZero();
   1319 }
   1320 
   1321 void WebContentsViewAura::OnOverscrollComplete(OverscrollMode mode) {
   1322   UMA_HISTOGRAM_ENUMERATION("Overscroll.Completed", mode, OVERSCROLL_COUNT);
   1323   if (web_contents_->GetDelegate() &&
   1324       IsScrollEndEffectEnabled() &&
   1325       (mode == OVERSCROLL_NORTH || mode == OVERSCROLL_SOUTH)) {
   1326     web_contents_->GetDelegate()->OverscrollComplete();
   1327   }
   1328   NavigationControllerImpl& controller = web_contents_->GetController();
   1329   if (ShouldNavigateForward(controller, mode) ||
   1330       ShouldNavigateBack(controller, mode)) {
   1331     CompleteOverscrollNavigation(mode);
   1332     return;
   1333   }
   1334 
   1335   ResetOverscrollTransform();
   1336 }
   1337 
   1338 void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode,
   1339                                                  OverscrollMode new_mode) {
   1340   // Reset any in-progress overscroll animation first.
   1341   ResetOverscrollTransform();
   1342 
   1343   if (old_mode == OVERSCROLL_NORTH || old_mode == OVERSCROLL_SOUTH)
   1344     OverscrollUpdateForWebContentsDelegate(0);
   1345 
   1346   if (new_mode != OVERSCROLL_NONE && touch_editable_)
   1347     touch_editable_->OverscrollStarted();
   1348 
   1349   if (new_mode == OVERSCROLL_NONE ||
   1350       !GetContentNativeView() ||
   1351       ((new_mode == OVERSCROLL_EAST || new_mode == OVERSCROLL_WEST) &&
   1352        navigation_overlay_.get() && navigation_overlay_->has_window())) {
   1353     current_overscroll_gesture_ = OVERSCROLL_NONE;
   1354   } else {
   1355     aura::Window* target = GetWindowToAnimateForOverscroll();
   1356     if (target) {
   1357       StopObservingImplicitAnimations();
   1358       target->layer()->GetAnimator()->AbortAllAnimations();
   1359     }
   1360     // Cleanup state of the content window first, because that can reset the
   1361     // value of |current_overscroll_gesture_|.
   1362     PrepareContentWindowForOverscroll();
   1363 
   1364     current_overscroll_gesture_ = new_mode;
   1365     if (current_overscroll_gesture_ == OVERSCROLL_EAST ||
   1366         current_overscroll_gesture_ == OVERSCROLL_WEST)
   1367       PrepareOverscrollWindow();
   1368 
   1369     UMA_HISTOGRAM_ENUMERATION("Overscroll.Started", new_mode, OVERSCROLL_COUNT);
   1370   }
   1371   completed_overscroll_gesture_ = OVERSCROLL_NONE;
   1372 }
   1373 
   1374 ////////////////////////////////////////////////////////////////////////////////
   1375 // WebContentsViewAura, ui::ImplicitAnimationObserver implementation:
   1376 
   1377 void WebContentsViewAura::OnImplicitAnimationsCompleted() {
   1378   overscroll_shadow_.reset();
   1379 
   1380   if (ShouldNavigateForward(web_contents_->GetController(),
   1381                             completed_overscroll_gesture_)) {
   1382     web_contents_->GetController().GoForward();
   1383     PrepareOverscrollNavigationOverlay();
   1384   } else if (ShouldNavigateBack(web_contents_->GetController(),
   1385                                 completed_overscroll_gesture_)) {
   1386     web_contents_->GetController().GoBack();
   1387     PrepareOverscrollNavigationOverlay();
   1388   } else {
   1389     if (touch_editable_)
   1390       touch_editable_->OverscrollCompleted();
   1391   }
   1392 
   1393   aura::Window* content = GetContentNativeView();
   1394   if (content) {
   1395     content->SetTransform(gfx::Transform());
   1396     content->layer()->SetLayerBrightness(0.f);
   1397   }
   1398   current_overscroll_gesture_ = OVERSCROLL_NONE;
   1399   completed_overscroll_gesture_ = OVERSCROLL_NONE;
   1400   overscroll_window_.reset();
   1401 }
   1402 
   1403 ////////////////////////////////////////////////////////////////////////////////
   1404 // WebContentsViewAura, aura::WindowDelegate implementation:
   1405 
   1406 gfx::Size WebContentsViewAura::GetMinimumSize() const {
   1407   return gfx::Size();
   1408 }
   1409 
   1410 gfx::Size WebContentsViewAura::GetMaximumSize() const {
   1411   return gfx::Size();
   1412 }
   1413 
   1414 void WebContentsViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
   1415                                           const gfx::Rect& new_bounds) {
   1416   SizeChangedCommon(new_bounds.size());
   1417   if (delegate_)
   1418     delegate_->SizeChanged(new_bounds.size());
   1419 
   1420   // Constrained web dialogs, need to be kept centered over our content area.
   1421   for (size_t i = 0; i < window_->children().size(); i++) {
   1422     if (window_->children()[i]->GetProperty(
   1423             aura::client::kConstrainedWindowKey)) {
   1424       gfx::Rect bounds = window_->children()[i]->bounds();
   1425       bounds.set_origin(
   1426           gfx::Point((new_bounds.width() - bounds.width()) / 2,
   1427                      (new_bounds.height() - bounds.height()) / 2));
   1428       window_->children()[i]->SetBounds(bounds);
   1429     }
   1430   }
   1431 }
   1432 
   1433 gfx::NativeCursor WebContentsViewAura::GetCursor(const gfx::Point& point) {
   1434   return gfx::kNullCursor;
   1435 }
   1436 
   1437 int WebContentsViewAura::GetNonClientComponent(const gfx::Point& point) const {
   1438   return HTCLIENT;
   1439 }
   1440 
   1441 bool WebContentsViewAura::ShouldDescendIntoChildForEventHandling(
   1442     aura::Window* child,
   1443     const gfx::Point& location) {
   1444   return true;
   1445 }
   1446 
   1447 bool WebContentsViewAura::CanFocus() {
   1448   // Do not take the focus if the render widget host view aura is gone or
   1449   // is in the process of shutting down because neither the view window nor
   1450   // this window can handle key events.
   1451   RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
   1452       web_contents_->GetRenderWidgetHostView());
   1453   if (view != NULL && !view->IsClosing())
   1454     return true;
   1455 
   1456   return false;
   1457 }
   1458 
   1459 void WebContentsViewAura::OnCaptureLost() {
   1460 }
   1461 
   1462 void WebContentsViewAura::OnPaint(gfx::Canvas* canvas) {
   1463 }
   1464 
   1465 void WebContentsViewAura::OnDeviceScaleFactorChanged(
   1466     float device_scale_factor) {
   1467 }
   1468 
   1469 void WebContentsViewAura::OnWindowDestroying(aura::Window* window) {
   1470   // This means the destructor is going to be called soon. If there is an
   1471   // overscroll gesture in progress (i.e. |overscroll_window_| is not NULL),
   1472   // then destroying it in the WebContentsViewAura destructor can trigger other
   1473   // virtual functions to be called (e.g. OnImplicitAnimationsCompleted()). So
   1474   // destroy the overscroll window here.
   1475   navigation_overlay_.reset();
   1476   overscroll_window_.reset();
   1477 }
   1478 
   1479 void WebContentsViewAura::OnWindowDestroyed(aura::Window* window) {
   1480 }
   1481 
   1482 void WebContentsViewAura::OnWindowTargetVisibilityChanged(bool visible) {
   1483 }
   1484 
   1485 bool WebContentsViewAura::HasHitTestMask() const {
   1486   return false;
   1487 }
   1488 
   1489 void WebContentsViewAura::GetHitTestMask(gfx::Path* mask) const {
   1490 }
   1491 
   1492 ////////////////////////////////////////////////////////////////////////////////
   1493 // WebContentsViewAura, ui::EventHandler implementation:
   1494 
   1495 void WebContentsViewAura::OnKeyEvent(ui::KeyEvent* event) {
   1496 }
   1497 
   1498 void WebContentsViewAura::OnMouseEvent(ui::MouseEvent* event) {
   1499   if (!web_contents_->GetDelegate())
   1500     return;
   1501 
   1502   switch (event->type()) {
   1503     case ui::ET_MOUSE_PRESSED:
   1504       web_contents_->GetDelegate()->ActivateContents(web_contents_);
   1505       break;
   1506     case ui::ET_MOUSE_MOVED:
   1507     case ui::ET_MOUSE_EXITED:
   1508       web_contents_->GetDelegate()->ContentsMouseEvent(
   1509           web_contents_,
   1510           gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(),
   1511           event->type() == ui::ET_MOUSE_MOVED);
   1512       break;
   1513     default:
   1514       break;
   1515   }
   1516 }
   1517 
   1518 ////////////////////////////////////////////////////////////////////////////////
   1519 // WebContentsViewAura, aura::client::DragDropDelegate implementation:
   1520 
   1521 void WebContentsViewAura::OnDragEntered(const ui::DropTargetEvent& event) {
   1522   current_rvh_for_drag_ = web_contents_->GetRenderViewHost();
   1523   current_drop_data_.reset(new DropData());
   1524 
   1525   PrepareDropData(current_drop_data_.get(), event.data());
   1526   blink::WebDragOperationsMask op = ConvertToWeb(event.source_operations());
   1527 
   1528   // Give the delegate an opportunity to cancel the drag.
   1529   if (web_contents_->GetDelegate() &&
   1530       !web_contents_->GetDelegate()->CanDragEnter(
   1531           web_contents_, *current_drop_data_.get(), op)) {
   1532     current_drop_data_.reset(NULL);
   1533     return;
   1534   }
   1535 
   1536   if (drag_dest_delegate_)
   1537     drag_dest_delegate_->DragInitialize(web_contents_);
   1538 
   1539   gfx::Point screen_pt =
   1540       gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
   1541   web_contents_->GetRenderViewHost()->DragTargetDragEnter(
   1542       *current_drop_data_.get(), event.location(), screen_pt, op,
   1543       ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
   1544 
   1545   if (drag_dest_delegate_) {
   1546     drag_dest_delegate_->OnReceiveDragData(event.data());
   1547     drag_dest_delegate_->OnDragEnter();
   1548   }
   1549 }
   1550 
   1551 int WebContentsViewAura::OnDragUpdated(const ui::DropTargetEvent& event) {
   1552   DCHECK(current_rvh_for_drag_);
   1553   if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost())
   1554     OnDragEntered(event);
   1555 
   1556   if (!current_drop_data_)
   1557     return ui::DragDropTypes::DRAG_NONE;
   1558 
   1559   blink::WebDragOperationsMask op = ConvertToWeb(event.source_operations());
   1560   gfx::Point screen_pt =
   1561       gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
   1562   web_contents_->GetRenderViewHost()->DragTargetDragOver(
   1563       event.location(), screen_pt, op,
   1564       ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
   1565 
   1566   if (drag_dest_delegate_)
   1567     drag_dest_delegate_->OnDragOver();
   1568 
   1569   return ConvertFromWeb(current_drag_op_);
   1570 }
   1571 
   1572 void WebContentsViewAura::OnDragExited() {
   1573   DCHECK(current_rvh_for_drag_);
   1574   if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost())
   1575     return;
   1576 
   1577   if (!current_drop_data_)
   1578     return;
   1579 
   1580   web_contents_->GetRenderViewHost()->DragTargetDragLeave();
   1581   if (drag_dest_delegate_)
   1582     drag_dest_delegate_->OnDragLeave();
   1583 
   1584   current_drop_data_.reset();
   1585 }
   1586 
   1587 int WebContentsViewAura::OnPerformDrop(const ui::DropTargetEvent& event) {
   1588   DCHECK(current_rvh_for_drag_);
   1589   if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost())
   1590     OnDragEntered(event);
   1591 
   1592   if (!current_drop_data_)
   1593     return ui::DragDropTypes::DRAG_NONE;
   1594 
   1595   web_contents_->GetRenderViewHost()->DragTargetDrop(
   1596       event.location(),
   1597       gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(),
   1598       ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
   1599   if (drag_dest_delegate_)
   1600     drag_dest_delegate_->OnDrop();
   1601   current_drop_data_.reset();
   1602   return ConvertFromWeb(current_drag_op_);
   1603 }
   1604 
   1605 void WebContentsViewAura::OnWindowVisibilityChanged(aura::Window* window,
   1606                                                     bool visible) {
   1607   // Ignore any visibility changes in the hierarchy below.
   1608   if (window != window_.get() && window_->Contains(window))
   1609     return;
   1610 
   1611   UpdateWebContentsVisibility(visible);
   1612 }
   1613 
   1614 void WebContentsViewAura::UpdateWebContentsVisibility(bool visible) {
   1615   if (!is_or_was_visible_) {
   1616     // We should not hide the web contents before it was shown the first time,
   1617     // since resources would immediately be destroyed and only re-created after
   1618     // content got loaded. In this state the window content is undefined and can
   1619     // show garbage.
   1620     // However - the page load mechanism requires an activation call through a
   1621     // visibility call to (re)load.
   1622     if (visible) {
   1623       is_or_was_visible_ = true;
   1624       web_contents_->WasShown();
   1625     }
   1626     return;
   1627   }
   1628   if (visible) {
   1629     if (!web_contents_->should_normally_be_visible())
   1630       web_contents_->WasShown();
   1631   } else {
   1632     if (web_contents_->should_normally_be_visible())
   1633       web_contents_->WasHidden();
   1634   }
   1635 }
   1636 
   1637 }  // namespace content
   1638