This source file includes following definitions.
- ping_request
 
- ping_response
 
- ping_response_
 
- CreateForDownload
 
- FromDownload
 
- weak_ptr_factory_
 
- MaybeStorePingsForDownload
 
- IsEnabledForDownload
 
- GetPingsForDownloadForTesting
 
- RecordEligibleDownloadShown
 
- BeginFeedbackForDownload
 
- BeginFeedbackOrDeleteFile
 
- StartPendingFeedback
 
- BeginFeedback
 
- FeedbackComplete
 
#include "chrome/browser/safe_browsing/download_feedback_service.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util_proxy.h"
#include "base/metrics/histogram.h"
#include "base/supports_user_data.h"
#include "base/task_runner.h"
#include "chrome/browser/safe_browsing/download_feedback.h"
#include "content/public/browser/download_danger_type.h"
#include "content/public/browser/download_item.h"
namespace safe_browsing {
namespace {
const void* kPingKey = &kPingKey;
class DownloadFeedbackPings : public base::SupportsUserData::Data {
 public:
  DownloadFeedbackPings(const std::string& ping_request,
                        const std::string& ping_response);
  
  static void CreateForDownload(content::DownloadItem* download,
                                const std::string& ping_request,
                                const std::string& ping_response);
  
  
  static DownloadFeedbackPings* FromDownload(
      const content::DownloadItem& download);
  const std::string& ping_request() const {
    return ping_request_;
  }
  const std::string& ping_response() const {
    return ping_response_;
  }
 private:
  std::string ping_request_;
  std::string ping_response_;
};
DownloadFeedbackPings::DownloadFeedbackPings(const std::string& ping_request,
                                             const std::string& ping_response)
    : ping_request_(ping_request),
      ping_response_(ping_response) {
}
void DownloadFeedbackPings::CreateForDownload(
    content::DownloadItem* download,
    const std::string& ping_request,
    const std::string& ping_response) {
  DownloadFeedbackPings* pings = new DownloadFeedbackPings(ping_request,
                                                           ping_response);
  download->SetUserData(kPingKey, pings);
}
DownloadFeedbackPings* DownloadFeedbackPings::FromDownload(
    const content::DownloadItem& download) {
  return static_cast<DownloadFeedbackPings*>(download.GetUserData(kPingKey));
}
}  
DownloadFeedbackService::DownloadFeedbackService(
    net::URLRequestContextGetter* request_context_getter,
    base::TaskRunner* file_task_runner)
    : request_context_getter_(request_context_getter),
      file_task_runner_(file_task_runner),
      weak_ptr_factory_(this) {
}
DownloadFeedbackService::~DownloadFeedbackService() {
  DCHECK(CalledOnValidThread());
}
void DownloadFeedbackService::MaybeStorePingsForDownload(
    DownloadProtectionService::DownloadCheckResult result,
    content::DownloadItem* download,
    const std::string& ping,
    const std::string& response) {
  if (result != DownloadProtectionService::UNCOMMON &&
      result != DownloadProtectionService::DANGEROUS_HOST)
    return;
  UMA_HISTOGRAM_COUNTS("SBDownloadFeedback.SizeEligibleKB",
                       download->GetReceivedBytes() / 1024);
  if (download->GetReceivedBytes() > DownloadFeedback::kMaxUploadSize)
    return;
  DownloadFeedbackPings::CreateForDownload(download, ping, response);
}
bool DownloadFeedbackService::IsEnabledForDownload(
    const content::DownloadItem& download) {
  return !!DownloadFeedbackPings::FromDownload(download);
}
bool DownloadFeedbackService::GetPingsForDownloadForTesting(
    const content::DownloadItem& download,
    std::string* ping,
    std::string* response) {
  DownloadFeedbackPings* pings = DownloadFeedbackPings::FromDownload(download);
  if (!pings)
    return false;
  *ping = pings->ping_request();
  *response = pings->ping_response();
  return true;
}
void DownloadFeedbackService::RecordEligibleDownloadShown(
    content::DownloadDangerType danger_type) {
  UMA_HISTOGRAM_ENUMERATION("SBDownloadFeedback.Eligible",
                            danger_type,
                            content::DOWNLOAD_DANGER_TYPE_MAX);
}
void DownloadFeedbackService::BeginFeedbackForDownload(
    content::DownloadItem* download) {
  DCHECK(CalledOnValidThread());
  UMA_HISTOGRAM_ENUMERATION("SBDownloadFeedback.Activations",
                            download->GetDangerType(),
                            content::DOWNLOAD_DANGER_TYPE_MAX);
  DownloadFeedbackPings* pings = DownloadFeedbackPings::FromDownload(*download);
  DCHECK(pings);
  download->StealDangerousDownload(
      base::Bind(&DownloadFeedbackService::BeginFeedbackOrDeleteFile,
                 file_task_runner_,
                 weak_ptr_factory_.GetWeakPtr(),
                 pings->ping_request(),
                 pings->ping_response()));
}
void DownloadFeedbackService::BeginFeedbackOrDeleteFile(
    const scoped_refptr<base::TaskRunner>& file_task_runner,
    const base::WeakPtr<DownloadFeedbackService>& service,
    const std::string& ping_request,
    const std::string& ping_response,
    const base::FilePath& path) {
  if (service) {
    service->BeginFeedback(ping_request, ping_response, path);
  } else {
    base::FileUtilProxy::DeleteFile(file_task_runner.get(),
                                    path,
                                    false,
                                    base::FileUtilProxy::StatusCallback());
  }
}
void DownloadFeedbackService::StartPendingFeedback() {
  DCHECK(!active_feedback_.empty());
  active_feedback_.front()->Start(base::Bind(
      &DownloadFeedbackService::FeedbackComplete, base::Unretained(this)));
}
void DownloadFeedbackService::BeginFeedback(
    const std::string& ping_request,
    const std::string& ping_response,
    const base::FilePath& path) {
  DCHECK(CalledOnValidThread());
  DownloadFeedback* feedback =
      DownloadFeedback::Create(request_context_getter_.get(),
                               file_task_runner_.get(),
                               path,
                               ping_request,
                               ping_response);
  active_feedback_.push_back(feedback);
  UMA_HISTOGRAM_COUNTS_100("SBDownloadFeedback.ActiveFeedbacks",
                           active_feedback_.size());
  if (active_feedback_.size() == 1)
    StartPendingFeedback();
}
void DownloadFeedbackService::FeedbackComplete() {
  DVLOG(1) << __FUNCTION__;
  DCHECK(CalledOnValidThread());
  DCHECK(!active_feedback_.empty());
  active_feedback_.erase(active_feedback_.begin());
  if (!active_feedback_.empty())
    StartPendingFeedback();
}
}