<commit_before>// Copyright (c) 2012 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 "chrome/browser/download/download_request_limiter.h"

#include "base/bind.h"
#include "base/stl_util.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/download/download_permission_request.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "url/gurl.h"

#if defined(OS_ANDROID)
#include "chrome/browser/download/download_request_infobar_delegate.h"
#endif

using content::BrowserThread;
using content::NavigationController;
using content::NavigationEntry;

// TabDownloadState ------------------------------------------------------------

DownloadRequestLimiter::TabDownloadState::TabDownloadState(
    DownloadRequestLimiter* host,
    content::WebContents* contents,
    content::WebContents* originating_web_contents)
    : content::WebContentsObserver(contents),
      web_contents_(contents),
      host_(host),
      status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD),
      download_count_(0),
      factory_(this) {
  content::Source<NavigationController> notification_source(
      &contents->GetController());
  registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
                 notification_source);
  NavigationEntry* active_entry = originating_web_contents ?
      originating_web_contents->GetController().GetActiveEntry() :
      contents->GetController().GetActiveEntry();
  if (active_entry)
    initial_page_host_ = active_entry->GetURL().host();
}

DownloadRequestLimiter::TabDownloadState::~TabDownloadState() {
  // We should only be destroyed after the callbacks have been notified.
  DCHECK(callbacks_.empty());

  // And we should have invalidated the back pointer.
  DCHECK(!factory_.HasWeakPtrs());
}

void DownloadRequestLimiter::TabDownloadState::DidNavigateMainFrame(
    const content::LoadCommittedDetails& details,
    const content::FrameNavigateParams& params) {
  switch (status_) {
    case ALLOW_ONE_DOWNLOAD:
    case PROMPT_BEFORE_DOWNLOAD:
      // When the user reloads the page without responding to the infobar, they
      // are expecting DownloadRequestLimiter to behave as if they had just
      // initially navigated to this page. See http://crbug.com/171372
      NotifyCallbacks(false);
      host_->Remove(this, web_contents());
      // WARNING: We've been deleted.
      break;
    case DOWNLOADS_NOT_ALLOWED:
    case ALLOW_ALL_DOWNLOADS:
      // Don't drop this information. The user has explicitly said that they
      // do/don't want downloads from this host.  If they accidentally Accepted
      // or Canceled, tough luck, they don't get another chance. They can copy
      // the URL into a new tab, which will make a new DownloadRequestLimiter.
      // See also the initial_page_host_ logic in Observe() for<commit_msg>c/b/download: Replace usage of GetActiveEntry by GetLastCommittedEntry.<commit_after>// Copyright (c) 2012 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 "chrome/browser/download/download_request_limiter.h"

#include "base/bind.h"
#include "base/stl_util.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/download/download_permission_request.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "url/gurl.h"

#if defined(OS_ANDROID)
#include "chrome/browser/download/download_request_infobar_delegate.h"
#endif

using content::BrowserThread;
using content::NavigationController;
using content::NavigationEntry;

// TabDownloadState ------------------------------------------------------------

DownloadRequestLimiter::TabDownloadState::TabDownloadState(
    DownloadRequestLimiter* host,
    content::WebContents* contents,
    content::WebContents* originating_web_contents)
    : content::WebContentsObserver(contents),
      web_contents_(contents),
      host_(host),
      status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD),
      download_count_(0),
      factory_(this) {
  content::Source<NavigationController> notification_source(
      &contents->GetController());
  registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
                 notification_source);
  NavigationEntry* last_entry = originating_web_contents ?
      originating_web_contents->GetController().GetLastCommittedEntry() :
      contents->GetController().GetLastCommittedEntry();
  if (last_entry)
    initial_page_host_ = last_entry->GetURL().host();
}

DownloadRequestLimiter::TabDownloadState::~TabDownloadState() {
  // We should only be destroyed after the callbacks have been notified.
  DCHECK(callbacks_.empty());

  // And we should have invalidated the back pointer.
  DCHECK(!factory_.HasWeakPtrs());
}

void DownloadRequestLimiter::TabDownloadState::DidNavigateMainFrame(
    const content::LoadCommittedDetails& details,
    const content::FrameNavigateParams& params) {
  switch (status_) {
    case ALLOW_ONE_DOWNLOAD:
    case PROMPT_BEFORE_DOWNLOAD:
      // When the user reloads the page without responding to the infobar, they
      // are expecting DownloadRequestLimiter to behave as if they had just
      // initially navigated to this page. See http://crbug.com/171372
      NotifyCallbacks(false);
      host_->Remove(this, web_contents());
      // WARNING: We've been deleted.
      break;
    case DOWNLOADS_NOT_ALLOWED:
    case ALLOW_ALL_DOWNLOADS:
      // Don't drop this information. The user has explicitly said that they
      // do/don't want downloads from this host.  If they accidentally Accepted
      // or Canceled, tough luck, they don't get another chance. They can copy
      // the URL into a new tab, which will make a new DownloadRequestLimiter.
      // See also the initial_page_host_ logic in Observe() for
{'fraction_non_alphanumeric': 0.11433852653815685, 'fraction_numerical': 0.002904673884341167, 'mean_word_length': 4.553519061583578, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 43, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4435446', 'n_tokens_mistral': 2171, 'n_tokens_neox': 2127, 'n_words': 487}