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