// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/frame_host/interstitial_page_impl.h"

#include <map>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/user_metrics.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
#include "content/browser/frame_host/interstitial_page_navigator_impl.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/display_util.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/renderer_host/text_input_manager.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_contents_view.h"
#include "content/common/buildflags.h"
#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/interstitial_page_delegate.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/keyboard_event_processing_result.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/bindings_policy.h"
#include "net/base/escape.h"
#include "net/url_request/url_request_context_getter.h"
#include "ui/base/page_transition_types.h"

using blink::WebDragOperation;
using blink::WebDragOperationsMask;

namespace content {

class InterstitialPageImpl::InterstitialPageRVHDelegateView
  : public RenderViewHostDelegateView {
 public:
  explicit InterstitialPageRVHDelegateView(InterstitialPageImpl* page);

  // RenderViewHostDelegateView implementation:
#if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
  void ShowPopupMenu(RenderFrameHost* render_frame_host,
                     const gfx::Rect& bounds,
                     int item_height,
                     double item_font_size,
                     int selected_item,
                     const std::vector<MenuItem>& items,
                     bool right_aligned,
                     bool allow_multiple_selection) override;
  void HidePopupMenu() override;
#endif
  void StartDragging(const DropData& drop_data,
                     WebDragOperationsMask operations_allowed,
                     const gfx::ImageSkia& image,
                     const gfx::Vector2d& image_offset,
                     const DragEventSourceInfo& event_info,
                     RenderWidgetHostImpl* source_rwh) override;
  void UpdateDragCursor(WebDragOperation operation) override;
  void GotFocus(RenderWidgetHostImpl* render_widget_host) override;
  void LostFocus(RenderWidgetHostImpl* render_widget_host) override;
  void TakeFocus(bool reverse) override;
  int GetTopControlsHeight() const override;
  int GetBottomControlsHeight() const override;
  bool DoBrowserControlsShrinkRendererSize() const override;
  virtual void OnFindReply(int request_id,
                           int number_of_matches,
                           const gfx::Rect& selection_rect,
                           int active_match_ordinal,
                           bool final_update);

 private:
  InterstitialPageImpl* interstitial_page_;

  DISALLOW_COPY_AND_ASSIGN(InterstitialPageRVHDelegateView);
};


// We keep a map of the various blocking pages shown as the UI tests need to
// be able to retrieve them.
typedef std::map<WebContents*, InterstitialPageImpl*> InterstitialPageMap;
static InterstitialPageMap* g_web_contents_to_interstitial_page;

// Initializes g_web_contents_to_interstitial_page in a thread-safe manner.
// Should be called before accessing g_web_contents_to_interstitial_page.
static void InitInterstitialPageMap() {
  if (!g_web_contents_to_interstitial_page)
    g_web_contents_to_interstitial_page = new InterstitialPageMap;
}

InterstitialPage* InterstitialPage::Create(WebContents* web_contents,
                                           bool new_navigation,
                                           const GURL& url,
                                           InterstitialPageDelegate* delegate) {
  return new InterstitialPageImpl(
      web_contents,
      static_cast<RenderWidgetHostDelegate*>(
          static_cast<WebContentsImpl*>(web_contents)),
      new_navigation, url, delegate);
}

InterstitialPage* InterstitialPage::GetInterstitialPage(
    WebContents* web_contents) {
  InitInterstitialPageMap();
  InterstitialPageMap::const_iterator iter =
      g_web_contents_to_interstitial_page->find(web_contents);
  if (iter == g_web_contents_to_interstitial_page->end())
    return nullptr;

  return iter->second;
}

InterstitialPage* InterstitialPage::FromRenderFrameHost(RenderFrameHost* rfh) {
  if (!rfh)
    return nullptr;
  return static_cast<RenderFrameHostImpl*>(rfh)
      ->delegate()
      ->GetAsInterstitialPage();
}

InterstitialPageImpl::InterstitialPageImpl(
    WebContents* web_contents,
    RenderWidgetHostDelegate* render_widget_host_delegate,
    bool new_navigation,
    const GURL& url,
    InterstitialPageDelegate* delegate)
    : underlying_content_observer_(web_contents, this),
      web_contents_(web_contents),
      controller_(static_cast<NavigationControllerImpl*>(
          &web_contents->GetController())),
      render_widget_host_delegate_(render_widget_host_delegate),
      url_(url),
      new_navigation_(new_navigation),
      should_discard_pending_nav_entry_(new_navigation),
      enabled_(true),
      action_taken_(NO_ACTION),
      render_view_host_(nullptr),
      // TODO(nasko): The InterstitialPageImpl will need to provide its own
      // NavigationControllerImpl to the Navigator, which is separate from
      // the WebContents one, so we can enforce no navigation policy here.
      // While we get the code to a point to do this, pass NULL for it.
      // TODO(creis): We will also need to pass delegates for the RVHM as we
      // start to use it.
      frame_tree_(std::make_unique<FrameTree>(
          new InterstitialPageNavigatorImpl(this, controller_),
          this,
          this,
          this,
          static_cast<WebContentsImpl*>(web_contents))),
      original_child_id_(
          web_contents->GetRenderViewHost()->GetProcess()->GetID()),
      original_rvh_id_(web_contents->GetRenderViewHost()->GetRoutingID()),
      should_revert_web_contents_title_(false),
      resource_dispatcher_host_notified_(false),
      rvh_delegate_view_(new InterstitialPageRVHDelegateView(this)),
      create_view_(true),
      pause_throbber_(false),
      delegate_(delegate),
      widget_observer_(this),
      weak_ptr_factory_(this) {
  InitInterstitialPageMap();
}

InterstitialPageImpl::~InterstitialPageImpl() {
  // RenderViewHostImpl::RenderWidgetLostFocus() will be eventually executed in
  // the destructor of FrameTree. It uses InterstitialPageRVHDelegate, which
  // will be deleted because std::unique_ptr<InterstitialPageRVHDelegateView> is
  // placed after frame_tree_. See bug http://crbug.com/725594.
  frame_tree_.reset();
}

void InterstitialPageImpl::Show() {
  if (!enabled())
    return;

  // If an interstitial is already showing or about to be shown, close it before
  // showing the new one.
  // Be careful not to take an action on the old interstitial more than once.
  InterstitialPageMap::const_iterator iter =
      g_web_contents_to_interstitial_page->find(web_contents_);
  if (iter != g_web_contents_to_interstitial_page->end()) {
    InterstitialPageImpl* interstitial = iter->second;
    if (interstitial->action_taken_ != NO_ACTION) {
      interstitial->Hide();
    } else {
      // If we are currently showing an interstitial page for which we created
      // a transient entry and a new interstitial is shown as the result of a
      // new browser initiated navigation, then that transient entry has already
      // been discarded and a new pending navigation entry created.
      // So we should not discard that new pending navigation entry.
      // See http://crbug.com/9791
      if (new_navigation_ && interstitial->new_navigation_)
        interstitial->should_discard_pending_nav_entry_ = false;
      interstitial->DontProceed();
    }
  }

  // Block the resource requests for the render view host while it is hidden.
  TakeActionOnResourceDispatcher(BLOCK);
  // We need to be notified when the RenderViewHost is destroyed so we can
  // cancel the blocked requests.  We cannot do that on
  // NOTIFY_WEB_CONTENTS_DESTROYED as at that point the RenderViewHost has
  // already been destroyed.
  widget_observer_.Add(
      controller_->delegate()->GetRenderViewHost()->GetWidget());

  // Update the g_web_contents_to_interstitial_page map.
  iter = g_web_contents_to_interstitial_page->find(web_contents_);
  DCHECK(iter == g_web_contents_to_interstitial_page->end());
  (*g_web_contents_to_interstitial_page)[web_contents_] = this;

  if (new_navigation_) {
    std::unique_ptr<NavigationEntryImpl> entry =
        base::WrapUnique(new NavigationEntryImpl);
    entry->SetURL(url_);
    entry->SetVirtualURL(url_);
    entry->set_page_type(PAGE_TYPE_INTERSTITIAL);

    // Give delegates a chance to set some states on the navigation entry.
    delegate_->OverrideEntry(entry.get());

    controller_->SetTransientEntry(std::move(entry));

    static_cast<WebContentsImpl*>(web_contents_)
        ->DidChangeVisibleSecurityState();
  }

  DCHECK(!render_view_host_);
  render_view_host_ = CreateRenderViewHost();
  CreateWebContentsView();

  GURL data_url = GURL("data:text/html;charset=utf-8," +
                       net::EscapePath(delegate_->GetHTMLContents()));
  frame_tree_->root()->current_frame_host()->NavigateToInterstitialURL(
      data_url);
  frame_tree_->root()->current_frame_host()->UpdateAccessibilityMode();

  notification_registrar_.Add(this, NOTIFICATION_NAV_ENTRY_PENDING,
      Source<NavigationController>(controller_));
}

void InterstitialPageImpl::Hide() {
  // We may have already been hidden, and are just waiting to be deleted.
  // We can't check for enabled() here, because some callers have already
  // called Disable.
  if (!render_view_host_)
    return;

  Disable();

  RenderWidgetHostView* old_view =
      controller_->delegate()->GetRenderViewHost()->GetWidget()->GetView();
  if (controller_->delegate()->GetInterstitialPage() == this &&
      old_view &&
      !old_view->IsShowing() &&
      !controller_->delegate()->IsHidden()) {
    // Show the original RVH since we're going away.  Note it might not exist if
    // the renderer crashed while the interstitial was showing.
    // Note that it is important that we don't call Show() if the view is
    // already showing. That would result in bad things (unparented HWND on
    // Windows for example) happening.
    old_view->Show();
  }

  // Delete this and call Shutdown on the RVH asynchronously, as we may have
  // been called from a RVH delegate method, and we can't delete the RVH out
  // from under itself.
  base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
      FROM_HERE, base::BindOnce(&InterstitialPageImpl::Shutdown,
                                weak_ptr_factory_.GetWeakPtr()));
  bool has_focus = render_view_host_->GetWidget()->GetView() &&
                   render_view_host_->GetWidget()->GetView()->HasFocus();
  render_view_host_ = nullptr;
  frame_tree_->root()->current_frame_host()->ResetChildren();
  controller_->delegate()->DetachInterstitialPage(has_focus);
  // Let's revert to the original title if necessary.
  NavigationEntry* entry = controller_->GetVisibleEntry();
  if (entry && !new_navigation_ && should_revert_web_contents_title_)
    web_contents_->UpdateTitleForEntry(entry, original_web_contents_title_);

