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 "content/public/browser/navigation_type.h"
21 #include "content/public/browser/notification_observer.h"
22 #include "content/public/browser/notification_registrar.h"
23 #include "content/public/browser/web_contents_delegate.h"
24 #include "content/public/browser/web_contents_observer.h"
25 #include "ui/base/accelerators/accelerator.h"
26 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
27 #include "ui/views/widget/widget_observer.h"
29 class AutomationProvider;
32 class TabContentsContainer;
33 class RenderViewContextMenuViews;
34 struct NavigationInfo;
47 class ContainerWindow;
50 // This class serves as the container window for an external tab.
51 // An external tab is a Chrome tab that is meant to displayed in an
52 // external process. This class provides the FocusManger needed by the
53 // WebContents as well as an implementation of content::WebContentsDelegate.
54 class ExternalTabContainerWin : public ExternalTabContainer,
55 public content::WebContentsDelegate,
56 public content::WebContentsObserver,
57 public content::NotificationObserver,
58 public views::WidgetObserver,
59 public ui::AcceleratorTarget,
60 public InfoBarContainer::Delegate {
62 typedef std::map<uintptr_t,
63 scoped_refptr<ExternalTabContainerWin> > PendingTabs;
65 ExternalTabContainerWin(AutomationProvider* automation,
66 AutomationResourceMessageFilter* filter);
68 static scoped_refptr<ExternalTabContainer> RemovePendingExternalTab(
71 // Overridden from ExternalTabContainer:
72 virtual bool Init(Profile* profile,
74 const gfx::Rect& bounds,
76 bool load_requests_via_automation,
77 bool handle_top_level_requests,
78 content::WebContents* existing_contents,
79 const GURL& initial_url,
81 bool infobars_enabled,
82 bool supports_full_tab_mode) OVERRIDE;
83 virtual void Uninitialize() OVERRIDE;
84 virtual bool Reinitialize(AutomationProvider* automation_provider,
85 AutomationResourceMessageFilter* filter,
86 HWND parent_window) OVERRIDE;
87 virtual content::WebContents* GetWebContents() const OVERRIDE;
88 virtual HWND GetExternalTabHWND() const OVERRIDE;
89 virtual HWND GetContentHWND() const OVERRIDE;
90 virtual void SetTabHandle(int handle) OVERRIDE;
91 virtual int GetTabHandle() const OVERRIDE;
92 virtual bool ExecuteContextMenuCommand(int command) OVERRIDE;
93 virtual void RunUnloadHandlers(IPC::Message* reply_message) OVERRIDE;
94 virtual void ProcessUnhandledAccelerator(const MSG& msg) OVERRIDE;
95 virtual void FocusThroughTabTraversal(bool reverse,
96 bool restore_focus_to_view) OVERRIDE;
98 // Overridden from content::WebContentsDelegate:
99 virtual content::WebContents* OpenURLFromTab(
100 content::WebContents* source,
101 const content::OpenURLParams& params) OVERRIDE;
102 virtual void NavigationStateChanged(const content::WebContents* source,
103 unsigned changed_flags) OVERRIDE;
104 virtual void AddNewContents(content::WebContents* source,
105 content::WebContents* new_contents,
106 WindowOpenDisposition disposition,
107 const gfx::Rect& initial_pos,
109 bool* was_blocked) OVERRIDE;
110 virtual void CloseContents(content::WebContents* source) OVERRIDE;
111 virtual void MoveContents(content::WebContents* source,
112 const gfx::Rect& pos) OVERRIDE;
113 virtual bool IsPopupOrPanel(
114 const content::WebContents* source) const OVERRIDE;
115 virtual void UpdateTargetURL(content::WebContents* source, int32 page_id,
116 const GURL& url) OVERRIDE;
117 virtual void ContentsZoomChange(bool zoom_in) OVERRIDE;
118 virtual void WebContentsCreated(content::WebContents* source_contents,
119 int64 source_frame_id,
120 const string16& frame_name,
121 const GURL& target_url,
122 content::WebContents* new_contents) OVERRIDE;
123 virtual bool PreHandleKeyboardEvent(
124 content::WebContents* source,
125 const content::NativeWebKeyboardEvent& event,
126 bool* is_keyboard_shortcut) OVERRIDE;
127 virtual void HandleKeyboardEvent(
128 content::WebContents* source,
129 const content::NativeWebKeyboardEvent& event) OVERRIDE;
130 virtual bool TakeFocus(content::WebContents* source, bool reverse) OVERRIDE;
131 virtual void WebContentsFocused(content::WebContents* contents) OVERRIDE;
132 virtual void CanDownload(content::RenderViewHost* render_view_host,
134 const std::string& request_method,
135 const base::Callback<void(bool)>& callback) OVERRIDE;
136 virtual bool OnGoToEntryOffset(int offset) OVERRIDE;
137 virtual bool HandleContextMenu(
138 const content::ContextMenuParams& params) OVERRIDE;
139 virtual void BeforeUnloadFired(content::WebContents* tab,
141 bool* proceed_to_fire_unload) OVERRIDE;
142 virtual content::JavaScriptDialogManager*
143 GetJavaScriptDialogManager() OVERRIDE;
144 virtual void ShowRepostFormWarningDialog(
145 content::WebContents* source) OVERRIDE;
146 virtual content::ColorChooser* OpenColorChooser(
147 content::WebContents* web_contents, SkColor color) OVERRIDE;
148 virtual void RunFileChooser(
149 content::WebContents* tab,
150 const content::FileChooserParams& params) OVERRIDE;
151 virtual void EnumerateDirectory(content::WebContents* tab,
153 const base::FilePath& path) OVERRIDE;
154 virtual void JSOutOfMemory(content::WebContents* tab);
155 virtual void RegisterProtocolHandler(content::WebContents* tab,
156 const std::string& protocol,
158 const string16& title,
159 bool user_gesture) OVERRIDE;
160 virtual void FindReply(content::WebContents* tab,
162 int number_of_matches,
163 const gfx::Rect& selection_rect,
164 int active_match_ordinal,
165 bool final_update) OVERRIDE;
166 virtual void RequestMediaAccessPermission(
167 content::WebContents* web_contents,
168 const content::MediaStreamRequest& request,
169 const content::MediaResponseCallback& callback) OVERRIDE;
170 virtual bool RequestPpapiBrokerPermission(
171 content::WebContents* web_contents,
173 const base::FilePath& plugin_path,
174 const base::Callback<void(bool)>& callback) OVERRIDE;
176 void RegisterRenderViewHost(content::RenderViewHost* render_view_host);
177 void UnregisterRenderViewHost(content::RenderViewHost* render_view_host);
179 // Overridden from content::WebContentsObserver:
180 virtual void RenderViewDeleted(
181 content::RenderViewHost* render_view_host) OVERRIDE;
182 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
183 virtual void DidFailProvisionalLoad(
185 const string16& frame_unique_name,
187 const GURL& validated_url,
189 const string16& error_description,
190 content::RenderViewHost* render_view_host) OVERRIDE;
193 void OnForwardMessageToExternalHost(const std::string& message,
194 const std::string& origin,
195 const std::string& target);
197 // Overridden from content::NotificationObserver:
198 virtual void Observe(int type,
199 const content::NotificationSource& source,
200 const content::NotificationDetails& details);
202 // Overridden from ui::AcceleratorTarget:
203 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
204 virtual bool CanHandleAccelerators() const OVERRIDE;
206 void set_pending(bool pending) { pending_ = pending; }
207 bool pending() const { return pending_; }
209 void set_is_popup_window(bool is_popup_window) {
210 is_popup_window_ = is_popup_window;
213 // Overridden from InfoBarContainer::Delegate:
214 virtual SkColor GetInfoBarSeparatorColor() const OVERRIDE;
215 virtual void InfoBarContainerStateChanged(bool is_animating) OVERRIDE;
216 virtual bool DrawInfoBarArrows(int* x) const OVERRIDE;
219 virtual ~ExternalTabContainerWin();
221 // WidgetObserver overrides.
222 virtual void OnWidgetCreated(views::Widget* widget) OVERRIDE;
223 virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
224 virtual void OnWidgetDestroyed(views::Widget* widget) OVERRIDE;
226 bool InitNavigationInfo(NavigationInfo* nav_info,
227 content::NavigationType nav_type,
228 int relative_offset);
229 void Navigate(const GURL& url, const GURL& referrer);
231 // Helper resource automation registration method, allowing registration of
232 // pending RenderViewHosts.
233 void RegisterRenderViewHostForAutomation(
235 content::RenderViewHost* render_view_host);
237 // Helper function for processing keystokes coming back from the renderer
239 bool ProcessUnhandledKeyStroke(HWND window, UINT message, WPARAM wparam,
242 void LoadAccelerators();
244 // Sends over pending Open URL requests to the external host.
245 void ServicePendingOpenURLRequests();
247 // Scheduled as a task in ExternalTabContainerWin::Reinitialize.
248 void OnReinitialize();
250 // Creates and initializes the view hierarchy for this
251 // ExternalTabContainerWin.
252 void SetupExternalTabView();
254 views::Widget* widget_;
255 scoped_ptr<content::WebContents> web_contents_;
256 scoped_refptr<AutomationProvider> automation_;
258 content::NotificationRegistrar registrar_;
260 // A view to handle focus cycling
261 views::WebView* tab_contents_container_;
264 // A failed navigation like a 404 is followed in chrome with a success
265 // navigation for the 404 page. We need to ignore the next navigation
266 // to avoid confusing the clients of the external tab. This member variable
267 // is set when we need to ignore the next load notification.
268 bool ignore_next_load_notification_;
270 scoped_ptr<RenderViewContextMenuViews> external_context_menu_;
272 // A message filter to load resources via automation
273 scoped_refptr<AutomationResourceMessageFilter>
274 automation_resource_message_filter_;
276 // If all the url requests for this tab are to be loaded via automation.
277 bool load_requests_via_automation_;
279 // whether top level URL requests are to be handled by the automation client.
280 bool handle_top_level_requests_;
282 // Set to true if the host needs to get notified of all top level navigations
283 // in this page. This typically applies to hosts which would render the new
284 // page without chrome frame.
285 bool route_all_top_level_navigations_;
287 // Contains ExternalTabContainers that have not been connected to as yet.
288 static base::LazyInstance<PendingTabs> pending_tabs_;
290 // Allows us to run tasks on the ExternalTabContainerWin instance which are
291 // bound by its lifetime.
292 base::WeakPtrFactory<ExternalTabContainerWin> weak_factory_;
294 // The URL request context to be used for this tab. Can be NULL.
295 scoped_refptr<ChromeURLRequestContextGetter> request_context_;
297 views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
299 // A mapping between accelerators and commands.
300 std::map<ui::Accelerator, int> accelerator_table_;
302 // Top level navigations received for a tab while it is waiting for an ack
303 // from the external host go here. Scenario is a window.open executes on a
304 // page in ChromeFrame. A new WebContents is created and the current
305 // ExternalTabContainerWin is notified via AddNewContents. At this point we
306 // send off an attach tab request to the host browser. Before the host
307 // browser sends over the ack, we receive a top level URL navigation for the
308 // new tab, which needs to be routed over the correct automation channel.
309 // We receive the automation channel only when the external host acks the
310 // attach tab request.
311 // Contains the list of URL requests which are pending waiting for an ack
312 // from the external host.
313 std::vector<content::OpenURLParams> pending_open_url_requests_;
315 // Set to true if the ExternalTabContainerWin instance is waiting for an ack
319 views::FocusManager* focus_manager_;
321 views::View* external_tab_view_;
323 IPC::Message* unload_reply_message_;
325 scoped_ptr<ui::ViewProp> prop_;
327 // if this tab is a popup
328 bool is_popup_window_;
330 #if defined(USE_AURA)
331 base::WeakPtr<ContainerWindow> tab_container_window_;
334 DISALLOW_COPY_AND_ASSIGN(ExternalTabContainerWin);
337 // This class is instantiated for handling requests to open popups for external
338 // tabs hosted in browsers which need to be notified about all top level
339 // navigations. An instance of this class is created for handling window.open
340 // or link navigations with target blank, etc.
341 class TemporaryPopupExternalTabContainerWin : public ExternalTabContainerWin {
343 TemporaryPopupExternalTabContainerWin(
344 AutomationProvider* automation,
345 AutomationResourceMessageFilter* filter);
346 virtual ~TemporaryPopupExternalTabContainerWin();
348 virtual bool OnGoToEntryOffset(int offset) {
353 virtual bool ProcessUnhandledKeyStroke(HWND window, UINT message,
354 WPARAM wparam, LPARAM lparam) {
359 virtual void Observe(int type, const content::NotificationSource& source,
360 const content::NotificationDetails& details) {}
362 virtual content::WebContents* OpenURLFromTab(
363 content::WebContents* source,
364 const content::OpenURLParams& params) OVERRIDE;
366 virtual void NavigationStateChanged(const content::WebContents* source,
367 unsigned changed_flags) {
371 virtual void CloseContents(content::WebContents* source) {
375 virtual void UpdateTargetURL(content::WebContents* source, int32 page_id,
380 void ForwardMessageToExternalHost(const std::string& message,
381 const std::string& origin,
382 const std::string& target) {
386 virtual bool TakeFocus(bool reverse) {
391 virtual bool HandleContextMenu(const content::ContextMenuParams& params) {
396 virtual void BeforeUnloadFired(content::WebContents* tab, bool proceed,
397 bool* proceed_to_fire_unload) {
402 #endif // CHROME_BROWSER_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_