OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 #ifndef CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_SERVICE_H_ | |
6 #define CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_SERVICE_H_ | |
7 | |
8 #include <stdint.h> | |
9 | |
10 #include <map> | |
11 | |
12 #include "base/compiler_specific.h" | |
13 #include "base/macros.h" | |
14 #include "base/memory/ref_counted.h" | |
15 #include "base/memory/scoped_ptr.h" | |
16 #include "base/memory/scoped_vector.h" | |
17 #include "base/memory/weak_ptr.h" | |
18 #include "base/threading/thread_checker.h" | |
19 #include "base/time/time.h" | |
20 #include "base/timer/timer.h" | |
21 #include "chrome/browser/safe_browsing/add_incident_callback.h" | |
22 #include "chrome/browser/safe_browsing/delayed_analysis_callback.h" | |
23 #include "chrome/browser/safe_browsing/delayed_callback_runner.h" | |
24 #include "chrome/browser/safe_browsing/incident_report_uploader.h" | |
25 #include "chrome/browser/safe_browsing/last_download_finder.h" | |
26 #include "content/public/browser/notification_observer.h" | |
27 #include "content/public/browser/notification_registrar.h" | |
28 | |
29 class Profile; | |
30 class SafeBrowsingDatabaseManager; | |
31 class SafeBrowsingService; | |
32 class TrackedPreferenceValidationDelegate; | |
33 | |
34 namespace base { | |
35 class TaskRunner; | |
36 } | |
37 | |
38 namespace content { | |
39 class NotificationDetails; | |
40 class NotificationSource; | |
41 } | |
42 | |
43 namespace net { | |
44 class URLRequestContextGetter; | |
45 } | |
46 | |
47 namespace safe_browsing { | |
48 | |
49 class ClientIncidentReport; | |
50 class ClientIncidentReport_DownloadDetails; | |
51 class ClientIncidentReport_EnvironmentData; | |
52 class ClientIncidentReport_IncidentData; | |
53 | |
54 // A class that manages the collection of incidents and submission of incident | |
55 // reports to the safe browsing client-side detection service. The service | |
56 // begins operation when an incident is reported via the AddIncident method. | |
57 // Incidents reported from a profile that is loading are held until the profile | |
58 // is fully created. Incidents originating from profiles that do not participate | |
59 // in safe browsing are dropped. Process-wide incidents are affiliated with a | |
60 // profile that participates in safe browsing when one becomes available. | |
61 // Following the addition of an incident that is not dropped, the service | |
62 // collects environmental data, finds the most recent binary download, and waits | |
63 // a bit. Additional incidents that arrive during this time are collated with | |
64 // the initial incident. Finally, already-reported incidents are pruned and any | |
65 // remaining are uploaded in an incident report. | |
66 class IncidentReportingService : public content::NotificationObserver { | |
67 public: | |
68 IncidentReportingService(SafeBrowsingService* safe_browsing_service, | |
69 const scoped_refptr<net::URLRequestContextGetter>& | |
70 request_context_getter); | |
71 | |
72 // All incident collection, data collection, and uploads in progress are | |
73 // dropped at destruction. | |
74 virtual ~IncidentReportingService(); | |
75 | |
76 // Returns a callback by which external components can add an incident to the | |
77 // service on behalf of |profile|. The callback may outlive the service, but | |
78 // will no longer have any effect after the service is deleted. The callback | |
79 // must not be run after |profile| has been destroyed. | |
80 AddIncidentCallback GetAddIncidentCallback(Profile* profile); | |
81 | |
82 // Returns a preference validation delegate that adds incidents to the service | |
83 // for validation failures in |profile|. The delegate may outlive the service, | |
84 // but incidents reported by it will no longer have any effect after the | |
85 // service is deleted. The lifetime of the delegate should not extend beyond | |
86 // that of the profile it services. | |
87 scoped_ptr<TrackedPreferenceValidationDelegate> | |
88 CreatePreferenceValidationDelegate(Profile* profile); | |
89 | |
90 // Registers |callback| to be run after some delay following process launch. | |
91 void RegisterDelayedAnalysisCallback(const DelayedAnalysisCallback& callback); | |
92 | |
93 protected: | |
94 // A pointer to a function that populates a protobuf with environment data. | |
95 typedef void (*CollectEnvironmentDataFn)( | |
96 ClientIncidentReport_EnvironmentData*); | |
97 | |
98 // For testing so that the TaskRunner used for delayed analysis callbacks can | |
99 // be specified. | |
100 IncidentReportingService( | |
101 SafeBrowsingService* safe_browsing_service, | |
102 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, | |
103 base::TimeDelta delayed_task_interval, | |
104 const scoped_refptr<base::TaskRunner>& delayed_task_runner); | |
105 | |
106 // Sets the function called by the service to collect environment data and the | |
107 // task runner on which it is called. Used by unit tests to provide a fake | |
108 // environment data collector. | |
109 void SetCollectEnvironmentHook( | |
110 CollectEnvironmentDataFn collect_environment_data_hook, | |
111 const scoped_refptr<base::TaskRunner>& task_runner); | |
112 | |
113 // Handles the addition of a new profile to the ProfileManager. Creates a new | |
114 // context for |profile| if one does not exist, drops any received incidents | |
115 // for the profile if the profile is not participating in safe browsing, and | |
116 // initiates a new search for the most recent download if a report is being | |
117 // assembled and the most recent has not been found. Overridden by unit tests | |
118 // to inject incidents prior to creation. | |
119 virtual void OnProfileAdded(Profile* profile); | |
120 | |
121 // Initiates a search for the most recent binary download. Overriden by unit | |
122 // tests to provide a fake finder. | |
123 virtual scoped_ptr<LastDownloadFinder> CreateDownloadFinder( | |
124 const LastDownloadFinder::LastDownloadCallback& callback); | |
125 | |
126 // Initiates an upload. Overridden by unit tests to provide a fake uploader. | |
127 virtual scoped_ptr<IncidentReportUploader> StartReportUpload( | |
128 const IncidentReportUploader::OnResultCallback& callback, | |
129 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, | |
130 const ClientIncidentReport& report); | |
131 | |
132 private: | |
133 struct ProfileContext; | |
134 class UploadContext; | |
135 | |
136 // A mapping of profiles to contexts holding state about received incidents. | |
137 typedef std::map<Profile*, ProfileContext*> ProfileContextCollection; | |
138 | |
139 // Returns the context for |profile|, creating it if it does not exist. | |
140 ProfileContext* GetOrCreateProfileContext(Profile* profile); | |
141 | |
142 // Returns the context for |profile|, or NULL if it is unknown. | |
143 ProfileContext* GetProfileContext(Profile* profile); | |
144 | |
145 // Handles the destruction of a profile. Incidents reported for the profile | |
146 // but not yet uploaded are dropped. | |
147 void OnProfileDestroyed(Profile* profile); | |
148 | |
149 // Returns an initialized profile that participates in safe browsing. Profiles | |
150 // participating in extended safe browsing are preferred. | |
151 Profile* FindEligibleProfile() const; | |
152 | |
153 // Adds |incident_data| to the service. The incident_time_msec field is | |
154 // populated with the current time if the caller has not already done so. | |
155 void AddIncident(Profile* profile, | |
156 scoped_ptr<ClientIncidentReport_IncidentData> incident_data); | |
157 | |
158 // Begins processing a report. If processing is already underway, ensures that | |
159 // collection tasks have completed or are running. | |
160 void BeginReportProcessing(); | |
161 | |
162 // Begins the process of collating incidents by waiting for incidents to | |
163 // arrive. This function is idempotent. | |
164 void BeginIncidentCollation(); | |
165 | |
166 // Starts a task to collect environment data in the blocking pool. | |
167 void BeginEnvironmentCollection(); | |
168 | |
169 // Returns true if the environment collection task is outstanding. | |
170 bool WaitingForEnvironmentCollection(); | |
171 | |
172 // Cancels any pending environment collection task and drops any data that has | |
173 // already been collected. | |
174 void CancelEnvironmentCollection(); | |
175 | |
176 // A callback invoked on the UI thread when environment data collection is | |
177 // complete. Incident report processing continues, either by waiting for the | |
178 // collection timeout or by sending an incident report. | |
179 void OnEnvironmentDataCollected( | |
180 scoped_ptr<ClientIncidentReport_EnvironmentData> environment_data); | |
181 | |
182 // Returns true if the service is waiting for additional incidents before | |
183 // uploading a report. | |
184 bool WaitingToCollateIncidents(); | |
185 | |
186 // Cancels the collection timeout. | |
187 void CancelIncidentCollection(); | |
188 | |
189 // A callback invoked on the UI thread after which incident collation has | |
190 // completed. Incident report processing continues, either by waiting for | |
191 // environment data or the most recent download to arrive or by sending an | |
192 // incident report. | |
193 void OnCollationTimeout(); | |
194 | |
195 // Starts the asynchronous process of finding the most recent executable | |
196 // download if one is not currently being search for and/or has not already | |
197 // been found. | |
198 void BeginDownloadCollection(); | |
199 | |
200 // True if the service is waiting to discover the most recent download either | |
201 // because a task to do so is outstanding, or because one or more profiles | |
202 // have yet to be added to the ProfileManager. | |
203 bool WaitingForMostRecentDownload(); | |
204 | |
205 // Cancels the search for the most recent executable download. | |
206 void CancelDownloadCollection(); | |
207 | |
208 // A callback invoked on the UI thread by the last download finder when the | |
209 // search for the most recent binary download is complete. | |
210 void OnLastDownloadFound( | |
211 scoped_ptr<ClientIncidentReport_DownloadDetails> last_download); | |
212 | |
213 // Uploads an incident report if all data collection is complete. Incidents | |
214 // originating from profiles that do not participate in safe browsing are | |
215 // dropped. | |
216 void UploadIfCollectionComplete(); | |
217 | |
218 // Cancels all uploads, discarding all reports and responses in progress. | |
219 void CancelAllReportUploads(); | |
220 | |
221 // Continues an upload after checking for the CSD whitelist killswitch. | |
222 void OnKillSwitchResult(UploadContext* context, bool is_killswitch_on); | |
223 | |
224 // Performs processing for a report after succesfully receiving a response. | |
225 void HandleResponse(const UploadContext& context); | |
226 | |
227 // IncidentReportUploader::OnResultCallback implementation. | |
228 void OnReportUploadResult(UploadContext* context, | |
229 IncidentReportUploader::Result result, | |
230 scoped_ptr<ClientIncidentResponse> response); | |
231 | |
232 // content::NotificationObserver methods. | |
233 virtual void Observe(int type, | |
234 const content::NotificationSource& source, | |
235 const content::NotificationDetails& details) OVERRIDE; | |
236 | |
237 base::ThreadChecker thread_checker_; | |
238 | |
239 // The safe browsing database manager, through which the whitelist killswitch | |
240 // is checked. | |
241 scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; | |
242 | |
243 // Accessor for an URL context with which reports will be sent. | |
244 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; | |
245 | |
246 // A pointer to a function that collects environment data. The function will | |
247 // be run by |environment_collection_task_runner_|. This is ordinarily | |
248 // CollectEnvironmentData, but may be overridden by tests; see | |
249 // SetCollectEnvironmentHook. | |
250 CollectEnvironmentDataFn collect_environment_data_fn_; | |
251 | |
252 // The task runner on which environment collection takes place. This is | |
253 // ordinarily a runner in the browser's blocking pool that will skip the | |
254 // collection task at shutdown if it has not yet started. | |
255 scoped_refptr<base::TaskRunner> environment_collection_task_runner_; | |
256 | |
257 // Registrar for observing profile lifecycle notifications. | |
258 content::NotificationRegistrar notification_registrar_; | |
259 | |
260 // True when the asynchronous environment collection task has been fired off | |
261 // but has not yet completed. | |
262 bool environment_collection_pending_; | |
263 | |
264 // True when an incident has been received and the service is waiting for the | |
265 // collation_timer_ to fire. | |
266 bool collation_timeout_pending_; | |
267 | |
268 // A timer upon the firing of which the service will report received | |
269 // incidents. | |
270 base::DelayTimer<IncidentReportingService> collation_timer_; | |
271 | |
272 // The report currently being assembled. This becomes non-NULL when an initial | |
273 // incident is reported, and returns to NULL when the report is sent for | |
274 // upload. | |
275 scoped_ptr<ClientIncidentReport> report_; | |
276 | |
277 // The time at which the initial incident is reported. | |
278 base::Time first_incident_time_; | |
279 | |
280 // The time at which the last incident is reported. | |
281 base::TimeTicks last_incident_time_; | |
282 | |
283 // The time at which environmental data collection was initiated. | |
284 base::TimeTicks environment_collection_begin_; | |
285 | |
286 // The time at which download collection was initiated. | |
287 base::TimeTicks last_download_begin_; | |
288 | |
289 // Context data for all on-the-record profiles plus the process-wide (NULL) | |
290 // context. | |
291 ProfileContextCollection profiles_; | |
292 | |
293 // Callbacks registered for performing delayed analysis. | |
294 DelayedCallbackRunner delayed_analysis_callbacks_; | |
295 | |
296 // The collection of uploads in progress. | |
297 ScopedVector<UploadContext> uploads_; | |
298 | |
299 // An object that asynchronously searches for the most recent binary download. | |
300 // Non-NULL while such a search is outstanding. | |
301 scoped_ptr<LastDownloadFinder> last_download_finder_; | |
302 | |
303 // A factory for handing out weak pointers for AddIncident callbacks. | |
304 base::WeakPtrFactory<IncidentReportingService> receiver_weak_ptr_factory_; | |
305 | |
306 // A factory for handing out weak pointers for internal asynchronous tasks | |
307 // that are posted during normal processing (e.g., environment collection, | |
308 // safe browsing database checks, and report uploads). | |
309 base::WeakPtrFactory<IncidentReportingService> weak_ptr_factory_; | |
310 | |
311 DISALLOW_COPY_AND_ASSIGN(IncidentReportingService); | |
312 }; | |
313 | |
314 } // namespace safe_browsing | |
315 | |
316 #endif // CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_SERVICE_H_ | |
OLD | NEW |