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