  static_cast<WebContentsImpl*>(web_contents_)->DidChangeVisibleSecurityState();

  auto iter = g_web_contents_to_interstitial_page->find(web_contents_);
  DCHECK(iter != g_web_contents_to_interstitial_page->end());
  if (iter != g_web_contents_to_interstitial_page->end())
    g_web_contents_to_interstitial_page->erase(iter);

  // Clear the WebContents pointer, because it may now be deleted.
  // This signifies that we are in the process of shutting down.
  web_contents_ = nullptr;
}

void InterstitialPageImpl::RenderWidgetHostDestroyed(
    content::RenderWidgetHost* widget_host) {
  widget_observer_.Remove(widget_host);
  if (action_taken_ == NO_ACTION) {
    // The RenderViewHost is being destroyed (as part of the tab being
    // closed); make sure we clear the blocked requests.
    RenderViewHost* rvh = RenderViewHost::From(widget_host);
    DCHECK(rvh->GetProcess()->GetID() == original_child_id_ &&
           rvh->GetRoutingID() == original_rvh_id_);
    TakeActionOnResourceDispatcher(CANCEL);
  }
}

void InterstitialPageImpl::Observe(
    int type,
    const NotificationSource& source,
    const NotificationDetails& details) {
  switch (type) {
    case NOTIFICATION_NAV_ENTRY_PENDING:
      // We are navigating away from the interstitial (the user has typed a URL
      // in the location bar or clicked a bookmark).  Make sure clicking on the
      // interstitial will have no effect.  Also cancel any blocked requests
      // on the ResourceDispatcherHost.  Note that when we get this notification
      // the RenderViewHost has not yet navigated so we'll unblock the
      // RenderViewHost before the resource request for the new page we are
      // navigating arrives in the ResourceDispatcherHost.  This ensures that
      // request won't be blocked if the same RenderViewHost was used for the
      // new navigation.
      Disable();
      TakeActionOnResourceDispatcher(CANCEL);
      break;
    default:
      NOTREACHED();
  }
}

