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.
5 #include "content/browser/web_contents/interstitial_page_impl.h"
10 #include "base/compiler_specific.h"
11 #include "base/message_loop.h"
12 #include "base/string_util.h"
13 #include "base/threading/thread.h"
14 #include "base/utf_string_conversions.h"
15 #include "content/browser/dom_storage/dom_storage_context_impl.h"
16 #include "content/browser/dom_storage/session_storage_namespace_impl.h"
17 #include "content/browser/loader/resource_dispatcher_host_impl.h"
18 #include "content/browser/renderer_host/render_process_host_impl.h"
19 #include "content/browser/renderer_host/render_view_host_impl.h"
20 #include "content/browser/site_instance_impl.h"
21 #include "content/browser/web_contents/navigation_controller_impl.h"
22 #include "content/browser/web_contents/navigation_entry_impl.h"
23 #include "content/browser/web_contents/web_contents_impl.h"
24 #include "content/common/view_messages.h"
25 #include "content/port/browser/render_view_host_delegate_view.h"
26 #include "content/port/browser/render_widget_host_view_port.h"
27 #include "content/public/browser/browser_context.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/content_browser_client.h"
30 #include "content/public/browser/dom_operation_notification_details.h"
31 #include "content/public/browser/interstitial_page_delegate.h"
32 #include "content/public/browser/invalidate_type.h"
33 #include "content/public/browser/notification_service.h"
34 #include "content/public/browser/notification_source.h"
35 #include "content/public/browser/storage_partition.h"
36 #include "content/public/browser/web_contents_view.h"
37 #include "content/public/common/bindings_policy.h"
38 #include "content/public/common/page_transition_types.h"
39 #include "net/base/escape.h"
40 #include "net/url_request/url_request_context_getter.h"
42 using WebKit::WebDragOperation
;
43 using WebKit::WebDragOperationsMask
;
48 void ResourceRequestHelper(ResourceDispatcherHostImpl
* rdh
,
50 int render_view_host_id
,
51 ResourceRequestAction action
) {
54 rdh
->BlockRequestsForRoute(process_id
, render_view_host_id
);
57 rdh
->ResumeBlockedRequestsForRoute(process_id
, render_view_host_id
);
60 rdh
->CancelBlockedRequestsForRoute(process_id
, render_view_host_id
);
69 class InterstitialPageImpl::InterstitialPageRVHDelegateView
70 : public RenderViewHostDelegateView
{
72 explicit InterstitialPageRVHDelegateView(InterstitialPageImpl
* page
);
74 // RenderViewHostDelegateView implementation:
75 virtual void ShowPopupMenu(const gfx::Rect
& bounds
,
77 double item_font_size
,
79 const std::vector
<WebMenuItem
>& items
,
81 bool allow_multiple_selection
) OVERRIDE
;
82 virtual void StartDragging(const WebDropData
& drop_data
,
83 WebDragOperationsMask operations_allowed
,
84 const gfx::ImageSkia
& image
,
85 const gfx::Vector2d
& image_offset
,
86 const DragEventSourceInfo
& event_info
) OVERRIDE
;
87 virtual void UpdateDragCursor(WebDragOperation operation
) OVERRIDE
;
88 virtual void GotFocus() OVERRIDE
;
89 virtual void TakeFocus(bool reverse
) OVERRIDE
;
90 virtual void OnFindReply(int request_id
,
91 int number_of_matches
,
92 const gfx::Rect
& selection_rect
,
93 int active_match_ordinal
,
97 InterstitialPageImpl
* interstitial_page_
;
99 DISALLOW_COPY_AND_ASSIGN(InterstitialPageRVHDelegateView
);
103 // We keep a map of the various blocking pages shown as the UI tests need to
104 // be able to retrieve them.
105 typedef std::map
<WebContents
*, InterstitialPageImpl
*> InterstitialPageMap
;
106 static InterstitialPageMap
* g_web_contents_to_interstitial_page
;
108 // Initializes g_web_contents_to_interstitial_page in a thread-safe manner.
109 // Should be called before accessing g_web_contents_to_interstitial_page.
110 static void InitInterstitialPageMap() {
111 if (!g_web_contents_to_interstitial_page
)
112 g_web_contents_to_interstitial_page
= new InterstitialPageMap
;
115 InterstitialPage
* InterstitialPage::Create(WebContents
* web_contents
,
118 InterstitialPageDelegate
* delegate
) {
119 return new InterstitialPageImpl(web_contents
, new_navigation
, url
, delegate
);
122 InterstitialPage
* InterstitialPage::GetInterstitialPage(
123 WebContents
* web_contents
) {
124 InitInterstitialPageMap();
125 InterstitialPageMap::const_iterator iter
=
126 g_web_contents_to_interstitial_page
->find(web_contents
);
127 if (iter
== g_web_contents_to_interstitial_page
->end())
133 InterstitialPageImpl::InterstitialPageImpl(WebContents
* web_contents
,
136 InterstitialPageDelegate
* delegate
)
137 : web_contents_(static_cast<WebContentsImpl
*>(web_contents
)),
139 new_navigation_(new_navigation
),
140 should_discard_pending_nav_entry_(new_navigation
),
141 reload_on_dont_proceed_(false),
143 action_taken_(NO_ACTION
),
144 render_view_host_(NULL
),
145 original_child_id_(web_contents
->GetRenderProcessHost()->GetID()),
146 original_rvh_id_(web_contents
->GetRenderViewHost()->GetRoutingID()),
147 should_revert_web_contents_title_(false),
148 web_contents_was_loading_(false),
149 resource_dispatcher_host_notified_(false),
150 ALLOW_THIS_IN_INITIALIZER_LIST(rvh_delegate_view_(
151 new InterstitialPageRVHDelegateView(this))),
154 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
155 InitInterstitialPageMap();
156 // It would be inconsistent to create an interstitial with no new navigation
157 // (which is the case when the interstitial was triggered by a sub-resource on
158 // a page) when we have a pending entry (in the process of loading a new top
160 DCHECK(new_navigation
|| !web_contents
->GetController().GetPendingEntry());
163 InterstitialPageImpl::~InterstitialPageImpl() {
166 void InterstitialPageImpl::Show() {
167 // If an interstitial is already showing or about to be shown, close it before
168 // showing the new one.
169 // Be careful not to take an action on the old interstitial more than once.
170 InterstitialPageMap::const_iterator iter
=
171 g_web_contents_to_interstitial_page
->find(web_contents_
);
172 if (iter
!= g_web_contents_to_interstitial_page
->end()) {
173 InterstitialPageImpl
* interstitial
= iter
->second
;
174 if (interstitial
->action_taken_
!= NO_ACTION
) {
175 interstitial
->Hide();
177 // If we are currently showing an interstitial page for which we created
178 // a transient entry and a new interstitial is shown as the result of a
179 // new browser initiated navigation, then that transient entry has already
180 // been discarded and a new pending navigation entry created.
181 // So we should not discard that new pending navigation entry.
182 // See http://crbug.com/9791
183 if (new_navigation_
&& interstitial
->new_navigation_
)
184 interstitial
->should_discard_pending_nav_entry_
= false;
185 interstitial
->DontProceed();
189 // Block the resource requests for the render view host while it is hidden.
190 TakeActionOnResourceDispatcher(BLOCK
);
191 // We need to be notified when the RenderViewHost is destroyed so we can
192 // cancel the blocked requests. We cannot do that on
193 // NOTIFY_WEB_CONTENTS_DESTROYED as at that point the RenderViewHost has
194 // already been destroyed.
195 notification_registrar_
.Add(
196 this, NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED
,
197 Source
<RenderWidgetHost
>(web_contents_
->GetRenderViewHost()));
199 // Update the g_web_contents_to_interstitial_page map.
200 iter
= g_web_contents_to_interstitial_page
->find(web_contents_
);
201 DCHECK(iter
== g_web_contents_to_interstitial_page
->end());
202 (*g_web_contents_to_interstitial_page
)[web_contents_
] = this;
204 if (new_navigation_
) {
205 NavigationEntryImpl
* entry
= new NavigationEntryImpl
;
207 entry
->SetVirtualURL(url_
);
208 entry
->set_page_type(PAGE_TYPE_INTERSTITIAL
);
210 // Give delegates a chance to set some states on the navigation entry.
211 delegate_
->OverrideEntry(entry
);
213 web_contents_
->GetController().AddTransientEntry(entry
);
216 DCHECK(!render_view_host_
);
217 render_view_host_
= static_cast<RenderViewHostImpl
*>(CreateRenderViewHost());
218 CreateWebContentsView();
220 std::string data_url
= "data:text/html;charset=utf-8," +
221 net::EscapePath(delegate_
->GetHTMLContents());
222 render_view_host_
->NavigateToURL(GURL(data_url
));
224 notification_registrar_
.Add(this,
225 NOTIFICATION_WEB_CONTENTS_DESTROYED
,
226 Source
<WebContents
>(web_contents_
));
227 notification_registrar_
.Add(this, NOTIFICATION_NAV_ENTRY_COMMITTED
,
228 Source
<NavigationController
>(&web_contents_
->GetController()));
229 notification_registrar_
.Add(this, NOTIFICATION_NAV_ENTRY_PENDING
,
230 Source
<NavigationController
>(&web_contents_
->GetController()));
231 notification_registrar_
.Add(
232 this, NOTIFICATION_DOM_OPERATION_RESPONSE
,
233 Source
<RenderViewHost
>(render_view_host_
));
236 void InterstitialPageImpl::Hide() {
237 // We may have already been hidden, and are just waiting to be deleted.
238 if (!render_view_host_
)
243 RenderWidgetHostView
* old_view
=
244 web_contents_
->GetRenderViewHost()->GetView();
245 if (web_contents_
->GetInterstitialPage() == this &&
246 old_view
&& !old_view
->IsShowing()) {
247 // Show the original RVH since we're going away. Note it might not exist if
248 // the renderer crashed while the interstitial was showing.
249 // Note that it is important that we don't call Show() if the view is
250 // already showing. That would result in bad things (unparented HWND on
251 // Windows for example) happening.
255 // If the focus was on the interstitial, let's keep it to the page.
256 // (Note that in unit-tests the RVH may not have a view).
257 if (render_view_host_
->GetView() &&
258 render_view_host_
->GetView()->HasFocus() &&
259 web_contents_
->GetRenderViewHost()->GetView()) {
260 RenderWidgetHostViewPort::FromRWHV(
261 web_contents_
->GetRenderViewHost()->GetView())->Focus();
264 // Shutdown the RVH asynchronously, as we may have been called from a RVH
265 // delegate method, and we can't delete the RVH out from under itself.
266 MessageLoop::current()->PostNonNestableTask(FROM_HERE
,
267 base::Bind(&InterstitialPageImpl::Shutdown
,
268 weak_ptr_factory_
.GetWeakPtr(),
270 render_view_host_
= NULL
;
271 if (web_contents_
->GetInterstitialPage())
272 web_contents_
->remove_interstitial_page();
273 // Let's revert to the original title if necessary.
274 NavigationEntry
* entry
= web_contents_
->GetController().GetActiveEntry();
275 if (!new_navigation_
&& should_revert_web_contents_title_
) {
276 entry
->SetTitle(original_web_contents_title_
);
277 web_contents_
->NotifyNavigationStateChanged(INVALIDATE_TYPE_TITLE
);
280 NotificationService::current()->Notify(
281 NOTIFICATION_INTERSTITIAL_DETACHED
,
282 Source
<WebContents
>(web_contents_
),
283 NotificationService::NoDetails());
285 InterstitialPageMap::iterator iter
=
286 g_web_contents_to_interstitial_page
->find(web_contents_
);
287 DCHECK(iter
!= g_web_contents_to_interstitial_page
->end());
288 if (iter
!= g_web_contents_to_interstitial_page
->end())
289 g_web_contents_to_interstitial_page
->erase(iter
);
292 void InterstitialPageImpl::Observe(
294 const NotificationSource
& source
,
295 const NotificationDetails
& details
) {
297 case NOTIFICATION_NAV_ENTRY_PENDING
:
298 // We are navigating away from the interstitial (the user has typed a URL
299 // in the location bar or clicked a bookmark). Make sure clicking on the
300 // interstitial will have no effect. Also cancel any blocked requests
301 // on the ResourceDispatcherHost. Note that when we get this notification
302 // the RenderViewHost has not yet navigated so we'll unblock the
303 // RenderViewHost before the resource request for the new page we are
304 // navigating arrives in the ResourceDispatcherHost. This ensures that
305 // request won't be blocked if the same RenderViewHost was used for the
308 TakeActionOnResourceDispatcher(CANCEL
);
310 case NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED
:
311 if (action_taken_
== NO_ACTION
) {
312 // The RenderViewHost is being destroyed (as part of the tab being
313 // closed); make sure we clear the blocked requests.
314 RenderViewHost
* rvh
= static_cast<RenderViewHost
*>(
315 static_cast<RenderViewHostImpl
*>(
316 RenderWidgetHostImpl::From(
317 Source
<RenderWidgetHost
>(source
).ptr())));
318 DCHECK(rvh
->GetProcess()->GetID() == original_child_id_
&&
319 rvh
->GetRoutingID() == original_rvh_id_
);
320 TakeActionOnResourceDispatcher(CANCEL
);
323 case NOTIFICATION_WEB_CONTENTS_DESTROYED
:
324 case NOTIFICATION_NAV_ENTRY_COMMITTED
:
325 if (action_taken_
== NO_ACTION
) {
326 // We are navigating away from the interstitial or closing a tab with an
327 // interstitial. Default to DontProceed(). We don't just call Hide as
328 // subclasses will almost certainly override DontProceed to do some work
329 // (ex: close pending connections).
332 // User decided to proceed and either the navigation was committed or
333 // the tab was closed before that.
337 case NOTIFICATION_DOM_OPERATION_RESPONSE
:
339 Details
<DomOperationNotificationDetails
> dom_op_details(
341 delegate_
->CommandReceived(dom_op_details
->json
);
349 RenderViewHostDelegateView
* InterstitialPageImpl::GetDelegateView() {
350 return rvh_delegate_view_
.get();
353 const GURL
& InterstitialPageImpl::GetURL() const {
357 void InterstitialPageImpl::RenderViewGone(RenderViewHost
* render_view_host
,
358 base::TerminationStatus status
,
360 // Our renderer died. This should not happen in normal cases.
361 // Just dismiss the interstitial.
365 void InterstitialPageImpl::DidNavigate(
366 RenderViewHost
* render_view_host
,
367 const ViewHostMsg_FrameNavigate_Params
& params
) {
368 // A fast user could have navigated away from the page that triggered the
369 // interstitial while the interstitial was loading, that would have disabled
370 // us. In that case we can dismiss ourselves.
375 if (params
.transition
== PAGE_TRANSITION_AUTO_SUBFRAME
) {
376 // No need to handle navigate message from iframe in the interstitial page.
380 // The RenderViewHost has loaded its contents, we can show it now.
381 render_view_host_
->GetView()->Show();
382 web_contents_
->set_interstitial_page(this);
384 // This notification hides the bookmark bar. Note that this has to happen
385 // after the interstitial page was registered with |web_contents_|, since
386 // there will be a callback to |web_contents_| testing if an interstitial page
387 // is showing before hiding the bookmark bar.
388 NotificationService::current()->Notify(
389 NOTIFICATION_INTERSTITIAL_ATTACHED
,
390 Source
<WebContents
>(web_contents_
),
391 NotificationService::NoDetails());
393 RenderWidgetHostView
* rwh_view
=
394 web_contents_
->GetRenderViewHost()->GetView();
396 // The RenderViewHost may already have crashed before we even get here.
398 // If the page has focus, focus the interstitial.
399 if (rwh_view
->HasFocus())
402 // Hide the original RVH since we're showing the interstitial instead.
406 // Notify the tab we are not loading so the throbber is stopped. It also
407 // causes a NOTIFY_LOAD_STOP notification, that the AutomationProvider (used
408 // by the UI tests) expects to consider a navigation as complete. Without
409 // this, navigating in a UI test to a URL that triggers an interstitial would
411 web_contents_was_loading_
= web_contents_
->IsLoading();
412 web_contents_
->SetIsLoading(false, NULL
);
415 void InterstitialPageImpl::UpdateTitle(
416 RenderViewHost
* render_view_host
,
418 const string16
& title
,
419 base::i18n::TextDirection title_direction
) {
423 DCHECK(render_view_host
== render_view_host_
);
424 NavigationEntry
* entry
= web_contents_
->GetController().GetActiveEntry();
426 // Crash reports from the field indicate this can be NULL.
427 // This is unexpected as InterstitialPages constructed with the
428 // new_navigation flag set to true create a transient navigation entry
429 // (that is returned as the active entry). And the only case so far of
430 // interstitial created with that flag set to false is with the
431 // SafeBrowsingBlockingPage, when the resource triggering the interstitial
432 // is a sub-resource, meaning the main page has already been loaded and a
433 // navigation entry should have been created.
438 // If this interstitial is shown on an existing navigation entry, we'll need
439 // to remember its title so we can revert to it when hidden.
440 if (!new_navigation_
&& !should_revert_web_contents_title_
) {
441 original_web_contents_title_
= entry
->GetTitle();
442 should_revert_web_contents_title_
= true;
444 // TODO(evan): make use of title_direction.
445 // http://code.google.com/p/chromium/issues/detail?id=27094
446 entry
->SetTitle(title
);
447 web_contents_
->NotifyNavigationStateChanged(INVALIDATE_TYPE_TITLE
);
450 RendererPreferences
InterstitialPageImpl::GetRendererPrefs(
451 BrowserContext
* browser_context
) const {
452 delegate_
->OverrideRendererPrefs(&renderer_preferences_
);
453 return renderer_preferences_
;
456 webkit_glue::WebPreferences
InterstitialPageImpl::GetWebkitPrefs() {
458 return webkit_glue::WebPreferences();
460 return WebContentsImpl::GetWebkitPrefs(render_view_host_
, url_
);
463 void InterstitialPageImpl::RenderWidgetDeleted(
464 RenderWidgetHostImpl
* render_widget_host
) {
468 bool InterstitialPageImpl::PreHandleKeyboardEvent(
469 const NativeWebKeyboardEvent
& event
,
470 bool* is_keyboard_shortcut
) {
471 return web_contents_
->PreHandleKeyboardEvent(event
, is_keyboard_shortcut
);
474 void InterstitialPageImpl::HandleKeyboardEvent(
475 const NativeWebKeyboardEvent
& event
) {
476 return web_contents_
->HandleKeyboardEvent(event
);
479 WebContents
* InterstitialPageImpl::web_contents() const {
480 return web_contents_
;
483 RenderViewHost
* InterstitialPageImpl::CreateRenderViewHost() {
484 // Interstitial pages don't want to share the session storage so we mint a
486 BrowserContext
* browser_context
= web_contents()->GetBrowserContext();
487 scoped_refptr
<SiteInstance
> site_instance
=
488 SiteInstance::Create(browser_context
);
489 DOMStorageContextImpl
* dom_storage_context
=
490 static_cast<DOMStorageContextImpl
*>(
491 BrowserContext::GetStoragePartition(
492 browser_context
, site_instance
)->GetDOMStorageContext());
493 SessionStorageNamespaceImpl
* session_storage_namespace_impl
=
494 new SessionStorageNamespaceImpl(dom_storage_context
);
496 RenderViewHostImpl
* render_view_host
= new RenderViewHostImpl(
497 site_instance
, this, this, MSG_ROUTING_NONE
, false,
498 session_storage_namespace_impl
);
499 web_contents_
->RenderViewForInterstitialPageCreated(render_view_host
);
500 return render_view_host
;
503 WebContentsView
* InterstitialPageImpl::CreateWebContentsView() {
504 if (!enabled() || !create_view_
)
506 WebContentsView
* web_contents_view
= web_contents()->GetView();
507 RenderWidgetHostView
* view
=
508 web_contents_view
->CreateViewForWidget(render_view_host_
);
509 render_view_host_
->SetView(view
);
510 render_view_host_
->AllowBindings(BINDINGS_POLICY_DOM_AUTOMATION
);
512 int32 max_page_id
= web_contents()->
513 GetMaxPageIDForSiteInstance(render_view_host_
->GetSiteInstance());
514 render_view_host_
->CreateRenderView(string16(),
517 view
->SetSize(web_contents_view
->GetContainerSize());
518 // Don't show the interstitial until we have navigated to it.
520 return web_contents_view
;
523 void InterstitialPageImpl::Proceed() {
524 if (action_taken_
!= NO_ACTION
) {
529 action_taken_
= PROCEED_ACTION
;
531 // Resumes the throbber, if applicable.
532 if (web_contents_was_loading_
)
533 web_contents_
->SetIsLoading(true, NULL
);
535 // If this is a new navigation, the old page is going away, so we cancel any
536 // blocked requests for it. If it is not a new navigation, then it means the
537 // interstitial was shown as a result of a resource loading in the page.
538 // Since the user wants to proceed, we'll let any blocked request go through.
540 TakeActionOnResourceDispatcher(CANCEL
);
542 TakeActionOnResourceDispatcher(RESUME
);
544 // No need to hide if we are a new navigation, we'll get hidden when the
545 // navigation is committed.
546 if (!new_navigation_
) {
548 delegate_
->OnProceed();
552 delegate_
->OnProceed();
555 void InterstitialPageImpl::DontProceed() {
556 DCHECK(action_taken_
!= DONT_PROCEED_ACTION
);
559 action_taken_
= DONT_PROCEED_ACTION
;
561 // If this is a new navigation, we are returning to the original page, so we
562 // resume blocked requests for it. If it is not a new navigation, then it
563 // means the interstitial was shown as a result of a resource loading in the
564 // page and we won't return to the original page, so we cancel blocked
565 // requests in that case.
567 TakeActionOnResourceDispatcher(RESUME
);
569 TakeActionOnResourceDispatcher(CANCEL
);
571 if (should_discard_pending_nav_entry_
) {
572 // Since no navigation happens we have to discard the transient entry
573 // explicitely. Note that by calling DiscardNonCommittedEntries() we also
574 // discard the pending entry, which is what we want, since the navigation is
576 web_contents_
->GetController().DiscardNonCommittedEntries();
579 if (reload_on_dont_proceed_
)
580 web_contents_
->GetController().Reload(true);
583 delegate_
->OnDontProceed();
586 void InterstitialPageImpl::CancelForNavigation() {
587 // The user is trying to navigate away. We should unblock the renderer and
588 // disable the interstitial, but keep it visible until the navigation
591 // If this interstitial was shown for a new navigation, allow any navigations
592 // on the original page to resume (e.g., subresource requests, XHRs, etc).
593 // Otherwise, cancel the pending, possibly dangerous navigations.
595 TakeActionOnResourceDispatcher(RESUME
);
597 TakeActionOnResourceDispatcher(CANCEL
);
600 void InterstitialPageImpl::SetSize(const gfx::Size
& size
) {
603 #if !defined(OS_MACOSX)
604 // When a tab is closed, we might be resized after our view was NULLed
605 // (typically if there was an info-bar).
606 if (render_view_host_
->GetView())
607 render_view_host_
->GetView()->SetSize(size
);
609 // TODO(port): Does Mac need to SetSize?
614 void InterstitialPageImpl::Focus() {
615 // Focus the native window.
618 RenderWidgetHostViewPort::FromRWHV(render_view_host_
->GetView())->Focus();
621 void InterstitialPageImpl::FocusThroughTabTraversal(bool reverse
) {
624 render_view_host_
->SetInitialFocus(reverse
);
627 RenderWidgetHostView
* InterstitialPageImpl::GetView() {
628 return render_view_host_
->GetView();
631 RenderViewHost
* InterstitialPageImpl::GetRenderViewHostForTesting() const {
632 return render_view_host_
;
635 #if defined(OS_ANDROID)
636 RenderViewHost
* InterstitialPageImpl::GetRenderViewHost() const {
637 return render_view_host_
;
641 InterstitialPageDelegate
* InterstitialPageImpl::GetDelegateForTesting() {
642 return delegate_
.get();
645 void InterstitialPageImpl::DontCreateViewForTesting() {
646 create_view_
= false;
649 gfx::Rect
InterstitialPageImpl::GetRootWindowResizerRect() const {
653 void InterstitialPageImpl::CreateNewWindow(
655 const ViewHostMsg_CreateWindow_Params
& params
,
656 SessionStorageNamespace
* session_storage_namespace
) {
657 NOTREACHED() << "InterstitialPage does not support showing popups yet.";
660 void InterstitialPageImpl::CreateNewWidget(int route_id
,
661 WebKit::WebPopupType popup_type
) {
662 NOTREACHED() << "InterstitialPage does not support showing drop-downs yet.";
665 void InterstitialPageImpl::CreateNewFullscreenWidget(int route_id
) {
667 << "InterstitialPage does not support showing full screen popups.";
670 void InterstitialPageImpl::ShowCreatedWindow(int route_id
,
671 WindowOpenDisposition disposition
,
672 const gfx::Rect
& initial_pos
,
674 NOTREACHED() << "InterstitialPage does not support showing popups yet.";
677 void InterstitialPageImpl::ShowCreatedWidget(int route_id
,
678 const gfx::Rect
& initial_pos
) {
679 NOTREACHED() << "InterstitialPage does not support showing drop-downs yet.";
682 void InterstitialPageImpl::ShowCreatedFullscreenWidget(int route_id
) {
684 << "InterstitialPage does not support showing full screen popups.";
687 void InterstitialPageImpl::ShowContextMenu(
688 const ContextMenuParams
& params
,
689 ContextMenuSourceType type
) {
692 void InterstitialPageImpl::Disable() {
696 void InterstitialPageImpl::Shutdown(RenderViewHostImpl
* render_view_host
) {
697 render_view_host
->Shutdown();
698 // We are deleted now.
701 void InterstitialPageImpl::TakeActionOnResourceDispatcher(
702 ResourceRequestAction action
) {
703 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
)) <<
704 "TakeActionOnResourceDispatcher should be called on the main thread.";
706 if (action
== CANCEL
|| action
== RESUME
) {
707 if (resource_dispatcher_host_notified_
)
709 resource_dispatcher_host_notified_
= true;
712 // The tab might not have a render_view_host if it was closed (in which case,
713 // we have taken care of the blocked requests when processing
714 // NOTIFY_RENDER_WIDGET_HOST_DESTROYED.
715 // Also we need to test there is a ResourceDispatcherHostImpl, as when unit-
716 // tests we don't have one.
717 RenderViewHostImpl
* rvh
= RenderViewHostImpl::FromID(original_child_id_
,
719 if (!rvh
|| !ResourceDispatcherHostImpl::Get())
722 BrowserThread::PostTask(
726 &ResourceRequestHelper
,
727 ResourceDispatcherHostImpl::Get(),
733 InterstitialPageImpl::InterstitialPageRVHDelegateView::
734 InterstitialPageRVHDelegateView(InterstitialPageImpl
* page
)
735 : interstitial_page_(page
) {
738 void InterstitialPageImpl::InterstitialPageRVHDelegateView::ShowPopupMenu(
739 const gfx::Rect
& bounds
,
741 double item_font_size
,
743 const std::vector
<WebMenuItem
>& items
,
745 bool allow_multiple_selection
) {
746 NOTREACHED() << "InterstitialPage does not support showing popup menus.";
749 void InterstitialPageImpl::InterstitialPageRVHDelegateView::StartDragging(
750 const WebDropData
& drop_data
,
751 WebDragOperationsMask allowed_operations
,
752 const gfx::ImageSkia
& image
,
753 const gfx::Vector2d
& image_offset
,
754 const DragEventSourceInfo
& event_info
) {
755 NOTREACHED() << "InterstitialPage does not support dragging yet.";
758 void InterstitialPageImpl::InterstitialPageRVHDelegateView::UpdateDragCursor(
760 NOTREACHED() << "InterstitialPage does not support dragging yet.";
763 void InterstitialPageImpl::InterstitialPageRVHDelegateView::GotFocus() {
766 void InterstitialPageImpl::InterstitialPageRVHDelegateView::TakeFocus(
768 if (!interstitial_page_
->web_contents())
770 WebContentsImpl
* web_contents
=
771 static_cast<WebContentsImpl
*>(interstitial_page_
->web_contents());
772 if (!web_contents
->GetDelegateView())
775 web_contents
->GetDelegateView()->TakeFocus(reverse
);
778 void InterstitialPageImpl::InterstitialPageRVHDelegateView::OnFindReply(
779 int request_id
, int number_of_matches
, const gfx::Rect
& selection_rect
,
780 int active_match_ordinal
, bool final_update
) {
783 } // namespace content