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