• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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_EXTERNAL_TAB_CONTAINER_WIN_H_
6 #define CHROME_BROWSER_EXTERNAL_TAB_CONTAINER_WIN_H_
7 #pragma once
8 
9 #include <map>
10 #include <string>
11 #include <vector>
12 
13 #include "base/lazy_instance.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "chrome/browser/automation/automation_resource_message_filter.h"
16 #include "chrome/browser/net/chrome_url_request_context.h"
17 #include "chrome/browser/ui/views/frame/browser_bubble_host.h"
18 #include "chrome/browser/ui/views/infobars/infobar_container.h"
19 #include "chrome/browser/ui/views/unhandled_keyboard_event_handler.h"
20 #include "content/browser/tab_contents/tab_contents_delegate.h"
21 #include "content/common/navigation_types.h"
22 #include "content/common/notification_observer.h"
23 #include "content/common/notification_registrar.h"
24 #include "views/accelerator.h"
25 #include "views/widget/widget_win.h"
26 
27 class AutomationProvider;
28 class Browser;
29 class Profile;
30 class TabContentsContainer;
31 class TabContentsWrapper;
32 class RenderViewContextMenuViews;
33 struct NavigationInfo;
34 
35 namespace ui {
36 class ViewProp;
37 }
38 
39 // This class serves as the container window for an external tab.
40 // An external tab is a Chrome tab that is meant to displayed in an
41 // external process. This class provides the FocusManger needed by the
42 // TabContents as well as an implementation of TabContentsDelegate.
43 class ExternalTabContainer : public TabContentsDelegate,
44                              public NotificationObserver,
45                              public views::WidgetWin,
46                              public base::RefCounted<ExternalTabContainer>,
47                              public views::AcceleratorTarget,
48                              public InfoBarContainer::Delegate,
49                              public BrowserBubbleHost {
50  public:
51   typedef std::map<uintptr_t, scoped_refptr<ExternalTabContainer> > PendingTabs;
52 
53   ExternalTabContainer(AutomationProvider* automation,
54       AutomationResourceMessageFilter* filter);
55 
56   TabContents* tab_contents() const;
57 
58   // Temporary hack so we can send notifications back
59   void SetTabHandle(int handle);
60 
tab_handle()61   int tab_handle() const {
62     return tab_handle_;
63   }
64 
65   bool Init(Profile* profile,
66             HWND parent,
67             const gfx::Rect& bounds,
68             DWORD style,
69             bool load_requests_via_automation,
70             bool handle_top_level_requests,
71             TabContentsWrapper* existing_tab_contents,
72             const GURL& initial_url,
73             const GURL& referrer,
74             bool infobars_enabled,
75             bool supports_full_tab_mode);
76 
77   // Unhook the keystroke listener and notify about the closing TabContents.
78   // This function gets called from three places, which is fine.
79   // 1. OnFinalMessage
80   // 2. In the destructor.
81   // 3. In AutomationProvider::CreateExternalTab
82   void Uninitialize();
83 
84   // Used to reinitialize the automation channel and related information
85   // for this container. Typically used when an ExternalTabContainer
86   // instance is created by Chrome and attached to an automation client.
87   bool Reinitialize(AutomationProvider* automation_provider,
88                     AutomationResourceMessageFilter* filter,
89                     gfx::NativeWindow parent_window);
90 
91   // This is invoked when the external host reflects back to us a keyboard
92   // message it did not process
93   void ProcessUnhandledAccelerator(const MSG& msg);
94 
95   // See TabContents::FocusThroughTabTraversal.  Called from AutomationProvider.
96   void FocusThroughTabTraversal(bool reverse, bool restore_focus_to_view);
97 
98   // A helper method that tests whether the given window is an
99   // ExternalTabContainer window
100   static bool IsExternalTabContainer(HWND window);
101 
102   // A helper function that returns a pointer to the ExternalTabContainer
103   // instance associated with a native view.  Returns NULL if the window
104   // is not an ExternalTabContainer.
105   static ExternalTabContainer* GetExternalContainerFromNativeWindow(
106       gfx::NativeView native_window);
107 
108   // A helper method that retrieves the ExternalTabContainer object that
109   // hosts the given tab window.
110   static ExternalTabContainer* GetContainerForTab(HWND tab_window);
111 
112   // Overridden from TabContentsDelegate:
113   virtual void OpenURLFromTab(TabContents* source,
114                               const GURL& url,
115                               const GURL& referrer,
116                               WindowOpenDisposition disposition,
117                               PageTransition::Type transition);
118   virtual void NavigationStateChanged(const TabContents* source,
119                                       unsigned changed_flags);
120   virtual void AddNewContents(TabContents* source,
121                               TabContents* new_contents,
122                               WindowOpenDisposition disposition,
123                               const gfx::Rect& initial_pos,
124                               bool user_gesture);
125   virtual void ActivateContents(TabContents* contents);
126   virtual void DeactivateContents(TabContents* contents);
127   virtual void LoadingStateChanged(TabContents* source);
128   virtual void CloseContents(TabContents* source);
129   virtual void MoveContents(TabContents* source, const gfx::Rect& pos);
130   virtual bool IsPopup(const TabContents* source) const;
131   virtual void UpdateTargetURL(TabContents* source, const GURL& url);
132   virtual void ContentsZoomChange(bool zoom_in);
133   virtual void ForwardMessageToExternalHost(const std::string& message,
134                                             const std::string& origin,
135                                             const std::string& target);
136   virtual bool IsExternalTabContainer() const;
137   virtual gfx::NativeWindow GetFrameNativeWindow();
138 
139   virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
140                                       bool* is_keyboard_shortcut);
141   virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event);
142 
143   virtual bool TakeFocus(bool reverse);
144 
145   virtual bool CanDownload(int request_id);
146 
147   virtual bool OnGoToEntryOffset(int offset);
148 
149   virtual void ShowPageInfo(Profile* profile,
150                             const GURL& url,
151                             const NavigationEntry::SSLStatus& ssl,
152                             bool show_history);
153 
154   // Handles the context menu display operation. This allows external
155   // hosts to customize the menu.
156   virtual bool HandleContextMenu(const ContextMenuParams& params);
157 
158   // Executes the context menu command identified by the command
159   // parameter.
160   virtual bool ExecuteContextMenuCommand(int command);
161 
162   // Show a dialog with HTML content. |delegate| contains a pointer to the
163   // delegate who knows how to display the dialog (which file URL and JSON
164   // string input to use during initialization). |parent_window| is the window
165   // that should be parent of the dialog, or NULL for the default.
166   virtual void ShowHtmlDialog(HtmlDialogUIDelegate* delegate,
167                               gfx::NativeWindow parent_window);
168 
169   virtual void BeforeUnloadFired(TabContents* tab,
170                                  bool proceed,
171                                  bool* proceed_to_fire_unload);
172 
173   void ShowRepostFormWarningDialog(TabContents* tab_contents);
174 
175   // Overriden from TabContentsDelegate::AutomationResourceRoutingDelegate
176   virtual void RegisterRenderViewHost(RenderViewHost* render_view_host);
177   virtual void UnregisterRenderViewHost(RenderViewHost* render_view_host);
178 
179   // Overridden from NotificationObserver:
180   virtual void Observe(NotificationType type,
181                        const NotificationSource& source,
182                        const NotificationDetails& details);
183 
184   // Returns the ExternalTabContainer instance associated with the cookie
185   // passed in. It also erases the corresponding reference from the map.
186   // Returns NULL if we fail to find the cookie in the map.
187   static scoped_refptr<ExternalTabContainer> RemovePendingTab(uintptr_t cookie);
188 
189   // Overridden from views::WidgetWin:
190   virtual views::Window* GetWindow();
191 
192   // Handles the specified |accelerator| being pressed.
193   bool AcceleratorPressed(const views::Accelerator& accelerator);
194 
pending()195   bool pending() const {
196     return pending_;
197   }
198 
set_pending(bool pending)199   void set_pending(bool pending) {
200     pending_ = pending;
201   }
202 
set_is_popup_window(bool is_popup_window)203   void set_is_popup_window(bool is_popup_window) {
204     is_popup_window_ = is_popup_window;
205   }
206 
207   // InfoBarContainer::Delegate overrides
208   virtual SkColor GetInfoBarSeparatorColor() const OVERRIDE;
209   virtual void InfoBarContainerStateChanged(bool is_animating) OVERRIDE;
210   virtual bool DrawInfoBarArrows(int* x) const OVERRIDE;
211 
212   virtual void TabContentsCreated(TabContents* new_contents);
213 
214   virtual bool infobars_enabled();
215 
216   void RunUnloadHandlers(IPC::Message* reply_message);
217 
218  protected:
219   ~ExternalTabContainer();
220   // Overridden from views::WidgetWin:
221   virtual LRESULT OnCreate(LPCREATESTRUCT create_struct);
222   virtual void OnDestroy();
223   virtual void OnFinalMessage(HWND window);
224 
225   bool InitNavigationInfo(NavigationInfo* nav_info,
226                           NavigationType::Type nav_type,
227                           int relative_offset);
228   void Navigate(const GURL& url, const GURL& referrer);
229 
230   friend class base::RefCounted<ExternalTabContainer>;
231 
232   // Helper resource automation registration method, allowing registration of
233   // pending RenderViewHosts.
234   void RegisterRenderViewHostForAutomation(RenderViewHost* render_view_host,
235                                            bool pending_view);
236 
237   // Top level navigations received for a tab while it is waiting for an ack
238   // from the external host go here. Scenario is a window.open executes on a
239   // page in ChromeFrame. A new TabContents is created and the current
240   // ExternalTabContainer is notified via AddNewContents. At this point we
241   // send off an attach tab request to the host browser. Before the host
242   // browser sends over the ack, we receive a top level URL navigation for the
243   // new tab, which needs to be routed over the correct automation channel.
244   // We receive the automation channel only when the external host acks the
245   // attach tab request.
246   struct PendingTopLevelNavigation {
247     GURL url;
248     GURL referrer;
249     WindowOpenDisposition disposition;
250     PageTransition::Type transition;
251   };
252 
253   // Helper function for processing keystokes coming back from the renderer
254   // process.
255   bool ProcessUnhandledKeyStroke(HWND window, UINT message, WPARAM wparam,
256                                  LPARAM lparam);
257 
258   void LoadAccelerators();
259 
260   // Sends over pending Open URL requests to the external host.
261   void ServicePendingOpenURLRequests();
262 
263   // Scheduled as a task in ExternalTabContainer::Reinitialize
264   void OnReinitialize();
265 
266   // Creates and initializes the view hierarchy for this ExternalTabContainer.
267   void SetupExternalTabView();
268 
269   scoped_ptr<TabContentsWrapper> tab_contents_;
270   scoped_refptr<AutomationProvider> automation_;
271 
272   NotificationRegistrar registrar_;
273 
274   // A view to handle focus cycling
275   TabContentsContainer* tab_contents_container_;
276 
277   int tab_handle_;
278   // A failed navigation like a 404 is followed in chrome with a success
279   // navigation for the 404 page. We need to ignore the next navigation
280   // to avoid confusing the clients of the external tab. This member variable
281   // is set when we need to ignore the next load notification.
282   bool ignore_next_load_notification_;
283 
284   scoped_ptr<RenderViewContextMenuViews> external_context_menu_;
285 
286   // A message filter to load resources via automation
287   scoped_refptr<AutomationResourceMessageFilter>
288       automation_resource_message_filter_;
289 
290   // If all the url requests for this tab are to be loaded via automation.
291   bool load_requests_via_automation_;
292 
293   // whether top level URL requests are to be handled by the automation client.
294   bool handle_top_level_requests_;
295 
296   // Scoped browser object for this ExternalTabContainer instance.
297   scoped_ptr<Browser> browser_;
298 
299   // Contains ExternalTabContainers that have not been connected to as yet.
300   static base::LazyInstance<PendingTabs> pending_tabs_;
301 
302   // Allows us to run tasks on the ExternalTabContainer instance which are
303   // bound by its lifetime.
304   ScopedRunnableMethodFactory<ExternalTabContainer> external_method_factory_;
305 
306   // The URL request context to be used for this tab. Can be NULL.
307   scoped_refptr<ChromeURLRequestContextGetter> request_context_;
308 
309   UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
310 
311   // A mapping between accelerators and commands.
312   std::map<views::Accelerator, int> accelerator_table_;
313 
314   // Contains the list of URL requests which are pending waiting for an ack
315   // from the external host.
316   std::vector<PendingTopLevelNavigation> pending_open_url_requests_;
317 
318   // Set to true if the ExternalTabContainer instance is waiting for an ack
319   // from the host.
320   bool pending_;
321 
322   // Set to true if the ExternalTabContainer if infobars should be enabled.
323   bool infobars_enabled_;
324 
325   views::FocusManager* focus_manager_;
326 
327   views::View* external_tab_view_;
328 
329   IPC::Message* unload_reply_message_;
330 
331   // set to true if the host needs to get notified of all top level navigations
332   // in this page. This typically applies to hosts which would render the new
333   // page without chrome frame.
334   bool route_all_top_level_navigations_;
335 
336   scoped_ptr<ui::ViewProp> prop_;
337 
338   // if this tab is a popup
339   bool is_popup_window_;
340 
341   DISALLOW_COPY_AND_ASSIGN(ExternalTabContainer);
342 };
343 
344 // This class is instantiated for handling requests to open popups for external
345 // tabs hosted in browsers which need to be notified about all top level
346 // navigations. An instance of this class is created for handling window.open
347 // or link navigations with target blank, etc.
348 class TemporaryPopupExternalTabContainer : public ExternalTabContainer {
349  public:
350   TemporaryPopupExternalTabContainer(AutomationProvider* automation,
351       AutomationResourceMessageFilter* filter);
352   virtual ~TemporaryPopupExternalTabContainer();
353 
OnGoToEntryOffset(int offset)354   virtual bool OnGoToEntryOffset(int offset) {
355     NOTREACHED();
356     return false;
357   }
358 
ProcessUnhandledKeyStroke(HWND window,UINT message,WPARAM wparam,LPARAM lparam)359   virtual bool ProcessUnhandledKeyStroke(HWND window, UINT message,
360                                          WPARAM wparam, LPARAM lparam) {
361     NOTREACHED();
362     return false;
363   }
364 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)365   virtual void Observe(NotificationType type, const NotificationSource& source,
366                        const NotificationDetails& details) {}
367 
368   virtual void OpenURLFromTab(TabContents* source, const GURL& url,
369                               const GURL& referrer,
370                               WindowOpenDisposition disposition,
371                               PageTransition::Type transition);
372 
NavigationStateChanged(const TabContents * source,unsigned changed_flags)373   virtual void NavigationStateChanged(const TabContents* source,
374                                       unsigned changed_flags) {
375     NOTREACHED();
376   }
377 
CloseContents(TabContents * source)378   virtual void CloseContents(TabContents* source) {
379     NOTREACHED();
380   }
381 
UpdateTargetURL(TabContents * source,const GURL & url)382   virtual void UpdateTargetURL(TabContents* source, const GURL& url) {
383     NOTREACHED();
384   }
385 
ForwardMessageToExternalHost(const std::string & message,const std::string & origin,const std::string & target)386   void ForwardMessageToExternalHost(const std::string& message,
387                                     const std::string& origin,
388                                     const std::string& target) {
389     NOTREACHED();
390   }
391 
TakeFocus(bool reverse)392   virtual bool TakeFocus(bool reverse) {
393     NOTREACHED();
394     return false;
395   }
396 
HandleContextMenu(const ContextMenuParams & params)397   virtual bool HandleContextMenu(const ContextMenuParams& params) {
398     NOTREACHED();
399     return false;
400   }
401 
BeforeUnloadFired(TabContents * tab,bool proceed,bool * proceed_to_fire_unload)402   virtual void BeforeUnloadFired(TabContents* tab, bool proceed,
403                                  bool* proceed_to_fire_unload) {
404     NOTREACHED();
405   }
406 };
407 
408 #endif  // CHROME_BROWSER_EXTERNAL_TAB_CONTAINER_WIN_H_
409