Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: chrome/browser/safe_browsing/download_feedback_service.cc

Issue 15881012: Implement safebrowsing download feedback service, enabled for dev & canary only. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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/safe_browsing/download_feedback_service.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/files/file_path.h"
10 #include "base/files/file_util_proxy.h"
11 #include "base/metrics/histogram.h"
12 #include "base/supports_user_data.h"
13 #include "base/task_runner.h"
14 #include "chrome/browser/safe_browsing/download_feedback.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/common/chrome_version_info.h"
17 #include "content/public/browser/download_danger_type.h"
18 #include "content/public/browser/download_item.h"
19
20 namespace safe_browsing {
21
22 namespace {
23
24 const void* kPingKey = &kPingKey;
25
26 bool IsEnabled() {
27 CommandLine* cmdline = CommandLine::ForCurrentProcess();
28 if (cmdline->HasSwitch(switches::kSbEnableDownloadFeedback))
29 return true;
30
31 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
32 if (channel == chrome::VersionInfo::CHANNEL_UNKNOWN ||
33 channel == chrome::VersionInfo::CHANNEL_CANARY ||
34 channel == chrome::VersionInfo::CHANNEL_DEV)
35 return true;
36
37 return false;
38 }
39
40 class DownloadFeedbackPings : public base::SupportsUserData::Data {
41 public:
42 DownloadFeedbackPings(const std::string& ping_request,
43 const std::string& ping_response);
44
45 // Stores the ping data in the given |download|.
46 static void CreateForDownload(content::DownloadItem* download,
47 const std::string& ping_request,
48 const std::string& ping_response);
49
50 // Returns the DownloadFeedbackPings object associated with |download|. May
51 // return NULL.
52 static DownloadFeedbackPings* FromDownload(
53 const content::DownloadItem& download);
54
55
56 const std::string& ping_request() const {
57 return ping_request_;
58 }
59
60 const std::string& ping_response() const {
61 return ping_response_;
62 }
63
64 private:
65 std::string ping_request_;
66 std::string ping_response_;
67 };
68
69 DownloadFeedbackPings::DownloadFeedbackPings(const std::string& ping_request,
70 const std::string& ping_response)
71 : ping_request_(ping_request),
72 ping_response_(ping_response) {
73 }
74
75 // static
76 void DownloadFeedbackPings::CreateForDownload(
77 content::DownloadItem* download,
78 const std::string& ping_request,
79 const std::string& ping_response) {
80 DownloadFeedbackPings* pings = new DownloadFeedbackPings(ping_request,
81 ping_response);
82 download->SetUserData(kPingKey, pings);
83 }
84
85 // static
86 DownloadFeedbackPings* DownloadFeedbackPings::FromDownload(
87 const content::DownloadItem& download) {
88 return static_cast<DownloadFeedbackPings*>(download.GetUserData(kPingKey));
89 }
90
91 } // namespace
92
93 DownloadFeedbackService::DownloadFeedbackService(
94 net::URLRequestContextGetter* request_context_getter,
95 base::TaskRunner* file_task_runner)
96 : request_context_getter_(request_context_getter),
97 file_task_runner_(file_task_runner),
98 weak_ptr_factory_(this) {
99 }
100
101 DownloadFeedbackService::~DownloadFeedbackService() {
102 DCHECK(CalledOnValidThread());
103 }
104
105 // static
106 void DownloadFeedbackService::MaybeStorePingsForDownload(
107 DownloadProtectionService::DownloadCheckResult result,
108 content::DownloadItem* download,
109 const std::string& ping,
110 const std::string& response) {
111 if (!IsEnabled() || !(result == DownloadProtectionService::UNCOMMON ||
112 result == DownloadProtectionService::DANGEROUS_HOST))
113 return;
114 UMA_HISTOGRAM_COUNTS("SBDownloadFeedback.SizeEligibleKB",
115 download->GetReceivedBytes() / 1024);
116 if (download->GetReceivedBytes() > DownloadFeedback::kMaxUploadSize)
117 return;
118
119 DownloadFeedbackPings::CreateForDownload(download, ping, response);
120 }
121
122 // static
123 bool DownloadFeedbackService::IsEnabledForDownload(
124 const content::DownloadItem& download) {
125 return !!DownloadFeedbackPings::FromDownload(download);
126 }
127
128 // static
129 bool DownloadFeedbackService::GetPingsForDownloadForTesting(
130 const content::DownloadItem& download,
131 std::string* ping,
132 std::string* response) {
133 DownloadFeedbackPings* pings = DownloadFeedbackPings::FromDownload(download);
134 if (!pings)
135 return false;
136
137 *ping = pings->ping_request();
138 *response = pings->ping_response();
139 return true;
140 }
141
142 // static
143 void DownloadFeedbackService::RecordFeedbackButtonShown(
144 content::DownloadDangerType danger_type) {
145 UMA_HISTOGRAM_ENUMERATION("SBDownloadFeedback.Shown",
146 danger_type,
147 content::DOWNLOAD_DANGER_TYPE_MAX);
148 }
149
150
151 void DownloadFeedbackService::BeginFeedbackForDownload(
152 content::DownloadItem* download) {
153 DCHECK(CalledOnValidThread());
154
155 UMA_HISTOGRAM_ENUMERATION("SBDownloadFeedback.Activations",
156 download->GetDangerType(),
157 content::DOWNLOAD_DANGER_TYPE_MAX);
158
159 DownloadFeedbackPings* pings = DownloadFeedbackPings::FromDownload(*download);
160 DCHECK(pings);
161
162 download->StealDangerousDownload(
163 base::Bind(&DownloadFeedbackService::BeginFeedbackOrDeleteFile,
164 file_task_runner_,
165 weak_ptr_factory_.GetWeakPtr(),
166 pings->ping_request(),
167 pings->ping_response()));
168 }
169
170 // static
171 void DownloadFeedbackService::BeginFeedbackOrDeleteFile(
172 const scoped_refptr<base::TaskRunner>& file_task_runner,
173 const base::WeakPtr<DownloadFeedbackService>& service,
174 const std::string& ping_request,
175 const std::string& ping_response,
176 const base::FilePath& path) {
177 if (service) {
178 service->BeginFeedback(ping_request, ping_response, path);
179 } else {
180 base::FileUtilProxy::Delete(file_task_runner, path, false,
181 base::FileUtilProxy::StatusCallback());
182 }
183 }
184
185 void DownloadFeedbackService::StartPendingFeedback() {
186 DCHECK(!active_feedback_.empty());
187 active_feedback_.front()->Start(base::Bind(
188 &DownloadFeedbackService::FeedbackComplete, base::Unretained(this)));
189 }
190
191 void DownloadFeedbackService::BeginFeedback(
192 const std::string& ping_request,
193 const std::string& ping_response,
194 const base::FilePath& path) {
195 DCHECK(CalledOnValidThread());
196 DownloadFeedback* feedback = DownloadFeedback::Create(
197 request_context_getter_, file_task_runner_, path,
198 ping_request, ping_response);
199 active_feedback_.push_back(feedback);
200 UMA_HISTOGRAM_COUNTS_100("SBDownloadFeedback.ActiveFeedbacks",
201 active_feedback_.size());
202
203 if (active_feedback_.size() == 1)
204 StartPendingFeedback();
205 }
206
207 void DownloadFeedbackService::FeedbackComplete() {
208 DVLOG(1) << __FUNCTION__;
209 DCHECK(CalledOnValidThread());
210 DCHECK(!active_feedback_.empty());
211 active_feedback_.erase(active_feedback_.begin());
212 if (!active_feedback_.empty())
213 StartPendingFeedback();
214 }
215
216 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698