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