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