blob: 91c3dfe3d983e015ef97043165b9448ff0808401 [file] [log] [blame]
// Copyright (c) 2012 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_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_
#define CHROME_BROWSER_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_
#include <map>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/automation/automation_resource_message_filter.h"
#include "chrome/browser/external_tab/external_tab_container.h"
#include "chrome/browser/infobars/infobar_container.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "content/public/browser/navigation_type.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
#include "ui/views/widget/widget_observer.h"
class AutomationProvider;
class Browser;
class Profile;
class TabContentsContainer;
class RenderViewContextMenuViews;
struct NavigationInfo;
namespace ui {
class ViewProp;
}
namespace views {
class View;
class WebView;
class Widget;
}
#if defined(USE_AURA)
class ContainerWindow;
#endif
// 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
// WebContents as well as an implementation of content::WebContentsDelegate.
class ExternalTabContainerWin : public ExternalTabContainer,
public content::WebContentsDelegate,
public content::WebContentsObserver,
public content::NotificationObserver,
public views::WidgetObserver,
public ui::AcceleratorTarget,
public InfoBarContainer::Delegate {
public:
typedef std::map<uintptr_t,
scoped_refptr<ExternalTabContainerWin> > PendingTabs;
ExternalTabContainerWin(AutomationProvider* automation,
AutomationResourceMessageFilter* filter);
static scoped_refptr<ExternalTabContainer> RemovePendingExternalTab(
uintptr_t cookie);
// Overridden from ExternalTabContainer:
virtual bool Init(Profile* profile,
HWND parent,
const gfx::Rect& bounds,
DWORD style,
bool load_requests_via_automation,
bool handle_top_level_requests,
content::WebContents* existing_contents,
const GURL& initial_url,
const GURL& referrer,
bool infobars_enabled,
bool supports_full_tab_mode) OVERRIDE;
virtual void Uninitialize() OVERRIDE;
virtual bool Reinitialize(AutomationProvider* automation_provider,
AutomationResourceMessageFilter* filter,
HWND parent_window) OVERRIDE;
virtual content::WebContents* GetWebContents() const OVERRIDE;
virtual HWND GetExternalTabHWND() const OVERRIDE;
virtual HWND GetContentHWND() const OVERRIDE;
virtual void SetTabHandle(int handle) OVERRIDE;
virtual int GetTabHandle() const OVERRIDE;
virtual bool ExecuteContextMenuCommand(int command) OVERRIDE;
virtual void RunUnloadHandlers(IPC::Message* reply_message) OVERRIDE;
virtual void ProcessUnhandledAccelerator(const MSG& msg) OVERRIDE;
virtual void FocusThroughTabTraversal(bool reverse,
bool restore_focus_to_view) OVERRIDE;
// Overridden from content::WebContentsDelegate:
virtual content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) OVERRIDE;
virtual void NavigationStateChanged(const content::WebContents* source,
unsigned changed_flags) OVERRIDE;
virtual void AddNewContents(content::WebContents* source,
content::WebContents* new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
bool user_gesture,
bool* was_blocked) OVERRIDE;
virtual void CloseContents(content::WebContents* source) OVERRIDE;
virtual void MoveContents(content::WebContents* source,
const gfx::Rect& pos) OVERRIDE;
virtual bool IsPopupOrPanel(
const content::WebContents* source) const OVERRIDE;
virtual void UpdateTargetURL(content::WebContents* source, int32 page_id,
const GURL& url) OVERRIDE;
virtual void ContentsZoomChange(bool zoom_in) OVERRIDE;
virtual void WebContentsCreated(content::WebContents* source_contents,
int64 source_frame_id,
const string16& frame_name,
const GURL& target_url,
content::WebContents* new_contents) OVERRIDE;
virtual bool PreHandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event,
bool* is_keyboard_shortcut) OVERRIDE;
virtual void HandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) OVERRIDE;
virtual bool TakeFocus(content::WebContents* source, bool reverse) OVERRIDE;
virtual void WebContentsFocused(content::WebContents* contents) OVERRIDE;
virtual void CanDownload(content::RenderViewHost* render_view_host,
int request_id,
const std::string& request_method,
const base::Callback<void(bool)>& callback) OVERRIDE;
virtual bool OnGoToEntryOffset(int offset) OVERRIDE;
virtual bool HandleContextMenu(
const content::ContextMenuParams& params) OVERRIDE;
virtual void BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) OVERRIDE;
virtual content::JavaScriptDialogManager*
GetJavaScriptDialogManager() OVERRIDE;
virtual void ShowRepostFormWarningDialog(
content::WebContents* source) OVERRIDE;
virtual content::ColorChooser* OpenColorChooser(
content::WebContents* web_contents, SkColor color) OVERRIDE;
virtual void RunFileChooser(
content::WebContents* tab,
const content::FileChooserParams& params) OVERRIDE;
virtual void EnumerateDirectory(content::WebContents* tab,
int request_id,
const base::FilePath& path) OVERRIDE;
virtual void JSOutOfMemory(content::WebContents* tab);
virtual void RegisterProtocolHandler(content::WebContents* tab,
const std::string& protocol,
const GURL& url,
const string16& title,
bool user_gesture) OVERRIDE;
virtual void FindReply(content::WebContents* tab,
int request_id,
int number_of_matches,
const gfx::Rect& selection_rect,
int active_match_ordinal,
bool final_update) OVERRIDE;
virtual void RequestMediaAccessPermission(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
const content::MediaResponseCallback& callback) OVERRIDE;
virtual bool RequestPpapiBrokerPermission(
content::WebContents* web_contents,
const GURL& url,
const base::FilePath& plugin_path,
const base::Callback<void(bool)>& callback) OVERRIDE;
void RegisterRenderViewHost(content::RenderViewHost* render_view_host);
void UnregisterRenderViewHost(content::RenderViewHost* render_view_host);
// Overridden from content::WebContentsObserver:
virtual void RenderViewDeleted(
content::RenderViewHost* render_view_host) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
virtual void DidFailProvisionalLoad(
int64 frame_id,
const string16& frame_unique_name,
bool is_main_frame,
const GURL& validated_url,
int error_code,
const string16& error_description,
content::RenderViewHost* render_view_host) OVERRIDE;
// Message handlers
void OnForwardMessageToExternalHost(const std::string& message,
const std::string& origin,
const std::string& target);
// Overridden from content::NotificationObserver:
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details);
// Overridden from ui::AcceleratorTarget:
virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
virtual bool CanHandleAccelerators() const OVERRIDE;
void set_pending(bool pending) { pending_ = pending; }
bool pending() const { return pending_; }
void set_is_popup_window(bool is_popup_window) {
is_popup_window_ = is_popup_window;
}
// Overridden from InfoBarContainer::Delegate:
virtual SkColor GetInfoBarSeparatorColor() const OVERRIDE;
virtual void InfoBarContainerStateChanged(bool is_animating) OVERRIDE;
virtual bool DrawInfoBarArrows(int* x) const OVERRIDE;
protected:
virtual ~ExternalTabContainerWin();
// WidgetObserver overrides.
virtual void OnWidgetCreated(views::Widget* widget) OVERRIDE;
virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
virtual void OnWidgetDestroyed(views::Widget* widget) OVERRIDE;
bool InitNavigationInfo(NavigationInfo* nav_info,
content::NavigationType nav_type,
int relative_offset);
void Navigate(const GURL& url, const GURL& referrer);
// Helper resource automation registration method, allowing registration of
// pending RenderViewHosts.
void RegisterRenderViewHostForAutomation(
bool pending_view,
content::RenderViewHost* render_view_host);
// 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 ExternalTabContainerWin::Reinitialize.
void OnReinitialize();
// Creates and initializes the view hierarchy for this
// ExternalTabContainerWin.
void SetupExternalTabView();
views::Widget* widget_;
scoped_ptr<content::WebContents> web_contents_;
scoped_refptr<AutomationProvider> automation_;
content::RenderViewHost::CreatedCallback rvh_callback_;
content::NotificationRegistrar registrar_;
// A view to handle focus cycling
views::WebView* 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_;
// 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_;
// Contains ExternalTabContainers that have not been connected to as yet.
static base::LazyInstance<PendingTabs> pending_tabs_;
// Allows us to run tasks on the ExternalTabContainerWin instance which are
// bound by its lifetime.
base::WeakPtrFactory<ExternalTabContainerWin> weak_factory_;
// The URL request context to be used for this tab. Can be NULL.
scoped_refptr<ChromeURLRequestContextGetter> request_context_;
views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
// A mapping between accelerators and commands.
std::map<ui::Accelerator, int> accelerator_table_;
// 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 WebContents is created and the current
// ExternalTabContainerWin 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.
// Contains the list of URL requests which are pending waiting for an ack
// from the external host.
std::vector<content::OpenURLParams> pending_open_url_requests_;
// Set to true if the ExternalTabContainerWin instance is waiting for an ack
// from the host.
bool pending_;
views::FocusManager* focus_manager_;
views::View* external_tab_view_;
IPC::Message* unload_reply_message_;
scoped_ptr<ui::ViewProp> prop_;
// if this tab is a popup
bool is_popup_window_;
#if defined(USE_AURA)
base::WeakPtr<ContainerWindow> tab_container_window_;
#endif
DISALLOW_COPY_AND_ASSIGN(ExternalTabContainerWin);
};
// 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 TemporaryPopupExternalTabContainerWin : public ExternalTabContainerWin {
public:
TemporaryPopupExternalTabContainerWin(
AutomationProvider* automation,
AutomationResourceMessageFilter* filter);
virtual ~TemporaryPopupExternalTabContainerWin();
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(int type, const content::NotificationSource& source,
const content::NotificationDetails& details) {}
virtual content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) OVERRIDE;
virtual void NavigationStateChanged(const content::WebContents* source,
unsigned changed_flags) {
NOTREACHED();
}
virtual void CloseContents(content::WebContents* source) {
NOTREACHED();
}
virtual void UpdateTargetURL(content::WebContents* source, int32 page_id,
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 content::ContextMenuParams& params) {
NOTREACHED();
return false;
}
virtual void BeforeUnloadFired(content::WebContents* tab, bool proceed,
bool* proceed_to_fire_unload) {
NOTREACHED();
}
};
#endif // CHROME_BROWSER_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_