bool InterstitialPageImpl::OnMessageReceived(
    RenderFrameHostImpl* render_frame_host,
    const IPC::Message& message) {
  if (render_frame_host->GetRenderViewHost() != render_view_host_) {
    DCHECK(!render_view_host_)
        << "We expect an interstitial page to have only a single RVH";
    return false;
  }

  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(InterstitialPageImpl, message,
                                   render_frame_host)
    IPC_MESSAGE_HANDLER(FrameHostMsg_DomOperationResponse,
                        OnDomOperationResponse)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

bool InterstitialPageImpl::OnMessageReceived(
    RenderViewHostImpl* render_view_host,
    const IPC::Message& message) {
  return false;
}

void InterstitialPageImpl::RenderFrameCreated(
    RenderFrameHost* render_frame_host) {
  // Note this is only for subframes in the interstitial, the notification for
  // the main frame happens in RenderViewCreated.
  controller_->delegate()->RenderFrameForInterstitialPageCreated(
      render_frame_host);
}

void InterstitialPageImpl::UpdateTitle(
    RenderFrameHost* render_frame_host,
    const base::string16& title,
    base::i18n::TextDirection title_direction) {
  if (!enabled())
    return;

  RenderViewHost* render_view_host = render_frame_host->GetRenderViewHost();
  DCHECK(render_view_host == render_view_host_);
  NavigationEntry* entry = controller_->GetVisibleEntry();
  if (!entry) {
    // There may be no visible entry if no URL has committed (e.g., after
    // window.open("")).  InterstitialPages with the new_navigation flag create
    // a transient NavigationEntry and thus have a visible entry.  However,
    // interstitials can still be created when there is no visible entry.  For
    // example, the opener window may inject content into the initial blank
    // page, which might trigger a SafeBrowsingBlockingPage.
    return;
  }

  // If this interstitial is shown on an existing navigation entry, we'll need
  // to remember its title so we can revert to it when hidden.
  if (!new_navigation_ && !should_revert_web_contents_title_) {
    original_web_contents_title_ = entry->GetTitle();
    should_revert_web_contents_title_ = true;
  }
  // TODO(evan): make use of title_direction.
  // http://code.google.com/p/chromium/issues/detail?id=27094
  web_contents_->UpdateTitleForEntry(entry, title);
}

InterstitialPage* InterstitialPageImpl::GetAsInterstitialPage() {
  return this;
}

ui::AXMode InterstitialPageImpl::GetAccessibilityMode() {
  if (web_contents_)
    return static_cast<WebContentsImpl*>(web_contents_)->GetAccessibilityMode();
  else
    return ui::AXMode();
}

void InterstitialPageImpl::Cut() {
  FrameTreeNode* focused_node = frame_tree_->GetFocusedFrame();
  if (!focused_node)
    return;

  focused_node->current_frame_host()->GetFrameInputHandler()->Cut();
  RecordAction(base::UserMetricsAction("Cut"));
}

void InterstitialPageImpl::ExecuteEditCommand(
    const std::string& command,
    const base::Optional<base::string16>& value) {
  FrameTreeNode* focused_node = frame_tree_->GetFocusedFrame();
  if (!focused_node)
    return;

  focused_node->current_frame_host()
      ->GetFrameInputHandler()
      ->ExecuteEditCommand(command, value);
}

void InterstitialPageImpl::Copy() {
  FrameTreeNode* focused_node = frame_tree_->GetFocusedFrame();
  if (!focused_node)
    return;

  focused_node->current_frame_host()->GetFrameInputHandler()->Copy();
  RecordAction(base::UserMetricsAction("Copy"));
}

void InterstitialPageImpl::Paste() {
  FrameTreeNode* focused_node = frame_tree_->GetFocusedFrame();
  if (!focused_node)
    return;

  focused_node->current_frame_host()->GetFrameInputHandler()->Paste();
  RecordAction(base::UserMetricsAction("Paste"));
}

void InterstitialPageImpl::SelectAll() {
  FrameTreeNode* focused_node = frame_tree_->GetFocusedFrame();
  if (!focused_node)
    return;

  focused_node->current_frame_host()->GetFrameInputHandler()->SelectAll();
  RecordAction(base::UserMetricsAction("SelectAll"));
}

RenderViewHostDelegateView* InterstitialPageImpl::GetDelegateView() {
  return rvh_delegate_view_.get();
}

WebContents* InterstitialPageImpl::GetWebContents() const {
  return web_contents();
}

const GURL& InterstitialPageImpl::GetMainFrameLastCommittedURL() {
  return url_;
}

void InterstitialPageImpl::RenderViewTerminated(
    RenderViewHost* render_view_host,
    base::TerminationStatus status,
    int error_code) {
  // Our renderer died. This should not happen in normal cases.
  // If we haven't already started shutdown, just dismiss the interstitial.
  // We cannot check for enabled() here, because we may have called Disable
  // without calling Hide.
  if (render_view_host_)
    DontProceed();
}

void InterstitialPageImpl::DidNavigate(
    RenderViewHost* render_view_host,
    const FrameHostMsg_DidCommitProvisionalLoad_Params& params) {
  // A fast user could have navigated away from the page that triggered the
  // interstitial while the interstitial was loading, that would have disabled
  // us. In that case we can dismiss ourselves.
  if (!enabled()) {
    DontProceed();
    return;
  }
  if (ui::PageTransitionCoreTypeIs(params.transition,
                                   ui::PAGE_TRANSITION_AUTO_SUBFRAME)) {
    // No need to handle navigate message from iframe in the interstitial page.
    return;
  }

  // The interstitial is not loading anymore so stop the throbber.
  pause_throbber_ = true;

  // The RenderViewHost has loaded its contents, we can show it now.
  if (!controller_->delegate()->IsHidden())
    render_view_host_->GetWidget()->GetView()->Show();
  controller_->delegate()->AttachInterstitialPage(this);
  render_view_host_->GetWidget()->GetView()->OnInterstitialPageAttached();

  RenderWidgetHostView* rwh_view =
      controller_->delegate()->GetRenderViewHost()->GetWidget()->GetView();

  // The RenderViewHost may already have crashed before we even get here.
  if (rwh_view) {
    // If the page has focus, focus the interstitial.
    if (rwh_view->HasFocus())
      Focus();

    // Hide the original RVH since we're showing the interstitial instead.
    rwh_view->Hide();
  }
}

WebContents* InterstitialPageImpl::OpenURL(const OpenURLParams& params) {
  NOTREACHED();
  return nullptr;
}

const std::string& InterstitialPageImpl::GetUserAgentOverride() {
  return base::EmptyString();
}

bool InterstitialPageImpl::ShouldOverrideUserAgentInNewTabs() {
  return false;
}

bool InterstitialPageImpl::ShowingInterstitialPage() {
  // An interstitial page never shows a second interstitial.
  return false;
}

RendererPreferences InterstitialPageImpl::GetRendererPrefs(
    BrowserContext* browser_context) const {
  delegate_->OverrideRendererPrefs(&renderer_preferences_);
  return renderer_preferences_;
}

void InterstitialPageImpl::RenderWidgetDeleted(
    RenderWidgetHostImpl* render_widget_host) {
  // TODO(creis): Remove this method once we verify the shutdown path is sane.
  CHECK(!web_contents_);
}

KeyboardEventProcessingResult InterstitialPageImpl::PreHandleKeyboardEvent(
    const NativeWebKeyboardEvent& event) {
  if (!enabled())
    return KeyboardEventProcessingResult::NOT_HANDLED;
  return render_widget_host_delegate_->PreHandleKeyboardEvent(event);
}

bool InterstitialPageImpl::PreHandleMouseEvent(
    const blink::WebMouseEvent& event) {
  if (!enabled())
    return false;

  if (event.GetType() == blink::WebInputEvent::Type::kMouseUp &&
      event.button == blink::WebPointerProperties::Button::kBack &&
      controller_->CanGoBack()) {
    controller_->GoBack();
    return true;
  }
  return false;
}

bool InterstitialPageImpl::HandleKeyboardEvent(
    const NativeWebKeyboardEvent& event) {
  return enabled() && render_widget_host_delegate_->HandleKeyboardEvent(event);
}

WebContents* InterstitialPageImpl::web_contents() const {
  return web_contents_;
}

RenderViewHostImpl* InterstitialPageImpl::CreateRenderViewHost() {
  if (!enabled())
    return nullptr;

  // Interstitial pages don't want to share the session storage so we mint a
  // new one.
  BrowserContext* browser_context = web_contents()->GetBrowserContext();
  scoped_refptr<SiteInstance> site_instance =
      SiteInstance::Create(browser_context);
  DOMStorageContextWrapper* dom_storage_context =
      static_cast<DOMStorageContextWrapper*>(
          BrowserContext::GetStoragePartition(
              browser_context, site_instance.get())->GetDOMStorageContext());
  session_storage_namespace_ =
      SessionStorageNamespaceImpl::Create(dom_storage_context);

  // Use the RenderViewHost from our FrameTree.
  frame_tree_->root()->render_manager()->Init(
      site_instance.get(), MSG_ROUTING_NONE, MSG_ROUTING_NONE, MSG_ROUTING_NONE,
      false);
  return frame_tree_->root()->current_frame_host()->render_view_host();
}

WebContentsView* InterstitialPageImpl::CreateWebContentsView() {
  if (!enabled() || !create_view_)
    return nullptr;
  WebContentsView* wcv =
      static_cast<WebContentsImpl*>(web_contents())->GetView();
  RenderWidgetHostViewBase* view =
      wcv->CreateViewForWidget(render_view_host_->GetWidget(), false);
  render_view_host_->GetWidget()->SetView(view);
  render_view_host_->GetMainFrame()->AllowBindings(
      BINDINGS_POLICY_DOM_AUTOMATION);

  render_view_host_->CreateRenderView(MSG_ROUTING_NONE, MSG_ROUTING_NONE,
                                      base::UnguessableToken::Create(),
                                      FrameReplicationState(), false);
  controller_->delegate()->RenderFrameForInterstitialPageCreated(
      frame_tree_->root()->current_frame_host());
  view->SetSize(web_contents()->GetContainerBounds().size());
  // Don't show the interstitial until we have navigated to it.
  view->Hide();
  return wcv;
}

void InterstitialPageImpl::Proceed() {
  // Don't repeat this if we are already shutting down.  We cannot check for
  // enabled() here, because we may have called Disable without calling Hide.
  if (!render_view_host_)
    return;

  if (action_taken_ != NO_ACTION) {
    NOTREACHED();
    return;
  }
  Disable();
  action_taken_ = PROCEED_ACTION;

  // Resumes the throbber, if applicable.
  pause_throbber_ = false;
  controller_->delegate()->DidProceedOnInterstitial();

  // If this is a new navigation, the old page is going away, so we cancel any
  // blocked requests for it.  If it is not a new navigation, then it means the
  // interstitial was shown as a result of a resource loading in the page.
  // Since the user wants to proceed, we'll let any blocked request go through.
  if (new_navigation_)
    TakeActionOnResourceDispatcher(CANCEL);
  else
    TakeActionOnResourceDispatcher(RESUME);

  // No need to hide if we are a new navigation, we'll get hidden when the
  // navigation is committed.
  if (!new_navigation_) {
    Hide();
    delegate_->OnProceed();
    return;
  }

  delegate_->OnProceed();
}

void InterstitialPageImpl::DontProceed() {
  // Don't repeat this if we are already shutting down.  We cannot check for
  // enabled() here, because we may have called Disable without calling Hide.
  if (!render_view_host_)
    return;
  DCHECK(action_taken_ != DONT_PROCEED_ACTION);

  Disable();
  action_taken_ = DONT_PROCEED_ACTION;

  // If this is a new navigation, we are returning to the original page, so we
  // resume blocked requests for it.  If it is not a new navigation, then it
  // means the interstitial was shown as a result of a resource loading in the
  // page and we won't return to the original page, so we cancel blocked
  // requests in that case.
  if (new_navigation_)
    TakeActionOnResourceDispatcher(RESUME);
  else
    TakeActionOnResourceDispatcher(CANCEL);

  if (should_discard_pending_nav_entry_) {
    // Since no navigation happens we have to discard the transient entry
    // explicitly.  Note that by calling DiscardNonCommittedEntries() we also
    // discard the pending entry, which is what we want, since the navigation is
    // cancelled.
    controller_->DiscardNonCommittedEntries();
  }

  Hide();
  delegate_->OnDontProceed();
}

void InterstitialPageImpl::CancelForNavigation() {
  // The user is trying to navigate away.  We should unblock the renderer and
  // disable the interstitial, but keep it visible until the navigation
  // completes.
  Disable();
  // If this interstitial was shown for a new navigation, allow any navigations
  // on the original page to resume (e.g., subresource requests, XHRs, etc).
  // Otherwise, cancel the pending, possibly dangerous navigations.
  if (new_navigation_)
    TakeActionOnResourceDispatcher(RESUME);
  else
    TakeActionOnResourceDispatcher(CANCEL);
}

void InterstitialPageImpl::SetSize(const gfx::Size& size) {
  if (!enabled())
    return;
#if !defined(OS_MACOSX)
  // When a tab is closed, we might be resized after our view was NULLed
  // (typically if there was an info-bar).
  if (render_view_host_->GetWidget()->GetView())
    render_view_host_->GetWidget()->GetView()->SetSize(size);
#else
  // TODO(port): Does Mac need to SetSize?
  NOTIMPLEMENTED();
#endif
}

void InterstitialPageImpl::Focus() {
  // Focus the native window.
  if (!enabled())
    return;
  render_view_host_->GetWidget()->GetView()->Focus();
}

void InterstitialPageImpl::FocusThroughTabTraversal(bool reverse) {
  if (!enabled())
    return;
  render_view_host_->SetInitialFocus(reverse);
}

RenderWidgetHostView* InterstitialPageImpl::GetView() {
  return render_view_host_->GetWidget()->GetView();
}

RenderFrameHost* InterstitialPageImpl::GetMainFrame() const {
  if (!render_view_host_)
    return nullptr;
  return render_view_host_->GetMainFrame();
}

InterstitialPageDelegate* InterstitialPageImpl::GetDelegateForTesting() {
  return delegate_.get();
}

void InterstitialPageImpl::DontCreateViewForTesting() {
  create_view_ = false;
}

void InterstitialPageImpl::CreateNewWindow(
    RenderFrameHost* opener,
    int32_t render_view_route_id,
    int32_t main_frame_route_id,
    int32_t main_frame_widget_route_id,
    const mojom::CreateNewWindowParams& params,
    SessionStorageNamespace* session_storage_namespace) {
  NOTREACHED() << "InterstitialPage does not support showing popups.";
}

void InterstitialPageImpl::SetFocusedFrame(FrameTreeNode* node,
                                           SiteInstance* source) {
  frame_tree_->SetFocusedFrame(node, source);

  if (web_contents_) {
    static_cast<WebContentsImpl*>(web_contents_)
        ->SetAsFocusedWebContentsIfNecessary();
  }
}

Visibility InterstitialPageImpl::GetVisibility() {
  // Interstitials always occlude the underlying web content.
  return Visibility::OCCLUDED;
}

void InterstitialPageImpl::CreateNewWidget(int32_t render_process_id,
                                           int32_t route_id,
                                           mojom::WidgetPtr widget) {
  NOTREACHED() << "InterstitialPage does not support showing drop-downs.";
}

void InterstitialPageImpl::CreateNewFullscreenWidget(int32_t render_process_id,
                                                     int32_t route_id,
                                                     mojom::WidgetPtr widget) {
  NOTREACHED()
      << "InterstitialPage does not support showing full screen popups.";
}

void InterstitialPageImpl::ShowCreatedWindow(int process_id,
                                             int main_frame_widget_route_id,
                                             WindowOpenDisposition disposition,
                                             const gfx::Rect& initial_rect,
                                             bool user_gesture) {
  NOTREACHED() << "InterstitialPage does not support showing popups.";
}

void InterstitialPageImpl::ShowCreatedWidget(int process_id,
                                             int route_id,
                                             const gfx::Rect& initial_rect) {
  NOTREACHED() << "InterstitialPage does not support showing drop-downs.";
}

void InterstitialPageImpl::ShowCreatedFullscreenWidget(int process_id,
                                                       int route_id) {
  NOTREACHED()
      << "InterstitialPage does not support showing full screen popups.";
}

SessionStorageNamespace* InterstitialPageImpl::GetSessionStorageNamespace(
    SiteInstance* instance) {
  return session_storage_namespace_.get();
}

FrameTree* InterstitialPageImpl::GetFrameTree() {
  return frame_tree_.get();
}

void InterstitialPageImpl::Disable() {
  enabled_ = false;

  // Also let the InterstitialPageNavigatorImpl know.
  static_cast<InterstitialPageNavigatorImpl*>(frame_tree_->root()->navigator())
      ->Disable();
}

void InterstitialPageImpl::Shutdown() {
  delete this;
}

void InterstitialPageImpl::OnNavigatingAwayOrTabClosing() {
  // Notify the RenderWidgetHostView so it can clean up interstitial resources
  // before the WebContents is fully destroyed.
  if (render_view_host_ && render_view_host_->GetWidget() &&
      render_view_host_->GetWidget()->GetView()) {
    render_view_host_->GetWidget()->GetView()->OnInterstitialPageGoingAway();
  }
  if (action_taken_ == NO_ACTION) {
    // We are navigating away from the interstitial or closing a tab with an
    // interstitial.  Default to DontProceed(). We don't just call Hide as
    // subclasses will almost certainly override DontProceed to do some work
    // (ex: close pending connections).
    DontProceed();
  } else {
    // User decided to proceed and either the navigation was committed or
    // the tab was closed before that.
    Hide();
  }
}

void InterstitialPageImpl::TakeActionOnResourceDispatcher(
    ResourceRequestAction action) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (action == CANCEL || action == RESUME) {
    if (resource_dispatcher_host_notified_)
      return;
    resource_dispatcher_host_notified_ = true;
  }

  // The tab might not have a render_view_host if it was closed (in which case,
  // we have taken care of the blocked requests when processing
  // NOTIFY_RENDER_WIDGET_HOST_DESTROYED.
  RenderViewHostImpl* rvh = RenderViewHostImpl::FromID(original_child_id_,
                                                       original_rvh_id_);
  if (!rvh)
    return;

  RenderFrameHostImpl* rfh =
      static_cast<RenderFrameHostImpl*>(rvh->GetMainFrame());
  // Note, the RenderViewHost can lose its main frame if a new RenderFrameHost
  // commits with a new RenderViewHost. Additionally, RenderViewHosts for OOPIF
  // don't have main frames.
  if (!rfh)
    return;

  switch (action) {
    case BLOCK:
      rfh->BlockRequestsForFrame();
      break;
    case RESUME:
      rfh->ResumeBlockedRequestsForFrame();
      break;
    default:
      DCHECK_EQ(action, CANCEL);
      rfh->CancelBlockedRequestsForFrame();
      break;
  }
}

