| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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 #include "chrome/browser/tab_contents/interstitial_page.h" | |
| 6 | |
| 7 #include <vector> | |
| 8 | |
| 9 #include "base/compiler_specific.h" | |
| 10 #include "base/message_loop.h" | |
| 11 #include "base/string_util.h" | |
| 12 #include "base/threading/thread.h" | |
| 13 #include "base/utf_string_conversions.h" | |
| 14 #include "chrome/browser/browser_list.h" | |
| 15 #include "chrome/browser/browser_process.h" | |
| 16 #include "chrome/browser/browser_thread.h" | |
| 17 #include "chrome/browser/dom_operation_notification_details.h" | |
| 18 #include "chrome/browser/profiles/profile.h" | |
| 19 #include "chrome/browser/renderer_host/render_process_host.h" | |
| 20 #include "chrome/browser/renderer_host/render_view_host.h" | |
| 21 #include "chrome/browser/renderer_host/render_widget_host_view.h" | |
| 22 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" | |
| 23 #include "chrome/browser/renderer_host/site_instance.h" | |
| 24 #include "chrome/browser/renderer_preferences_util.h" | |
| 25 #include "chrome/browser/tab_contents/navigation_controller.h" | |
| 26 #include "chrome/browser/tab_contents/navigation_entry.h" | |
| 27 #include "chrome/browser/tab_contents/tab_contents.h" | |
| 28 #include "chrome/browser/tab_contents/tab_contents_view.h" | |
| 29 #include "chrome/common/bindings_policy.h" | |
| 30 #include "chrome/common/dom_storage_common.h" | |
| 31 #include "chrome/common/net/url_request_context_getter.h" | |
| 32 #include "chrome/common/notification_source.h" | |
| 33 #include "grit/browser_resources.h" | |
| 34 #include "net/base/escape.h" | |
| 35 | |
| 36 #if defined(TOOLKIT_GTK) | |
| 37 #include "chrome/browser/ui/gtk/gtk_theme_provider.h" | |
| 38 #endif | |
| 39 | |
| 40 using WebKit::WebDragOperation; | |
| 41 using WebKit::WebDragOperationsMask; | |
| 42 | |
| 43 namespace { | |
| 44 | |
| 45 class ResourceRequestTask : public Task { | |
| 46 public: | |
| 47 ResourceRequestTask(int process_id, | |
| 48 int render_view_host_id, | |
| 49 ResourceRequestAction action) | |
| 50 : action_(action), | |
| 51 process_id_(process_id), | |
| 52 render_view_host_id_(render_view_host_id), | |
| 53 resource_dispatcher_host_( | |
| 54 g_browser_process->resource_dispatcher_host()) { | |
| 55 } | |
| 56 | |
| 57 virtual void Run() { | |
| 58 switch (action_) { | |
| 59 case BLOCK: | |
| 60 resource_dispatcher_host_->BlockRequestsForRoute( | |
| 61 process_id_, render_view_host_id_); | |
| 62 break; | |
| 63 case RESUME: | |
| 64 resource_dispatcher_host_->ResumeBlockedRequestsForRoute( | |
| 65 process_id_, render_view_host_id_); | |
| 66 break; | |
| 67 case CANCEL: | |
| 68 resource_dispatcher_host_->CancelBlockedRequestsForRoute( | |
| 69 process_id_, render_view_host_id_); | |
| 70 break; | |
| 71 default: | |
| 72 NOTREACHED(); | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 private: | |
| 77 ResourceRequestAction action_; | |
| 78 int process_id_; | |
| 79 int render_view_host_id_; | |
| 80 ResourceDispatcherHost* resource_dispatcher_host_; | |
| 81 | |
| 82 DISALLOW_COPY_AND_ASSIGN(ResourceRequestTask); | |
| 83 }; | |
| 84 | |
| 85 } // namespace | |
| 86 | |
| 87 class InterstitialPage::InterstitialPageRVHViewDelegate | |
| 88 : public RenderViewHostDelegate::View { | |
| 89 public: | |
| 90 explicit InterstitialPageRVHViewDelegate(InterstitialPage* page); | |
| 91 | |
| 92 // RenderViewHostDelegate::View implementation: | |
| 93 virtual void CreateNewWindow( | |
| 94 int route_id, | |
| 95 const ViewHostMsg_CreateWindow_Params& params); | |
| 96 virtual void CreateNewWidget(int route_id, | |
| 97 WebKit::WebPopupType popup_type); | |
| 98 virtual void CreateNewFullscreenWidget(int route_id); | |
| 99 virtual void ShowCreatedWindow(int route_id, | |
| 100 WindowOpenDisposition disposition, | |
| 101 const gfx::Rect& initial_pos, | |
| 102 bool user_gesture); | |
| 103 virtual void ShowCreatedWidget(int route_id, | |
| 104 const gfx::Rect& initial_pos); | |
| 105 virtual void ShowCreatedFullscreenWidget(int route_id); | |
| 106 virtual void ShowContextMenu(const ContextMenuParams& params); | |
| 107 virtual void ShowPopupMenu(const gfx::Rect& bounds, | |
| 108 int item_height, | |
| 109 double item_font_size, | |
| 110 int selected_item, | |
| 111 const std::vector<WebMenuItem>& items, | |
| 112 bool right_aligned); | |
| 113 virtual void StartDragging(const WebDropData& drop_data, | |
| 114 WebDragOperationsMask operations_allowed, | |
| 115 const SkBitmap& image, | |
| 116 const gfx::Point& image_offset); | |
| 117 virtual void UpdateDragCursor(WebDragOperation operation); | |
| 118 virtual void GotFocus(); | |
| 119 virtual void TakeFocus(bool reverse); | |
| 120 virtual void LostCapture(); | |
| 121 virtual void Activate(); | |
| 122 virtual void Deactivate(); | |
| 123 virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, | |
| 124 bool* is_keyboard_shortcut); | |
| 125 virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); | |
| 126 virtual void HandleMouseMove(); | |
| 127 virtual void HandleMouseDown(); | |
| 128 virtual void HandleMouseLeave(); | |
| 129 virtual void HandleMouseUp(); | |
| 130 virtual void HandleMouseActivate(); | |
| 131 virtual void OnFindReply(int request_id, | |
| 132 int number_of_matches, | |
| 133 const gfx::Rect& selection_rect, | |
| 134 int active_match_ordinal, | |
| 135 bool final_update); | |
| 136 virtual void UpdatePreferredSize(const gfx::Size& pref_size); | |
| 137 | |
| 138 private: | |
| 139 InterstitialPage* interstitial_page_; | |
| 140 | |
| 141 DISALLOW_COPY_AND_ASSIGN(InterstitialPageRVHViewDelegate); | |
| 142 }; | |
| 143 | |
| 144 // static | |
| 145 InterstitialPage::InterstitialPageMap* | |
| 146 InterstitialPage::tab_to_interstitial_page_ = NULL; | |
| 147 | |
| 148 InterstitialPage::InterstitialPage(TabContents* tab, | |
| 149 bool new_navigation, | |
| 150 const GURL& url) | |
| 151 : tab_(tab), | |
| 152 url_(url), | |
| 153 new_navigation_(new_navigation), | |
| 154 should_discard_pending_nav_entry_(new_navigation), | |
| 155 reload_on_dont_proceed_(false), | |
| 156 enabled_(true), | |
| 157 action_taken_(NO_ACTION), | |
| 158 render_view_host_(NULL), | |
| 159 original_child_id_(tab->render_view_host()->process()->id()), | |
| 160 original_rvh_id_(tab->render_view_host()->routing_id()), | |
| 161 should_revert_tab_title_(false), | |
| 162 resource_dispatcher_host_notified_(false), | |
| 163 ALLOW_THIS_IN_INITIALIZER_LIST(rvh_view_delegate_( | |
| 164 new InterstitialPageRVHViewDelegate(this))) { | |
| 165 renderer_preferences_util::UpdateFromSystemSettings( | |
| 166 &renderer_preferences_, tab_->profile()); | |
| 167 | |
| 168 InitInterstitialPageMap(); | |
| 169 // It would be inconsistent to create an interstitial with no new navigation | |
| 170 // (which is the case when the interstitial was triggered by a sub-resource on | |
| 171 // a page) when we have a pending entry (in the process of loading a new top | |
| 172 // frame). | |
| 173 DCHECK(new_navigation || !tab->controller().pending_entry()); | |
| 174 } | |
| 175 | |
| 176 InterstitialPage::~InterstitialPage() { | |
| 177 InterstitialPageMap::iterator iter = tab_to_interstitial_page_->find(tab_); | |
| 178 DCHECK(iter != tab_to_interstitial_page_->end()); | |
| 179 if (iter != tab_to_interstitial_page_->end()) | |
| 180 tab_to_interstitial_page_->erase(iter); | |
| 181 DCHECK(!render_view_host_); | |
| 182 } | |
| 183 | |
| 184 void InterstitialPage::Show() { | |
| 185 // If an interstitial is already showing or about to be shown, close it before | |
| 186 // showing the new one. | |
| 187 // Be careful not to take an action on the old interstitial more than once. | |
| 188 InterstitialPageMap::const_iterator iter = | |
| 189 tab_to_interstitial_page_->find(tab_); | |
| 190 if (iter != tab_to_interstitial_page_->end()) { | |
| 191 InterstitialPage* interstitial = iter->second; | |
| 192 if (interstitial->action_taken_ != NO_ACTION) { | |
| 193 interstitial->Hide(); | |
| 194 } else { | |
| 195 // If we are currently showing an interstitial page for which we created | |
| 196 // a transient entry and a new interstitial is shown as the result of a | |
| 197 // new browser initiated navigation, then that transient entry has already | |
| 198 // been discarded and a new pending navigation entry created. | |
| 199 // So we should not discard that new pending navigation entry. | |
| 200 // See http://crbug.com/9791 | |
| 201 if (new_navigation_ && interstitial->new_navigation_) | |
| 202 interstitial->should_discard_pending_nav_entry_= false; | |
| 203 interstitial->DontProceed(); | |
| 204 } | |
| 205 } | |
| 206 | |
| 207 // Block the resource requests for the render view host while it is hidden. | |
| 208 TakeActionOnResourceDispatcher(BLOCK); | |
| 209 // We need to be notified when the RenderViewHost is destroyed so we can | |
| 210 // cancel the blocked requests. We cannot do that on | |
| 211 // NOTIFY_TAB_CONTENTS_DESTROYED as at that point the RenderViewHost has | |
| 212 // already been destroyed. | |
| 213 notification_registrar_.Add( | |
| 214 this, NotificationType::RENDER_WIDGET_HOST_DESTROYED, | |
| 215 Source<RenderWidgetHost>(tab_->render_view_host())); | |
| 216 | |
| 217 // Update the tab_to_interstitial_page_ map. | |
| 218 iter = tab_to_interstitial_page_->find(tab_); | |
| 219 DCHECK(iter == tab_to_interstitial_page_->end()); | |
| 220 (*tab_to_interstitial_page_)[tab_] = this; | |
| 221 | |
| 222 if (new_navigation_) { | |
| 223 NavigationEntry* entry = new NavigationEntry; | |
| 224 entry->set_url(url_); | |
| 225 entry->set_virtual_url(url_); | |
| 226 entry->set_page_type(INTERSTITIAL_PAGE); | |
| 227 | |
| 228 // Give sub-classes a chance to set some states on the navigation entry. | |
| 229 UpdateEntry(entry); | |
| 230 | |
| 231 tab_->controller().AddTransientEntry(entry); | |
| 232 } | |
| 233 | |
| 234 DCHECK(!render_view_host_); | |
| 235 render_view_host_ = CreateRenderViewHost(); | |
| 236 CreateTabContentsView(); | |
| 237 | |
| 238 std::string data_url = "data:text/html;charset=utf-8," + | |
| 239 EscapePath(GetHTMLContents()); | |
| 240 render_view_host_->NavigateToURL(GURL(data_url)); | |
| 241 | |
| 242 notification_registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, | |
| 243 Source<TabContents>(tab_)); | |
| 244 notification_registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, | |
| 245 Source<NavigationController>(&tab_->controller())); | |
| 246 notification_registrar_.Add(this, NotificationType::NAV_ENTRY_PENDING, | |
| 247 Source<NavigationController>(&tab_->controller())); | |
| 248 } | |
| 249 | |
| 250 void InterstitialPage::Hide() { | |
| 251 RenderWidgetHostView* old_view = tab_->render_view_host()->view(); | |
| 252 if (old_view && !old_view->IsShowing()) { | |
| 253 // Show the original RVH since we're going away. Note it might not exist if | |
| 254 // the renderer crashed while the interstitial was showing. | |
| 255 // Note that it is important that we don't call Show() if the view is | |
| 256 // already showing. That would result in bad things (unparented HWND on | |
| 257 // Windows for example) happening. | |
| 258 old_view->Show(); | |
| 259 } | |
| 260 | |
| 261 // If the focus was on the interstitial, let's keep it to the page. | |
| 262 // (Note that in unit-tests the RVH may not have a view). | |
| 263 if (render_view_host_->view() && render_view_host_->view()->HasFocus() && | |
| 264 tab_->render_view_host()->view()) { | |
| 265 tab_->render_view_host()->view()->Focus(); | |
| 266 } | |
| 267 | |
| 268 render_view_host_->Shutdown(); | |
| 269 render_view_host_ = NULL; | |
| 270 if (tab_->interstitial_page()) | |
| 271 tab_->remove_interstitial_page(); | |
| 272 // Let's revert to the original title if necessary. | |
| 273 NavigationEntry* entry = tab_->controller().GetActiveEntry(); | |
| 274 if (!new_navigation_ && should_revert_tab_title_) { | |
| 275 entry->set_title(WideToUTF16Hack(original_tab_title_)); | |
| 276 tab_->NotifyNavigationStateChanged(TabContents::INVALIDATE_TITLE); | |
| 277 } | |
| 278 delete this; | |
| 279 } | |
| 280 | |
| 281 void InterstitialPage::Observe(NotificationType type, | |
| 282 const NotificationSource& source, | |
| 283 const NotificationDetails& details) { | |
| 284 switch (type.value) { | |
| 285 case NotificationType::NAV_ENTRY_PENDING: | |
| 286 // We are navigating away from the interstitial (the user has typed a URL | |
| 287 // in the location bar or clicked a bookmark). Make sure clicking on the | |
| 288 // interstitial will have no effect. Also cancel any blocked requests | |
| 289 // on the ResourceDispatcherHost. Note that when we get this notification | |
| 290 // the RenderViewHost has not yet navigated so we'll unblock the | |
| 291 // RenderViewHost before the resource request for the new page we are | |
| 292 // navigating arrives in the ResourceDispatcherHost. This ensures that | |
| 293 // request won't be blocked if the same RenderViewHost was used for the | |
| 294 // new navigation. | |
| 295 Disable(); | |
| 296 TakeActionOnResourceDispatcher(CANCEL); | |
| 297 break; | |
| 298 case NotificationType::RENDER_WIDGET_HOST_DESTROYED: | |
| 299 if (action_taken_ == NO_ACTION) { | |
| 300 // The RenderViewHost is being destroyed (as part of the tab being | |
| 301 // closed), make sure we clear the blocked requests. | |
| 302 RenderViewHost* rvh = Source<RenderViewHost>(source).ptr(); | |
| 303 DCHECK(rvh->process()->id() == original_child_id_ && | |
| 304 rvh->routing_id() == original_rvh_id_); | |
| 305 TakeActionOnResourceDispatcher(CANCEL); | |
| 306 } | |
| 307 break; | |
| 308 case NotificationType::TAB_CONTENTS_DESTROYED: | |
| 309 case NotificationType::NAV_ENTRY_COMMITTED: | |
| 310 if (action_taken_ == NO_ACTION) { | |
| 311 // We are navigating away from the interstitial or closing a tab with an | |
| 312 // interstitial. Default to DontProceed(). We don't just call Hide as | |
| 313 // subclasses will almost certainly override DontProceed to do some work | |
| 314 // (ex: close pending connections). | |
| 315 DontProceed(); | |
| 316 } else { | |
| 317 // User decided to proceed and either the navigation was committed or | |
| 318 // the tab was closed before that. | |
| 319 Hide(); | |
| 320 // WARNING: we are now deleted! | |
| 321 } | |
| 322 break; | |
| 323 default: | |
| 324 NOTREACHED(); | |
| 325 } | |
| 326 } | |
| 327 | |
| 328 RenderViewHostDelegate::View* InterstitialPage::GetViewDelegate() { | |
| 329 return rvh_view_delegate_.get(); | |
| 330 } | |
| 331 | |
| 332 const GURL& InterstitialPage::GetURL() const { | |
| 333 return url_; | |
| 334 } | |
| 335 | |
| 336 void InterstitialPage::RenderViewGone(RenderViewHost* render_view_host, | |
| 337 base::TerminationStatus status, | |
| 338 int error_code) { | |
| 339 // Our renderer died. This should not happen in normal cases. | |
| 340 // Just dismiss the interstitial. | |
| 341 DontProceed(); | |
| 342 } | |
| 343 | |
| 344 void InterstitialPage::DidNavigate( | |
| 345 RenderViewHost* render_view_host, | |
| 346 const ViewHostMsg_FrameNavigate_Params& params) { | |
| 347 // A fast user could have navigated away from the page that triggered the | |
| 348 // interstitial while the interstitial was loading, that would have disabled | |
| 349 // us. In that case we can dismiss ourselves. | |
| 350 if (!enabled_) { | |
| 351 DontProceed(); | |
| 352 return; | |
| 353 } | |
| 354 | |
| 355 // The RenderViewHost has loaded its contents, we can show it now. | |
| 356 render_view_host_->view()->Show(); | |
| 357 tab_->set_interstitial_page(this); | |
| 358 | |
| 359 RenderWidgetHostView* rwh_view = tab_->render_view_host()->view(); | |
| 360 | |
| 361 // The RenderViewHost may already have crashed before we even get here. | |
| 362 if (rwh_view) { | |
| 363 // If the page has focus, focus the interstitial. | |
| 364 if (rwh_view->HasFocus()) | |
| 365 Focus(); | |
| 366 | |
| 367 // Hide the original RVH since we're showing the interstitial instead. | |
| 368 rwh_view->Hide(); | |
| 369 } | |
| 370 | |
| 371 // Notify the tab we are not loading so the throbber is stopped. It also | |
| 372 // causes a NOTIFY_LOAD_STOP notification, that the AutomationProvider (used | |
| 373 // by the UI tests) expects to consider a navigation as complete. Without | |
| 374 // this, navigating in a UI test to a URL that triggers an interstitial would | |
| 375 // hang. | |
| 376 tab_->SetIsLoading(false, NULL); | |
| 377 } | |
| 378 | |
| 379 void InterstitialPage::UpdateTitle(RenderViewHost* render_view_host, | |
| 380 int32 page_id, | |
| 381 const std::wstring& title) { | |
| 382 DCHECK(render_view_host == render_view_host_); | |
| 383 NavigationEntry* entry = tab_->controller().GetActiveEntry(); | |
| 384 if (!entry) { | |
| 385 // Crash reports from the field indicate this can be NULL. | |
| 386 // This is unexpected as InterstitialPages constructed with the | |
| 387 // new_navigation flag set to true create a transient navigation entry | |
| 388 // (that is returned as the active entry). And the only case so far of | |
| 389 // interstitial created with that flag set to false is with the | |
| 390 // SafeBrowsingBlockingPage, when the resource triggering the interstitial | |
| 391 // is a sub-resource, meaning the main page has already been loaded and a | |
| 392 // navigation entry should have been created. | |
| 393 NOTREACHED(); | |
| 394 return; | |
| 395 } | |
| 396 | |
| 397 // If this interstitial is shown on an existing navigation entry, we'll need | |
| 398 // to remember its title so we can revert to it when hidden. | |
| 399 if (!new_navigation_ && !should_revert_tab_title_) { | |
| 400 original_tab_title_ = UTF16ToWideHack(entry->title()); | |
| 401 should_revert_tab_title_ = true; | |
| 402 } | |
| 403 entry->set_title(WideToUTF16Hack(title)); | |
| 404 tab_->NotifyNavigationStateChanged(TabContents::INVALIDATE_TITLE); | |
| 405 } | |
| 406 | |
| 407 void InterstitialPage::DomOperationResponse(const std::string& json_string, | |
| 408 int automation_id) { | |
| 409 if (enabled_) | |
| 410 CommandReceived(json_string); | |
| 411 } | |
| 412 | |
| 413 RendererPreferences InterstitialPage::GetRendererPrefs(Profile* profile) const { | |
| 414 return renderer_preferences_; | |
| 415 } | |
| 416 | |
| 417 RenderViewHost* InterstitialPage::CreateRenderViewHost() { | |
| 418 RenderViewHost* render_view_host = new RenderViewHost( | |
| 419 SiteInstance::CreateSiteInstance(tab()->profile()), | |
| 420 this, MSG_ROUTING_NONE, kInvalidSessionStorageNamespaceId); | |
| 421 return render_view_host; | |
| 422 } | |
| 423 | |
| 424 TabContentsView* InterstitialPage::CreateTabContentsView() { | |
| 425 TabContentsView* tab_contents_view = tab()->view(); | |
| 426 RenderWidgetHostView* view = | |
| 427 tab_contents_view->CreateViewForWidget(render_view_host_); | |
| 428 render_view_host_->set_view(view); | |
| 429 render_view_host_->AllowBindings(BindingsPolicy::DOM_AUTOMATION); | |
| 430 | |
| 431 render_view_host_->CreateRenderView(string16()); | |
| 432 view->SetSize(tab_contents_view->GetContainerSize()); | |
| 433 // Don't show the interstitial until we have navigated to it. | |
| 434 view->Hide(); | |
| 435 return tab_contents_view; | |
| 436 } | |
| 437 | |
| 438 void InterstitialPage::Proceed() { | |
| 439 if (action_taken_ != NO_ACTION) { | |
| 440 NOTREACHED(); | |
| 441 return; | |
| 442 } | |
| 443 Disable(); | |
| 444 action_taken_ = PROCEED_ACTION; | |
| 445 | |
| 446 // Resumes the throbber. | |
| 447 tab_->SetIsLoading(true, NULL); | |
| 448 | |
| 449 // If this is a new navigation, the old page is going away, so we cancel any | |
| 450 // blocked requests for it. If it is not a new navigation, then it means the | |
| 451 // interstitial was shown as a result of a resource loading in the page. | |
| 452 // Since the user wants to proceed, we'll let any blocked request go through. | |
| 453 if (new_navigation_) | |
| 454 TakeActionOnResourceDispatcher(CANCEL); | |
| 455 else | |
| 456 TakeActionOnResourceDispatcher(RESUME); | |
| 457 | |
| 458 // No need to hide if we are a new navigation, we'll get hidden when the | |
| 459 // navigation is committed. | |
| 460 if (!new_navigation_) { | |
| 461 Hide(); | |
| 462 // WARNING: we are now deleted! | |
| 463 } | |
| 464 } | |
| 465 | |
| 466 std::string InterstitialPage::GetHTMLContents() { | |
| 467 return std::string(); | |
| 468 } | |
| 469 | |
| 470 void InterstitialPage::DontProceed() { | |
| 471 DCHECK(action_taken_ != DONT_PROCEED_ACTION); | |
| 472 | |
| 473 Disable(); | |
| 474 action_taken_ = DONT_PROCEED_ACTION; | |
| 475 | |
| 476 // If this is a new navigation, we are returning to the original page, so we | |
| 477 // resume blocked requests for it. If it is not a new navigation, then it | |
| 478 // means the interstitial was shown as a result of a resource loading in the | |
| 479 // page and we won't return to the original page, so we cancel blocked | |
| 480 // requests in that case. | |
| 481 if (new_navigation_) | |
| 482 TakeActionOnResourceDispatcher(RESUME); | |
| 483 else | |
| 484 TakeActionOnResourceDispatcher(CANCEL); | |
| 485 | |
| 486 if (should_discard_pending_nav_entry_) { | |
| 487 // Since no navigation happens we have to discard the transient entry | |
| 488 // explicitely. Note that by calling DiscardNonCommittedEntries() we also | |
| 489 // discard the pending entry, which is what we want, since the navigation is | |
| 490 // cancelled. | |
| 491 tab_->controller().DiscardNonCommittedEntries(); | |
| 492 } | |
| 493 | |
| 494 if (reload_on_dont_proceed_) | |
| 495 tab_->controller().Reload(true); | |
| 496 | |
| 497 Hide(); | |
| 498 // WARNING: we are now deleted! | |
| 499 } | |
| 500 | |
| 501 void InterstitialPage::CancelForNavigation() { | |
| 502 // The user is trying to navigate away. We should unblock the renderer and | |
| 503 // disable the interstitial, but keep it visible until the navigation | |
| 504 // completes. | |
| 505 Disable(); | |
| 506 // If this interstitial was shown for a new navigation, allow any navigations | |
| 507 // on the original page to resume (e.g., subresource requests, XHRs, etc). | |
| 508 // Otherwise, cancel the pending, possibly dangerous navigations. | |
| 509 if (new_navigation_) | |
| 510 TakeActionOnResourceDispatcher(RESUME); | |
| 511 else | |
| 512 TakeActionOnResourceDispatcher(CANCEL); | |
| 513 } | |
| 514 | |
| 515 void InterstitialPage::SetSize(const gfx::Size& size) { | |
| 516 #if !defined(OS_MACOSX) | |
| 517 // When a tab is closed, we might be resized after our view was NULLed | |
| 518 // (typically if there was an info-bar). | |
| 519 if (render_view_host_->view()) | |
| 520 render_view_host_->view()->SetSize(size); | |
| 521 #else | |
| 522 // TODO(port): Does Mac need to SetSize? | |
| 523 NOTIMPLEMENTED(); | |
| 524 #endif | |
| 525 } | |
| 526 | |
| 527 void InterstitialPage::Focus() { | |
| 528 // Focus the native window. | |
| 529 render_view_host_->view()->Focus(); | |
| 530 } | |
| 531 | |
| 532 void InterstitialPage::FocusThroughTabTraversal(bool reverse) { | |
| 533 render_view_host_->SetInitialFocus(reverse); | |
| 534 } | |
| 535 | |
| 536 ViewType::Type InterstitialPage::GetRenderViewType() const { | |
| 537 return ViewType::INTERSTITIAL_PAGE; | |
| 538 } | |
| 539 | |
| 540 void InterstitialPage::Disable() { | |
| 541 enabled_ = false; | |
| 542 } | |
| 543 | |
| 544 void InterstitialPage::TakeActionOnResourceDispatcher( | |
| 545 ResourceRequestAction action) { | |
| 546 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) << | |
| 547 "TakeActionOnResourceDispatcher should be called on the main thread."; | |
| 548 | |
| 549 if (action == CANCEL || action == RESUME) { | |
| 550 if (resource_dispatcher_host_notified_) | |
| 551 return; | |
| 552 resource_dispatcher_host_notified_ = true; | |
| 553 } | |
| 554 | |
| 555 // The tab might not have a render_view_host if it was closed (in which case, | |
| 556 // we have taken care of the blocked requests when processing | |
| 557 // NOTIFY_RENDER_WIDGET_HOST_DESTROYED. | |
| 558 // Also we need to test there is a ResourceDispatcherHost, as when unit-tests | |
| 559 // we don't have one. | |
| 560 RenderViewHost* rvh = RenderViewHost::FromID(original_child_id_, | |
| 561 original_rvh_id_); | |
| 562 if (!rvh || !g_browser_process->resource_dispatcher_host()) | |
| 563 return; | |
| 564 | |
| 565 BrowserThread::PostTask( | |
| 566 BrowserThread::IO, FROM_HERE, | |
| 567 new ResourceRequestTask(original_child_id_, original_rvh_id_, action)); | |
| 568 } | |
| 569 | |
| 570 // static | |
| 571 void InterstitialPage::InitInterstitialPageMap() { | |
| 572 if (!tab_to_interstitial_page_) | |
| 573 tab_to_interstitial_page_ = new InterstitialPageMap; | |
| 574 } | |
| 575 | |
| 576 // static | |
| 577 InterstitialPage* InterstitialPage::GetInterstitialPage( | |
| 578 TabContents* tab_contents) { | |
| 579 InitInterstitialPageMap(); | |
| 580 InterstitialPageMap::const_iterator iter = | |
| 581 tab_to_interstitial_page_->find(tab_contents); | |
| 582 if (iter == tab_to_interstitial_page_->end()) | |
| 583 return NULL; | |
| 584 | |
| 585 return iter->second; | |
| 586 } | |
| 587 | |
| 588 InterstitialPage::InterstitialPageRVHViewDelegate:: | |
| 589 InterstitialPageRVHViewDelegate(InterstitialPage* page) | |
| 590 : interstitial_page_(page) { | |
| 591 } | |
| 592 | |
| 593 void InterstitialPage::InterstitialPageRVHViewDelegate::CreateNewWindow( | |
| 594 int route_id, | |
| 595 const ViewHostMsg_CreateWindow_Params& params) { | |
| 596 NOTREACHED() << "InterstitialPage does not support showing popups yet."; | |
| 597 } | |
| 598 | |
| 599 void InterstitialPage::InterstitialPageRVHViewDelegate::CreateNewWidget( | |
| 600 int route_id, WebKit::WebPopupType popup_type) { | |
| 601 NOTREACHED() << "InterstitialPage does not support showing drop-downs yet."; | |
| 602 } | |
| 603 | |
| 604 void | |
| 605 InterstitialPage::InterstitialPageRVHViewDelegate::CreateNewFullscreenWidget( | |
| 606 int route_id) { | |
| 607 NOTREACHED() | |
| 608 << "InterstitialPage does not support showing full screen popups."; | |
| 609 } | |
| 610 | |
| 611 void InterstitialPage::InterstitialPageRVHViewDelegate::ShowCreatedWindow( | |
| 612 int route_id, WindowOpenDisposition disposition, | |
| 613 const gfx::Rect& initial_pos, bool user_gesture) { | |
| 614 NOTREACHED() << "InterstitialPage does not support showing popups yet."; | |
| 615 } | |
| 616 | |
| 617 void InterstitialPage::InterstitialPageRVHViewDelegate::ShowCreatedWidget( | |
| 618 int route_id, const gfx::Rect& initial_pos) { | |
| 619 NOTREACHED() << "InterstitialPage does not support showing drop-downs yet."; | |
| 620 } | |
| 621 | |
| 622 void | |
| 623 InterstitialPage::InterstitialPageRVHViewDelegate::ShowCreatedFullscreenWidget( | |
| 624 int route_id) { | |
| 625 NOTREACHED() | |
| 626 << "InterstitialPage does not support showing full screen popups."; | |
| 627 } | |
| 628 | |
| 629 void InterstitialPage::InterstitialPageRVHViewDelegate::ShowContextMenu( | |
| 630 const ContextMenuParams& params) { | |
| 631 } | |
| 632 | |
| 633 void InterstitialPage::InterstitialPageRVHViewDelegate::ShowPopupMenu( | |
| 634 const gfx::Rect& bounds, | |
| 635 int item_height, | |
| 636 double item_font_size, | |
| 637 int selected_item, | |
| 638 const std::vector<WebMenuItem>& items, | |
| 639 bool right_aligned) { | |
| 640 } | |
| 641 | |
| 642 void InterstitialPage::InterstitialPageRVHViewDelegate::StartDragging( | |
| 643 const WebDropData& drop_data, | |
| 644 WebDragOperationsMask allowed_operations, | |
| 645 const SkBitmap& image, | |
| 646 const gfx::Point& image_offset) { | |
| 647 NOTREACHED() << "InterstitialPage does not support dragging yet."; | |
| 648 } | |
| 649 | |
| 650 void InterstitialPage::InterstitialPageRVHViewDelegate::UpdateDragCursor( | |
| 651 WebDragOperation) { | |
| 652 NOTREACHED() << "InterstitialPage does not support dragging yet."; | |
| 653 } | |
| 654 | |
| 655 void InterstitialPage::InterstitialPageRVHViewDelegate::GotFocus() { | |
| 656 } | |
| 657 | |
| 658 void InterstitialPage::InterstitialPageRVHViewDelegate::UpdatePreferredSize( | |
| 659 const gfx::Size& pref_size) { | |
| 660 } | |
| 661 | |
| 662 void InterstitialPage::InterstitialPageRVHViewDelegate::TakeFocus( | |
| 663 bool reverse) { | |
| 664 if (interstitial_page_->tab() && interstitial_page_->tab()->GetViewDelegate()) | |
| 665 interstitial_page_->tab()->GetViewDelegate()->TakeFocus(reverse); | |
| 666 } | |
| 667 | |
| 668 void InterstitialPage::InterstitialPageRVHViewDelegate::LostCapture() { | |
| 669 } | |
| 670 | |
| 671 void InterstitialPage::InterstitialPageRVHViewDelegate::Activate() { | |
| 672 if (interstitial_page_->tab() && interstitial_page_->tab()->GetViewDelegate()) | |
| 673 interstitial_page_->tab()->GetViewDelegate()->Activate(); | |
| 674 } | |
| 675 | |
| 676 void InterstitialPage::InterstitialPageRVHViewDelegate::Deactivate() { | |
| 677 if (interstitial_page_->tab() && interstitial_page_->tab()->GetViewDelegate()) | |
| 678 interstitial_page_->tab()->GetViewDelegate()->Deactivate(); | |
| 679 } | |
| 680 | |
| 681 bool InterstitialPage::InterstitialPageRVHViewDelegate::PreHandleKeyboardEvent( | |
| 682 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) { | |
| 683 if (interstitial_page_->tab() && interstitial_page_->tab()->GetViewDelegate()) | |
| 684 return interstitial_page_->tab()->GetViewDelegate()->PreHandleKeyboardEvent( | |
| 685 event, is_keyboard_shortcut); | |
| 686 return false; | |
| 687 } | |
| 688 | |
| 689 void InterstitialPage::InterstitialPageRVHViewDelegate::HandleKeyboardEvent( | |
| 690 const NativeWebKeyboardEvent& event) { | |
| 691 if (interstitial_page_->tab() && interstitial_page_->tab()->GetViewDelegate()) | |
| 692 interstitial_page_->tab()->GetViewDelegate()->HandleKeyboardEvent(event); | |
| 693 } | |
| 694 | |
| 695 void InterstitialPage::InterstitialPageRVHViewDelegate::HandleMouseMove() { | |
| 696 if (interstitial_page_->tab() && interstitial_page_->tab()->GetViewDelegate()) | |
| 697 interstitial_page_->tab()->GetViewDelegate()->HandleMouseMove(); | |
| 698 } | |
| 699 | |
| 700 void InterstitialPage::InterstitialPageRVHViewDelegate::HandleMouseDown() { | |
| 701 if (interstitial_page_->tab() && interstitial_page_->tab()->GetViewDelegate()) | |
| 702 interstitial_page_->tab()->GetViewDelegate()->HandleMouseDown(); | |
| 703 } | |
| 704 | |
| 705 void InterstitialPage::InterstitialPageRVHViewDelegate::HandleMouseLeave() { | |
| 706 if (interstitial_page_->tab() && interstitial_page_->tab()->GetViewDelegate()) | |
| 707 interstitial_page_->tab()->GetViewDelegate()->HandleMouseLeave(); | |
| 708 } | |
| 709 | |
| 710 void InterstitialPage::InterstitialPageRVHViewDelegate::HandleMouseUp() { | |
| 711 } | |
| 712 | |
| 713 void InterstitialPage::InterstitialPageRVHViewDelegate::HandleMouseActivate() { | |
| 714 } | |
| 715 | |
| 716 void InterstitialPage::InterstitialPageRVHViewDelegate::OnFindReply( | |
| 717 int request_id, int number_of_matches, const gfx::Rect& selection_rect, | |
| 718 int active_match_ordinal, bool final_update) { | |
| 719 } | |
| 720 | |
| 721 int InterstitialPage::GetBrowserWindowID() const { | |
| 722 return tab_->GetBrowserWindowID(); | |
| 723 } | |
| 724 | |
| 725 void InterstitialPage::UpdateInspectorSetting(const std::string& key, | |
| 726 const std::string& value) { | |
| 727 RenderViewHostDelegateHelper::UpdateInspectorSetting( | |
| 728 tab_->profile(), key, value); | |
| 729 } | |
| 730 | |
| 731 void InterstitialPage::ClearInspectorSettings() { | |
| 732 RenderViewHostDelegateHelper::ClearInspectorSettings(tab_->profile()); | |
| 733 } | |
| OLD | NEW |