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.
5 #ifndef CHROME_BROWSER_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_
6 #define CHROME_BROWSER_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_
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"
31 class AutomationProvider
;
34 class TabContentsContainer
;
35 class RenderViewContextMenuViews
;
36 struct NavigationInfo
;
49 class ContainerWindow
;
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
{
65 typedef std::map
<uintptr_t,
66 scoped_refptr
<ExternalTabContainerWin
> > PendingTabs
;
68 ExternalTabContainerWin(AutomationProvider
* automation
,
69 AutomationResourceMessageFilter
* filter
);
71 static scoped_refptr
<ExternalTabContainer
> RemovePendingExternalTab(
74 // Overridden from ExternalTabContainer:
75 virtual bool Init(Profile
* profile
,
77 const gfx::Rect
& bounds
,
79 bool load_requests_via_automation
,
80 bool handle_top_level_requests
,
81 content::WebContents
* existing_contents
,
82 const GURL
& initial_url
,
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
;
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
,
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
,
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
,
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
,
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
,
161 const string16
& title
,
162 bool user_gesture
) OVERRIDE
;
163 virtual void FindReply(content::WebContents
* tab
,
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
,
176 const base::FilePath
& plugin_path
,
177 const base::Callback
<void(bool)>& callback
) OVERRIDE
;
179 void RegisterRenderViewHost(content::RenderViewHost
* render_view_host
);
180 void UnregisterRenderViewHost(content::RenderViewHost
* render_view_host
);
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(
189 const GURL
& validated_url
,
191 const string16
& error_description
,
192 content::RenderViewHost
* render_view_host
) OVERRIDE
;
195 void OnForwardMessageToExternalHost(const std::string
& message
,
196 const std::string
& origin
,
197 const std::string
& target
);
199 // Overridden from content::NotificationObserver:
200 virtual void Observe(int type
,
201 const content::NotificationSource
& source
,
202 const content::NotificationDetails
& details
);
204 // Overridden from ui::AcceleratorTarget:
205 virtual bool AcceleratorPressed(const ui::Accelerator
& accelerator
) OVERRIDE
;
206 virtual bool CanHandleAccelerators() const OVERRIDE
;
208 void set_pending(bool pending
) { pending_
= pending
; }
209 bool pending() const { return pending_
; }
211 void set_is_popup_window(bool is_popup_window
) {
212 is_popup_window_
= is_popup_window
;
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
;
220 // Overridden from BlockedContentTabHelperDelegate:
221 virtual content::WebContents
* GetConstrainingWebContents(
222 content::WebContents
* source
) OVERRIDE
;
225 virtual ~ExternalTabContainerWin();
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
;
232 bool InitNavigationInfo(NavigationInfo
* nav_info
,
233 content::NavigationType nav_type
,
234 int relative_offset
);
235 void Navigate(const GURL
& url
, const GURL
& referrer
);
237 // Helper resource automation registration method, allowing registration of
238 // pending RenderViewHosts.
239 void RegisterRenderViewHostForAutomation(
241 content::RenderViewHost
* render_view_host
);
243 // Helper function for processing keystokes coming back from the renderer
245 bool ProcessUnhandledKeyStroke(HWND window
, UINT message
, WPARAM wparam
,
248 void LoadAccelerators();
250 // Sends over pending Open URL requests to the external host.
251 void ServicePendingOpenURLRequests();
253 // Scheduled as a task in ExternalTabContainerWin::Reinitialize.
254 void OnReinitialize();
256 // Creates and initializes the view hierarchy for this
257 // ExternalTabContainerWin.
258 void SetupExternalTabView();
260 views::Widget
* widget_
;
261 scoped_ptr
<content::WebContents
> web_contents_
;
262 scoped_refptr
<AutomationProvider
> automation_
;
264 content::RenderViewHost::CreatedCallback rvh_callback_
;
266 content::NotificationRegistrar registrar_
;
268 // A view to handle focus cycling
269 views::WebView
* tab_contents_container_
;
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_
;
278 scoped_ptr
<RenderViewContextMenuViews
> external_context_menu_
;
280 // A message filter to load resources via automation
281 scoped_refptr
<AutomationResourceMessageFilter
>
282 automation_resource_message_filter_
;
284 // If all the url requests for this tab are to be loaded via automation.
285 bool load_requests_via_automation_
;
287 // whether top level URL requests are to be handled by the automation client.
288 bool handle_top_level_requests_
;
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_
;
295 // Contains ExternalTabContainers that have not been connected to as yet.
296 static base::LazyInstance
<PendingTabs
> pending_tabs_
;
298 // Allows us to run tasks on the ExternalTabContainerWin instance which are
299 // bound by its lifetime.
300 base::WeakPtrFactory
<ExternalTabContainerWin
> weak_factory_
;
302 // The URL request context to be used for this tab. Can be NULL.
303 scoped_refptr
<ChromeURLRequestContextGetter
> request_context_
;
305 views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_
;
307 // A mapping between accelerators and commands.
308 std::map
<ui::Accelerator
, int> accelerator_table_
;
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_
;
323 // Set to true if the ExternalTabContainerWin instance is waiting for an ack
327 views::FocusManager
* focus_manager_
;
329 views::View
* external_tab_view_
;
331 IPC::Message
* unload_reply_message_
;
333 scoped_ptr
<ui::ViewProp
> prop_
;
335 // if this tab is a popup
336 bool is_popup_window_
;
338 #if defined(USE_AURA)
339 base::WeakPtr
<ContainerWindow
> tab_container_window_
;
342 DISALLOW_COPY_AND_ASSIGN(ExternalTabContainerWin
);
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
{
351 TemporaryPopupExternalTabContainerWin(
352 AutomationProvider
* automation
,
353 AutomationResourceMessageFilter
* filter
);
354 virtual ~TemporaryPopupExternalTabContainerWin();
356 virtual bool OnGoToEntryOffset(int offset
) {
361 virtual bool ProcessUnhandledKeyStroke(HWND window
, UINT message
,
362 WPARAM wparam
, LPARAM lparam
) {
367 virtual void Observe(int type
, const content::NotificationSource
& source
,
368 const content::NotificationDetails
& details
) {}
370 virtual content::WebContents
* OpenURLFromTab(
371 content::WebContents
* source
,
372 const content::OpenURLParams
& params
) OVERRIDE
;
374 virtual void NavigationStateChanged(const content::WebContents
* source
,
375 unsigned changed_flags
) {
379 virtual void CloseContents(content::WebContents
* source
) {
383 virtual void UpdateTargetURL(content::WebContents
* source
, int32 page_id
,
388 void ForwardMessageToExternalHost(const std::string
& message
,
389 const std::string
& origin
,
390 const std::string
& target
) {
394 virtual bool TakeFocus(bool reverse
) {
399 virtual bool HandleContextMenu(const content::ContextMenuParams
& params
) {
404 virtual void BeforeUnloadFired(content::WebContents
* tab
, bool proceed
,
405 bool* proceed_to_fire_unload
) {
410 #endif // CHROME_BROWSER_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_