void InterstitialPageImpl::OnDomOperationResponse(
    RenderFrameHostImpl* source,
    const std::string& json_string) {
  std::string json = json_string;
  // Needed by test code.
  NotificationService::current()->Notify(NOTIFICATION_DOM_OPERATION_RESPONSE,
                                         Source<WebContents>(web_contents()),
                                         Details<std::string>(&json));

  if (!enabled())
    return;
  delegate_->CommandReceived(json_string);
}


InterstitialPageImpl::InterstitialPageRVHDelegateView::
    InterstitialPageRVHDelegateView(InterstitialPageImpl* page)
    : interstitial_page_(page) {
}

#if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
void InterstitialPageImpl::InterstitialPageRVHDelegateView::ShowPopupMenu(
    RenderFrameHost* render_frame_host,
    const gfx::Rect& bounds,
    int item_height,
    double item_font_size,
    int selected_item,
    const std::vector<MenuItem>& items,
    bool right_aligned,
    bool allow_multiple_selection) {
  NOTREACHED() << "InterstitialPage does not support showing popup menus.";
}

void InterstitialPageImpl::InterstitialPageRVHDelegateView::HidePopupMenu() {
  NOTREACHED() << "InterstitialPage does not support showing popup menus.";
}
#endif

void InterstitialPageImpl::InterstitialPageRVHDelegateView::StartDragging(
    const DropData& drop_data,
    WebDragOperationsMask allowed_operations,
    const gfx::ImageSkia& image,
    const gfx::Vector2d& image_offset,
    const DragEventSourceInfo& event_info,
    RenderWidgetHostImpl* source_rwh) {
  interstitial_page_->render_view_host_->GetWidget()->
      DragSourceSystemDragEnded();
  DVLOG(1) << "InterstitialPage does not support dragging yet.";
}

