| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_EXTERNAL_TAB_CONTAINER_WIN_H_ |
| #define CHROME_BROWSER_EXTERNAL_TAB_CONTAINER_WIN_H_ |
| #pragma once |
| |
| #include <map> |
| #include <string> |
| #include <vector> |
| |
| #include "base/lazy_instance.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "chrome/browser/automation/automation_resource_message_filter.h" |
| #include "chrome/browser/net/chrome_url_request_context.h" |
| #include "chrome/browser/ui/views/frame/browser_bubble_host.h" |
| #include "chrome/browser/ui/views/infobars/infobar_container.h" |
| #include "chrome/browser/ui/views/unhandled_keyboard_event_handler.h" |
| #include "content/browser/tab_contents/tab_contents_delegate.h" |
| #include "content/common/navigation_types.h" |
| #include "content/common/notification_observer.h" |
| #include "content/common/notification_registrar.h" |
| #include "views/accelerator.h" |
| #include "views/widget/widget_win.h" |
| |
| class AutomationProvider; |
| class Browser; |
| class Profile; |
| class TabContentsContainer; |
| class TabContentsWrapper; |
| class RenderViewContextMenuViews; |
| struct NavigationInfo; |
| |
| namespace ui { |
| class ViewProp; |
| } |
| |
| // This class serves as the container window for an external tab. |
| // An external tab is a Chrome tab that is meant to displayed in an |
| // external process. This class provides the FocusManger needed by the |
| // TabContents as well as an implementation of TabContentsDelegate. |
| class ExternalTabContainer : public TabContentsDelegate, |
| public NotificationObserver, |
| public views::WidgetWin, |
| public base::RefCounted<ExternalTabContainer>, |
| public views::AcceleratorTarget, |
| public InfoBarContainer::Delegate, |
| public BrowserBubbleHost { |
| public: |
| typedef std::map<uintptr_t, scoped_refptr<ExternalTabContainer> > PendingTabs; |
| |
| ExternalTabContainer(AutomationProvider* automation, |
| AutomationResourceMessageFilter* filter); |
| |
| TabContents* tab_contents() const; |
| |
| // Temporary hack so we can send notifications back |
| void SetTabHandle(int handle); |
| |
| int tab_handle() const { |
| return tab_handle_; |
| } |
| |
| bool Init(Profile* profile, |
| HWND parent, |
| const gfx::Rect& bounds, |
| DWORD style, |
| bool load_requests_via_automation, |
| bool handle_top_level_requests, |
| TabContentsWrapper* existing_tab_contents, |
| const GURL& initial_url, |
| const GURL& referrer, |
| bool infobars_enabled, |
| bool supports_full_tab_mode); |
| |
| // Unhook the keystroke listener and notify about the closing TabContents. |
| // This function gets called from three places, which is fine. |
| // 1. OnFinalMessage |
| // 2. In the destructor. |
| // 3. In AutomationProvider::CreateExternalTab |
| void Uninitialize(); |
| |
| // Used to reinitialize the automation channel and related information |
| // for this container. Typically used when an ExternalTabContainer |
| // instance is created by Chrome and attached to an automation client. |
| bool Reinitialize(AutomationProvider* automation_provider, |
| AutomationResourceMessageFilter* filter, |
| gfx::NativeWindow parent_window); |
| |
| // This is invoked when the external host reflects back to us a keyboard |
| // message it did not process |
| void ProcessUnhandledAccelerator(const MSG& msg); |
| |
| // See TabContents::FocusThroughTabTraversal. Called from AutomationProvider. |
| void FocusThroughTabTraversal(bool reverse, bool restore_focus_to_view); |
| |
| // A helper method that tests whether the given window is an |
| // ExternalTabContainer window |
| static bool IsExternalTabContainer(HWND window); |
| |
| // A helper function that returns a pointer to the ExternalTabContainer |
| // instance associated with a native view. Returns NULL if the window |
| // is not an ExternalTabContainer. |
| static ExternalTabContainer* GetExternalContainerFromNativeWindow( |
| gfx::NativeView native_window); |
| |
| // A helper method that retrieves the ExternalTabContainer object that |
| // hosts the given tab window. |
| static ExternalTabContainer* GetContainerForTab(HWND tab_window); |
| |
| // Overridden from TabContentsDelegate: |
| virtual void OpenURLFromTab(TabContents* source, |
| const GURL& url, |
| const GURL& referrer, |
| WindowOpenDisposition disposition, |
| PageTransition::Type transition); |
| virtual void NavigationStateChanged(const TabContents* source, |
| unsigned changed_flags); |
| virtual void AddNewContents(TabContents* source, |
| TabContents* new_contents, |
| WindowOpenDisposition disposition, |
| const gfx::Rect& initial_pos, |
| bool user_gesture); |
| virtual void ActivateContents(TabContents* contents); |
| virtual void DeactivateContents(TabContents* contents); |
| virtual void LoadingStateChanged(TabContents* source); |
| virtual void CloseContents(TabContents* source); |
| virtual void MoveContents(TabContents* source, const gfx::Rect& pos); |
| virtual bool IsPopup(const TabContents* source) const; |
| virtual void UpdateTargetURL(TabContents* source, const GURL& url); |
| virtual void ContentsZoomChange(bool zoom_in); |
| virtual void ForwardMessageToExternalHost(const std::string& message, |
| const std::string& origin, |
| const std::string& target); |
| virtual bool IsExternalTabContainer() const; |
| virtual gfx::NativeWindow GetFrameNativeWindow(); |
| |
| virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, |
| bool* is_keyboard_shortcut); |
| virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); |
| |
| virtual bool TakeFocus(bool reverse); |
| |
| virtual bool CanDownload(int request_id); |
| |
| virtual bool OnGoToEntryOffset(int offset); |
| |
| virtual void ShowPageInfo(Profile* profile, |
| const GURL& url, |
| const NavigationEntry::SSLStatus& ssl, |
| bool show_history); |
| |
| // Handles the context menu display operation. This allows external |
| // hosts to customize the menu. |
| virtual bool HandleContextMenu(const ContextMenuParams& params); |
| |
| // Executes the context menu command identified by the command |
| // parameter. |
| virtual bool ExecuteContextMenuCommand(int command); |
| |
| // Show a dialog with HTML content. |delegate| contains a pointer to the |
| // delegate who knows how to display the dialog (which file URL and JSON |
| // string input to use during initialization). |parent_window| is the window |
| // that should be parent of the dialog, or NULL for the default. |
| virtual void ShowHtmlDialog(HtmlDialogUIDelegate* delegate, |
| gfx::NativeWindow parent_window); |
| |
| virtual void BeforeUnloadFired(TabContents* tab, |
| bool proceed, |
| bool* proceed_to_fire_unload); |
| |
| void ShowRepostFormWarningDialog(TabContents* tab_contents); |
| |
| // Overriden from TabContentsDelegate::AutomationResourceRoutingDelegate |
| virtual void RegisterRenderViewHost(RenderViewHost* render_view_host); |
| virtual void UnregisterRenderViewHost(RenderViewHost* render_view_host); |
| |
| // Overridden from NotificationObserver: |
| virtual void Observe(NotificationType type, |
| const NotificationSource& source, |
| const NotificationDetails& details); |
| |
| // Returns the ExternalTabContainer instance associated with the cookie |
| // passed in. It also erases the corresponding reference from the map. |
| // Returns NULL if we fail to find the cookie in the map. |
| static scoped_refptr<ExternalTabContainer> RemovePendingTab(uintptr_t cookie); |
| |
| // Overridden from views::WidgetWin: |
| virtual views::Window* GetWindow(); |
| |
| // Handles the specified |accelerator| being pressed. |
| bool AcceleratorPressed(const views::Accelerator& accelerator); |
| |
| bool pending() const { |
| return pending_; |
| } |
| |
| void set_pending(bool pending) { |
| pending_ = pending; |
| } |
| |
| void set_is_popup_window(bool is_popup_window) { |
| is_popup_window_ = is_popup_window; |
| } |
| |
| // InfoBarContainer::Delegate overrides |
| virtual SkColor GetInfoBarSeparatorColor() const OVERRIDE; |
| virtual void InfoBarContainerStateChanged(bool is_animating) OVERRIDE; |
| virtual bool DrawInfoBarArrows(int* x) const OVERRIDE; |
| |
| virtual void TabContentsCreated(TabContents* new_contents); |
| |
| virtual bool infobars_enabled(); |
| |
| void RunUnloadHandlers(IPC::Message* reply_message); |
| |
| protected: |
| ~ExternalTabContainer(); |
| // Overridden from views::WidgetWin: |
| virtual LRESULT OnCreate(LPCREATESTRUCT create_struct); |
| virtual void OnDestroy(); |
| virtual void OnFinalMessage(HWND window); |
| |
| bool InitNavigationInfo(NavigationInfo* nav_info, |
| NavigationType::Type nav_type, |
| int relative_offset); |
| void Navigate(const GURL& url, const GURL& referrer); |
| |
| friend class base::RefCounted<ExternalTabContainer>; |
| |
| // Helper resource automation registration method, allowing registration of |
| // pending RenderViewHosts. |
| void RegisterRenderViewHostForAutomation(RenderViewHost* render_view_host, |
| bool pending_view); |
| |
| // Top level navigations received for a tab while it is waiting for an ack |
| // from the external host go here. Scenario is a window.open executes on a |
| // page in ChromeFrame. A new TabContents is created and the current |
| // ExternalTabContainer is notified via AddNewContents. At this point we |
| // send off an attach tab request to the host browser. Before the host |
| // browser sends over the ack, we receive a top level URL navigation for the |
| // new tab, which needs to be routed over the correct automation channel. |
| // We receive the automation channel only when the external host acks the |
| // attach tab request. |
| struct PendingTopLevelNavigation { |
| GURL url; |
| GURL referrer; |
| WindowOpenDisposition disposition; |
| PageTransition::Type transition; |
| }; |
| |
| // Helper function for processing keystokes coming back from the renderer |
| // process. |
| bool ProcessUnhandledKeyStroke(HWND window, UINT message, WPARAM wparam, |
| LPARAM lparam); |
| |
| void LoadAccelerators(); |
| |
| // Sends over pending Open URL requests to the external host. |
| void ServicePendingOpenURLRequests(); |
| |
| // Scheduled as a task in ExternalTabContainer::Reinitialize |
| void OnReinitialize(); |
| |
| // Creates and initializes the view hierarchy for this ExternalTabContainer. |
| void SetupExternalTabView(); |
| |
| scoped_ptr<TabContentsWrapper> tab_contents_; |
| scoped_refptr<AutomationProvider> automation_; |
| |
| NotificationRegistrar registrar_; |
| |
| // A view to handle focus cycling |
| TabContentsContainer* tab_contents_container_; |
| |
| int tab_handle_; |
| // A failed navigation like a 404 is followed in chrome with a success |
| // navigation for the 404 page. We need to ignore the next navigation |
| // to avoid confusing the clients of the external tab. This member variable |
| // is set when we need to ignore the next load notification. |
| bool ignore_next_load_notification_; |
| |
| scoped_ptr<RenderViewContextMenuViews> external_context_menu_; |
| |
| // A message filter to load resources via automation |
| scoped_refptr<AutomationResourceMessageFilter> |
| automation_resource_message_filter_; |
| |
| // If all the url requests for this tab are to be loaded via automation. |
| bool load_requests_via_automation_; |
| |
| // whether top level URL requests are to be handled by the automation client. |
| bool handle_top_level_requests_; |
| |
| // Scoped browser object for this ExternalTabContainer instance. |
| scoped_ptr<Browser> browser_; |
| |
| // Contains ExternalTabContainers that have not been connected to as yet. |
| static base::LazyInstance<PendingTabs> pending_tabs_; |
| |
| // Allows us to run tasks on the ExternalTabContainer instance which are |
| // bound by its lifetime. |
| ScopedRunnableMethodFactory<ExternalTabContainer> external_method_factory_; |
| |
| // The URL request context to be used for this tab. Can be NULL. |
| scoped_refptr<ChromeURLRequestContextGetter> request_context_; |
| |
| UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_; |
| |
| // A mapping between accelerators and commands. |
| std::map<views::Accelerator, int> accelerator_table_; |
| |
| // Contains the list of URL requests which are pending waiting for an ack |
| // from the external host. |
| std::vector<PendingTopLevelNavigation> pending_open_url_requests_; |
| |
| // Set to true if the ExternalTabContainer instance is waiting for an ack |
| // from the host. |
| bool pending_; |
| |
| // Set to true if the ExternalTabContainer if infobars should be enabled. |
| bool infobars_enabled_; |
| |
| views::FocusManager* focus_manager_; |
| |
| views::View* external_tab_view_; |
| |
| IPC::Message* unload_reply_message_; |
| |
| // set to true if the host needs to get notified of all top level navigations |
| // in this page. This typically applies to hosts which would render the new |
| // page without chrome frame. |
| bool route_all_top_level_navigations_; |
| |
| scoped_ptr<ui::ViewProp> prop_; |
| |
| // if this tab is a popup |
| bool is_popup_window_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ExternalTabContainer); |
| }; |
| |
| // This class is instantiated for handling requests to open popups for external |
| // tabs hosted in browsers which need to be notified about all top level |
| // navigations. An instance of this class is created for handling window.open |
| // or link navigations with target blank, etc. |
| class TemporaryPopupExternalTabContainer : public ExternalTabContainer { |
| public: |
| TemporaryPopupExternalTabContainer(AutomationProvider* automation, |
| AutomationResourceMessageFilter* filter); |
| virtual ~TemporaryPopupExternalTabContainer(); |
| |
| virtual bool OnGoToEntryOffset(int offset) { |
| NOTREACHED(); |
| return false; |
| } |
| |
| virtual bool ProcessUnhandledKeyStroke(HWND window, UINT message, |
| WPARAM wparam, LPARAM lparam) { |
| NOTREACHED(); |
| return false; |
| } |
| |
| virtual void Observe(NotificationType type, const NotificationSource& source, |
| const NotificationDetails& details) {} |
| |
| virtual void OpenURLFromTab(TabContents* source, const GURL& url, |
| const GURL& referrer, |
| WindowOpenDisposition disposition, |
| PageTransition::Type transition); |
| |
| virtual void NavigationStateChanged(const TabContents* source, |
| unsigned changed_flags) { |
| NOTREACHED(); |
| } |
| |
| virtual void CloseContents(TabContents* source) { |
| NOTREACHED(); |
| } |
| |
| virtual void UpdateTargetURL(TabContents* source, const GURL& url) { |
| NOTREACHED(); |
| } |
| |
| void ForwardMessageToExternalHost(const std::string& message, |
| const std::string& origin, |
| const std::string& target) { |
| NOTREACHED(); |
| } |
| |
| virtual bool TakeFocus(bool reverse) { |
| NOTREACHED(); |
| return false; |
| } |
| |
| virtual bool HandleContextMenu(const ContextMenuParams& params) { |
| NOTREACHED(); |
| return false; |
| } |
| |
| virtual void BeforeUnloadFired(TabContents* tab, bool proceed, |
| bool* proceed_to_fire_unload) { |
| NOTREACHED(); |
| } |
| }; |
| |
| #endif // CHROME_BROWSER_EXTERNAL_TAB_CONTAINER_WIN_H_ |