Home | History | Annotate | Download | only in views
      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 #ifndef CHROME_BROWSER_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_
      6 #define CHROME_BROWSER_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/compiler_specific.h"
     13 #include "base/lazy_instance.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/memory/weak_ptr.h"
     16 #include "chrome/browser/automation/automation_resource_message_filter.h"
     17 #include "chrome/browser/external_tab/external_tab_container.h"
     18 #include "chrome/browser/infobars/infobar_container.h"
     19 #include "chrome/browser/net/chrome_url_request_context.h"
     20 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper_delegate.h"
     21 #include "content/public/browser/navigation_type.h"
     22 #include "content/public/browser/notification_observer.h"
     23 #include "content/public/browser/notification_registrar.h"
     24 #include "content/public/browser/render_view_host.h"
     25 #include "content/public/browser/web_contents_delegate.h"
     26 #include "content/public/browser/web_contents_observer.h"
     27 #include "ui/base/accelerators/accelerator.h"
     28 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
     29 #include "ui/views/widget/widget_observer.h"
     30 
     31 class AutomationProvider;
     32 class Browser;
     33 class Profile;
     34 class TabContentsContainer;
     35 class RenderViewContextMenuViews;
     36 struct NavigationInfo;
     37 
     38 namespace ui {
     39 class ViewProp;
     40 }
     41 
     42 namespace views {
     43 class View;
     44 class WebView;
     45 class Widget;
     46 }
     47 
     48 #if defined(USE_AURA)
     49 class ContainerWindow;
     50 #endif
     51 
     52 // This class serves as the container window for an external tab.
     53 // An external tab is a Chrome tab that is meant to displayed in an
     54 // external process. This class provides the FocusManger needed by the
     55 // WebContents as well as an implementation of content::WebContentsDelegate.
     56 class ExternalTabContainerWin : public ExternalTabContainer,
     57                                 public content::WebContentsDelegate,
     58                                 public content::WebContentsObserver,
     59                                 public content::NotificationObserver,
     60                                 public views::WidgetObserver,
     61                                 public ui::AcceleratorTarget,
     62                                 public InfoBarContainer::Delegate,
     63                                 public BlockedContentTabHelperDelegate {
     64  public:
     65   typedef std::map<uintptr_t,
     66                    scoped_refptr<ExternalTabContainerWin> > PendingTabs;
     67 
     68   ExternalTabContainerWin(AutomationProvider* automation,
     69                           AutomationResourceMessageFilter* filter);
     70 
     71   static scoped_refptr<ExternalTabContainer> RemovePendingExternalTab(
     72       uintptr_t cookie);
     73 
     74   // Overridden from ExternalTabContainer:
     75   virtual bool Init(Profile* profile,
     76                     HWND parent,
     77                     const gfx::Rect& bounds,
     78                     DWORD style,
     79                     bool load_requests_via_automation,
     80                     bool handle_top_level_requests,
     81                     content::WebContents* existing_contents,
     82                     const GURL& initial_url,
     83                     const GURL& referrer,
     84                     bool infobars_enabled,
     85                     bool supports_full_tab_mode) OVERRIDE;
     86   virtual void Uninitialize() OVERRIDE;
     87   virtual bool Reinitialize(AutomationProvider* automation_provider,
     88                             AutomationResourceMessageFilter* filter,
     89                             HWND parent_window) OVERRIDE;
     90   virtual content::WebContents* GetWebContents() const OVERRIDE;
     91   virtual HWND GetExternalTabHWND() const OVERRIDE;
     92   virtual HWND GetContentHWND() const OVERRIDE;
     93   virtual void SetTabHandle(int handle) OVERRIDE;
     94   virtual int GetTabHandle() const OVERRIDE;
     95   virtual bool ExecuteContextMenuCommand(int command) OVERRIDE;
     96   virtual void RunUnloadHandlers(IPC::Message* reply_message) OVERRIDE;
     97   virtual void ProcessUnhandledAccelerator(const MSG& msg) OVERRIDE;
     98   virtual void FocusThroughTabTraversal(bool reverse,
     99                                         bool restore_focus_to_view) OVERRIDE;
    100 
    101   // Overridden from content::WebContentsDelegate:
    102   virtual content::WebContents* OpenURLFromTab(
    103       content::WebContents* source,
    104       const content::OpenURLParams& params) OVERRIDE;
    105   virtual void NavigationStateChanged(const content::WebContents* source,
    106                                       unsigned changed_flags) OVERRIDE;
    107   virtual void AddNewContents(content::WebContents* source,
    108                               content::WebContents* new_contents,
    109                               WindowOpenDisposition disposition,
    110                               const gfx::Rect& initial_pos,
    111                               bool user_gesture,
    112                               bool* was_blocked) OVERRIDE;
    113   virtual void CloseContents(content::WebContents* source) OVERRIDE;
    114   virtual void MoveContents(content::WebContents* source,
    115                             const gfx::Rect& pos) OVERRIDE;
    116   virtual bool IsPopupOrPanel(
    117       const content::WebContents* source) const OVERRIDE;
    118   virtual void UpdateTargetURL(content::WebContents* source, int32 page_id,
    119                                const GURL& url) OVERRIDE;
    120   virtual void ContentsZoomChange(bool zoom_in) OVERRIDE;
    121   virtual void WebContentsCreated(content::WebContents* source_contents,
    122                                   int64 source_frame_id,
    123                                   const string16& frame_name,
    124                                   const GURL& target_url,
    125                                   content::WebContents* new_contents) OVERRIDE;
    126   virtual bool PreHandleKeyboardEvent(
    127       content::WebContents* source,
    128       const content::NativeWebKeyboardEvent& event,
    129       bool* is_keyboard_shortcut) OVERRIDE;
    130   virtual void HandleKeyboardEvent(
    131       content::WebContents* source,
    132       const content::NativeWebKeyboardEvent& event) OVERRIDE;
    133   virtual bool TakeFocus(content::WebContents* source, bool reverse) OVERRIDE;
    134   virtual void WebContentsFocused(content::WebContents* contents) OVERRIDE;
    135   virtual void CanDownload(content::RenderViewHost* render_view_host,
    136                            int request_id,
    137                            const std::string& request_method,
    138                            const base::Callback<void(bool)>& callback) OVERRIDE;
    139   virtual bool OnGoToEntryOffset(int offset) OVERRIDE;
    140   virtual bool HandleContextMenu(
    141       const content::ContextMenuParams& params) OVERRIDE;
    142   virtual void BeforeUnloadFired(content::WebContents* tab,
    143                                  bool proceed,
    144                                  bool* proceed_to_fire_unload) OVERRIDE;
    145   virtual content::JavaScriptDialogManager*
    146       GetJavaScriptDialogManager() OVERRIDE;
    147   virtual void ShowRepostFormWarningDialog(
    148       content::WebContents* source) OVERRIDE;
    149   virtual content::ColorChooser* OpenColorChooser(
    150       content::WebContents* web_contents, SkColor color) OVERRIDE;
    151   virtual void RunFileChooser(
    152       content::WebContents* tab,
    153       const content::FileChooserParams& params) OVERRIDE;
    154   virtual void EnumerateDirectory(content::WebContents* tab,
    155                                   int request_id,
    156                                   const base::FilePath& path) OVERRIDE;
    157   virtual void JSOutOfMemory(content::WebContents* tab);
    158   virtual void RegisterProtocolHandler(content::WebContents* tab,
    159                                        const std::string& protocol,
    160                                        const GURL& url,
    161                                        const string16& title,
    162                                        bool user_gesture) OVERRIDE;
    163   virtual void FindReply(content::WebContents* tab,
    164                          int request_id,
    165                          int number_of_matches,
    166                          const gfx::Rect& selection_rect,
    167                          int active_match_ordinal,
    168                          bool final_update) OVERRIDE;
    169   virtual void RequestMediaAccessPermission(
    170       content::WebContents* web_contents,
    171       const content::MediaStreamRequest& request,
    172       const content::MediaResponseCallback& callback) OVERRIDE;
    173   virtual bool RequestPpapiBrokerPermission(
    174       content::WebContents* web_contents,
    175       const GURL& url,
    176       const base::FilePath& plugin_path,
    177       const base::Callback<void(bool)>& callback) OVERRIDE;
    178 
    179   void RegisterRenderViewHost(content::RenderViewHost* render_view_host);
    180   void UnregisterRenderViewHost(content::RenderViewHost* render_view_host);
    181 
    182   // Overridden from content::WebContentsObserver:
    183   virtual void RenderViewDeleted(
    184       content::RenderViewHost* render_view_host) OVERRIDE;
    185   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
    186   virtual void DidFailProvisionalLoad(
    187       int64 frame_id,
    188       bool is_main_frame,
    189       const GURL& validated_url,
    190       int error_code,
    191       const string16& error_description,
    192       content::RenderViewHost* render_view_host) OVERRIDE;
    193 
    194   // Message handlers
    195   void OnForwardMessageToExternalHost(const std::string& message,
    196                                       const std::string& origin,
    197                                       const std::string& target);
    198 
    199   // Overridden from content::NotificationObserver:
    200   virtual void Observe(int type,
    201                        const content::NotificationSource& source,
    202                        const content::NotificationDetails& details);
    203 
    204   // Overridden from ui::AcceleratorTarget:
    205   virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
    206   virtual bool CanHandleAccelerators() const OVERRIDE;
    207 
    208   void set_pending(bool pending) { pending_ = pending; }
    209   bool pending() const { return pending_; }
    210 
    211   void set_is_popup_window(bool is_popup_window) {
    212     is_popup_window_ = is_popup_window;
    213   }
    214 
    215   // Overridden from InfoBarContainer::Delegate:
    216   virtual SkColor GetInfoBarSeparatorColor() const OVERRIDE;
    217   virtual void InfoBarContainerStateChanged(bool is_animating) OVERRIDE;
    218   virtual bool DrawInfoBarArrows(int* x) const OVERRIDE;
    219 
    220   // Overridden from BlockedContentTabHelperDelegate:
    221   virtual content::WebContents* GetConstrainingWebContents(
    222       content::WebContents* source) OVERRIDE;
    223 
    224  protected:
    225   virtual ~ExternalTabContainerWin();
    226 
    227   // WidgetObserver overrides.
    228   virtual void OnWidgetCreated(views::Widget* widget) OVERRIDE;
    229   virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
    230   virtual void OnWidgetDestroyed(views::Widget* widget) OVERRIDE;
    231 
    232   bool InitNavigationInfo(NavigationInfo* nav_info,
    233                           content::NavigationType nav_type,
    234                           int relative_offset);
    235   void Navigate(const GURL& url, const GURL& referrer);
    236 
    237   // Helper resource automation registration method, allowing registration of
    238   // pending RenderViewHosts.
    239   void RegisterRenderViewHostForAutomation(
    240       bool pending_view,
    241       content::RenderViewHost* render_view_host);
    242 
    243   // Helper function for processing keystokes coming back from the renderer
    244   // process.
    245   bool ProcessUnhandledKeyStroke(HWND window, UINT message, WPARAM wparam,
    246                                  LPARAM lparam);
    247 
    248   void LoadAccelerators();
    249 
    250   // Sends over pending Open URL requests to the external host.
    251   void ServicePendingOpenURLRequests();
    252 
    253   // Scheduled as a task in ExternalTabContainerWin::Reinitialize.
    254   void OnReinitialize();
    255 
    256   // Creates and initializes the view hierarchy for this
    257   // ExternalTabContainerWin.
    258   void SetupExternalTabView();
    259 
    260   views::Widget* widget_;
    261   scoped_ptr<content::WebContents> web_contents_;
    262   scoped_refptr<AutomationProvider> automation_;
    263 
    264   content::RenderViewHost::CreatedCallback rvh_callback_;
    265 
    266   content::NotificationRegistrar registrar_;
    267 
    268   // A view to handle focus cycling
    269   views::WebView* tab_contents_container_;
    270 
    271   int tab_handle_;
    272   // A failed navigation like a 404 is followed in chrome with a success
    273   // navigation for the 404 page. We need to ignore the next navigation
    274   // to avoid confusing the clients of the external tab. This member variable
    275   // is set when we need to ignore the next load notification.
    276   bool ignore_next_load_notification_;
    277 
    278   scoped_ptr<RenderViewContextMenuViews> external_context_menu_;
    279 
    280   // A message filter to load resources via automation
    281   scoped_refptr<AutomationResourceMessageFilter>
    282       automation_resource_message_filter_;
    283 
    284   // If all the url requests for this tab are to be loaded via automation.
    285   bool load_requests_via_automation_;
    286 
    287   // whether top level URL requests are to be handled by the automation client.
    288   bool handle_top_level_requests_;
    289 
    290   // Set to true if the host needs to get notified of all top level navigations
    291   // in this page. This typically applies to hosts which would render the new
    292   // page without chrome frame.
    293   bool route_all_top_level_navigations_;
    294 
    295   // Contains ExternalTabContainers that have not been connected to as yet.
    296   static base::LazyInstance<PendingTabs> pending_tabs_;
    297 
    298   // Allows us to run tasks on the ExternalTabContainerWin instance which are
    299   // bound by its lifetime.
    300   base::WeakPtrFactory<ExternalTabContainerWin> weak_factory_;
    301 
    302   // The URL request context to be used for this tab. Can be NULL.
    303   scoped_refptr<ChromeURLRequestContextGetter> request_context_;
    304 
    305   views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
    306 
    307   // A mapping between accelerators and commands.
    308   std::map<ui::Accelerator, int> accelerator_table_;
    309 
    310   // Top level navigations received for a tab while it is waiting for an ack
    311   // from the external host go here. Scenario is a window.open executes on a
    312   // page in ChromeFrame. A new WebContents is created and the current
    313   // ExternalTabContainerWin is notified via AddNewContents. At this point we
    314   // send off an attach tab request to the host browser. Before the host
    315   // browser sends over the ack, we receive a top level URL navigation for the
    316   // new tab, which needs to be routed over the correct automation channel.
    317   // We receive the automation channel only when the external host acks the
    318   // attach tab request.
    319   // Contains the list of URL requests which are pending waiting for an ack
    320   // from the external host.
    321   std::vector<content::OpenURLParams> pending_open_url_requests_;
    322 
    323   // Set to true if the ExternalTabContainerWin instance is waiting for an ack
    324   // from the host.
    325   bool pending_;
    326 
    327   views::FocusManager* focus_manager_;
    328 
    329   views::View* external_tab_view_;
    330 
    331   IPC::Message* unload_reply_message_;
    332 
    333   scoped_ptr<ui::ViewProp> prop_;
    334 
    335   // if this tab is a popup
    336   bool is_popup_window_;
    337 
    338 #if defined(USE_AURA)
    339   base::WeakPtr<ContainerWindow> tab_container_window_;
    340 #endif
    341 
    342   DISALLOW_COPY_AND_ASSIGN(ExternalTabContainerWin);
    343 };
    344 
    345 // This class is instantiated for handling requests to open popups for external
    346 // tabs hosted in browsers which need to be notified about all top level
    347 // navigations. An instance of this class is created for handling window.open
    348 // or link navigations with target blank, etc.
    349 class TemporaryPopupExternalTabContainerWin : public ExternalTabContainerWin {
    350  public:
    351   TemporaryPopupExternalTabContainerWin(
    352       AutomationProvider* automation,
    353       AutomationResourceMessageFilter* filter);
    354   virtual ~TemporaryPopupExternalTabContainerWin();
    355 
    356   virtual bool OnGoToEntryOffset(int offset) {
    357     NOTREACHED();
    358     return false;
    359   }
    360 
    361   virtual bool ProcessUnhandledKeyStroke(HWND window, UINT message,
    362                                          WPARAM wparam, LPARAM lparam) {
    363     NOTREACHED();
    364     return false;
    365   }
    366 
    367   virtual void Observe(int type, const content::NotificationSource& source,
    368                        const content::NotificationDetails& details) {}
    369 
    370   virtual content::WebContents* OpenURLFromTab(
    371     content::WebContents* source,
    372     const content::OpenURLParams& params) OVERRIDE;
    373 
    374   virtual void NavigationStateChanged(const content::WebContents* source,
    375                                       unsigned changed_flags) {
    376     NOTREACHED();
    377   }
    378 
    379   virtual void CloseContents(content::WebContents* source) {
    380     NOTREACHED();
    381   }
    382 
    383   virtual void UpdateTargetURL(content::WebContents* source, int32 page_id,
    384                                const GURL& url) {
    385     NOTREACHED();
    386   }
    387 
    388   void ForwardMessageToExternalHost(const std::string& message,
    389                                     const std::string& origin,
    390                                     const std::string& target) {
    391     NOTREACHED();
    392   }
    393 
    394   virtual bool TakeFocus(bool reverse) {
    395     NOTREACHED();
    396     return false;
    397   }
    398 
    399   virtual bool HandleContextMenu(const content::ContextMenuParams& params) {
    400     NOTREACHED();
    401     return false;
    402   }
    403 
    404   virtual void BeforeUnloadFired(content::WebContents* tab, bool proceed,
    405                                  bool* proceed_to_fire_unload) {
    406     NOTREACHED();
    407   }
    408 };
    409 
    410 #endif  // CHROME_BROWSER_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_
    411