void InterstitialPageImpl::InterstitialPageRVHDelegateView::UpdateDragCursor(
    WebDragOperation) {
  NOTREACHED() << "InterstitialPage does not support dragging yet.";
}

void InterstitialPageImpl::InterstitialPageRVHDelegateView::GotFocus(
    RenderWidgetHostImpl* render_widget_host) {
  WebContents* web_contents = interstitial_page_->web_contents();
  if (web_contents) {
    static_cast<WebContentsImpl*>(web_contents)
        ->NotifyWebContentsFocused(render_widget_host);
  }
}

void InterstitialPageImpl::InterstitialPageRVHDelegateView::LostFocus(
    RenderWidgetHostImpl* render_widget_host) {
  WebContents* web_contents = interstitial_page_->web_contents();
  if (web_contents) {
    static_cast<WebContentsImpl*>(web_contents)
        ->NotifyWebContentsLostFocus(render_widget_host);
  }
}

void InterstitialPageImpl::InterstitialPageRVHDelegateView::TakeFocus(
    bool reverse) {
  if (!interstitial_page_->web_contents())
    return;
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(interstitial_page_->web_contents());
  if (!web_contents->GetDelegateView())
    return;

  web_contents->GetDelegateView()->TakeFocus(reverse);
}

int InterstitialPageImpl::InterstitialPageRVHDelegateView::
    GetTopControlsHeight() const {
  if (!interstitial_page_->web_contents())
    return 0;
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(interstitial_page_->web_contents());
  if (!web_contents || !web_contents->GetDelegateView())
    return 0;
  return web_contents->GetDelegateView()->GetTopControlsHeight();
}

