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