int InterstitialPageImpl::InterstitialPageRVHDelegateView::
    GetBottomControlsHeight() const {
  if (!interstitial_page_->web_contents())
    return 0;
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(interstitial_page_->web_contents());
  if (!web_contents || !web_contents->GetDelegateView())
    return 0;
  return web_contents->GetDelegateView()->GetBottomControlsHeight();
}

bool InterstitialPageImpl::InterstitialPageRVHDelegateView::
    DoBrowserControlsShrinkRendererSize() const {
  if (!interstitial_page_->web_contents())
    return false;
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(interstitial_page_->web_contents());
  if (!web_contents || !web_contents->GetDelegateView())
    return false;
  return web_contents->GetDelegateView()->DoBrowserControlsShrinkRendererSize();
}

void InterstitialPageImpl::InterstitialPageRVHDelegateView::OnFindReply(
    int request_id, int number_of_matches, const gfx::Rect& selection_rect,
    int active_match_ordinal, bool final_update) {
}

InterstitialPageImpl::UnderlyingContentObserver::UnderlyingContentObserver(
    WebContents* web_contents,
    InterstitialPageImpl* interstitial)
    : WebContentsObserver(web_contents), interstitial_(interstitial) {
}

void InterstitialPageImpl::UnderlyingContentObserver::NavigationEntryCommitted(
    const LoadCommittedDetails& load_details) {
  interstitial_->OnNavigatingAwayOrTabClosing();
}

void InterstitialPageImpl::UnderlyingContentObserver::WebContentsDestroyed() {
  interstitial_->OnNavigatingAwayOrTabClosing();
}

TextInputManager* InterstitialPageImpl::GetTextInputManager() {
  return !web_contents_ ? nullptr : static_cast<WebContentsImpl*>(web_contents_)
                                        ->GetTextInputManager();
}

RenderWidgetHostInputEventRouter* InterstitialPageImpl::GetInputEventRouter() {
  WebContentsImpl* web_contents_impl =
      static_cast<WebContentsImpl*>(web_contents_);
  if (!web_contents_impl)
    return nullptr;

  return web_contents_impl->GetInputEventRouter();
}

BrowserAccessibilityManager*
InterstitialPageImpl::GetRootBrowserAccessibilityManager() {
  WebContentsImpl* web_contents_impl =
      static_cast<WebContentsImpl*>(web_contents_);
  if (!web_contents_impl)
    return nullptr;

  return web_contents_impl->GetRootBrowserAccessibilityManager();
}

BrowserAccessibilityManager*
InterstitialPageImpl::GetOrCreateRootBrowserAccessibilityManager() {
  WebContentsImpl* web_contents_impl =
      static_cast<WebContentsImpl*>(web_contents_);
  if (!web_contents_impl)
    return nullptr;

  return web_contents_impl->GetOrCreateRootBrowserAccessibilityManager();
}

void InterstitialPageImpl::AudioContextPlaybackStarted(RenderFrameHost* host,
                                                       int context_id) {
  // Interstitial pages should not be playing any sound via WebAudio
  NOTREACHED();
}

void InterstitialPageImpl::AudioContextPlaybackStopped(RenderFrameHost* host,
                                                       int context_id) {
  // Interstitial pages should not be playing any sound via WebAudio.
  NOTREACHED();
}

}  // namespace content
