Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / safe_browsing / incident_reporting / incident_reporting_service.h
blob10fb114e3f2b56042222a6a2d68b49580819cc21
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.
5 #ifndef CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_INCIDENT_REPORTING_SERVICE_H_
6 #define CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_INCIDENT_REPORTING_SERVICE_H_
8 #include <stdint.h>
10 #include <map>
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/incident_reporting/add_incident_callback.h"
22 #include "chrome/browser/safe_browsing/incident_reporting/delayed_analysis_callback.h"
23 #include "chrome/browser/safe_browsing/incident_reporting/delayed_callback_runner.h"
24 #include "chrome/browser/safe_browsing/incident_reporting/incident_report_uploader.h"
25 #include "chrome/browser/safe_browsing/incident_reporting/last_download_finder.h"
26 #include "content/public/browser/notification_observer.h"
27 #include "content/public/browser/notification_registrar.h"
29 class Profile;
30 class SafeBrowsingDatabaseManager;
31 class SafeBrowsingService;
32 class TrackedPreferenceValidationDelegate;
34 namespace base {
35 class TaskRunner;
38 namespace content {
39 class NotificationDetails;
40 class NotificationSource;
43 namespace net {
44 class URLRequestContextGetter;
47 namespace safe_browsing {
49 class ClientIncidentReport;
50 class ClientIncidentReport_DownloadDetails;
51 class ClientIncidentReport_EnvironmentData;
52 class ClientIncidentReport_IncidentData;
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);
72 // All incident collection, data collection, and uploads in progress are
73 // dropped at destruction.
74 virtual ~IncidentReportingService();
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);
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);
90 // Registers |callback| to be run after some delay following process launch.
91 void RegisterDelayedAnalysisCallback(const DelayedAnalysisCallback& callback);
93 protected:
94 // A pointer to a function that populates a protobuf with environment data.
95 typedef void (*CollectEnvironmentDataFn)(
96 ClientIncidentReport_EnvironmentData*);
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);
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);
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);
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);
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);
132 // Returns true if a report is currently being processed.
133 bool IsProcessingReport() const;
135 private:
136 struct ProfileContext;
137 class UploadContext;
139 // A mapping of profiles to contexts holding state about received incidents.
140 typedef std::map<Profile*, ProfileContext*> ProfileContextCollection;
142 // Returns the context for |profile|, creating it if it does not exist.
143 ProfileContext* GetOrCreateProfileContext(Profile* profile);
145 // Returns the context for |profile|, or NULL if it is unknown.
146 ProfileContext* GetProfileContext(Profile* profile);
148 // Handles the destruction of a profile. Incidents reported for the profile
149 // but not yet uploaded are dropped.
150 void OnProfileDestroyed(Profile* profile);
152 // Returns an initialized profile that participates in safe browsing. Profiles
153 // participating in extended safe browsing are preferred.
154 Profile* FindEligibleProfile() const;
156 // Adds |incident_data| to the service. The incident_time_msec field is
157 // populated with the current time if the caller has not already done so.
158 void AddIncident(Profile* profile,
159 scoped_ptr<ClientIncidentReport_IncidentData> incident_data);
161 // Begins processing a report. If processing is already underway, ensures that
162 // collection tasks have completed or are running.
163 void BeginReportProcessing();
165 // Begins the process of collating incidents by waiting for incidents to
166 // arrive. This function is idempotent.
167 void BeginIncidentCollation();
169 // Starts a task to collect environment data in the blocking pool.
170 void BeginEnvironmentCollection();
172 // Returns true if the environment collection task is outstanding.
173 bool WaitingForEnvironmentCollection();
175 // Cancels any pending environment collection task and drops any data that has
176 // already been collected.
177 void CancelEnvironmentCollection();
179 // A callback invoked on the UI thread when environment data collection is
180 // complete. Incident report processing continues, either by waiting for the
181 // collection timeout or by sending an incident report.
182 void OnEnvironmentDataCollected(
183 scoped_ptr<ClientIncidentReport_EnvironmentData> environment_data);
185 // Returns true if the service is waiting for additional incidents before
186 // uploading a report.
187 bool WaitingToCollateIncidents();
189 // Cancels the collection timeout.
190 void CancelIncidentCollection();
192 // A callback invoked on the UI thread after which incident collation has
193 // completed. Incident report processing continues, either by waiting for
194 // environment data or the most recent download to arrive or by sending an
195 // incident report.
196 void OnCollationTimeout();
198 // Starts the asynchronous process of finding the most recent executable
199 // download if one is not currently being search for and/or has not already
200 // been found.
201 void BeginDownloadCollection();
203 // True if the service is waiting to discover the most recent download either
204 // because a task to do so is outstanding, or because one or more profiles
205 // have yet to be added to the ProfileManager.
206 bool WaitingForMostRecentDownload();
208 // Cancels the search for the most recent executable download.
209 void CancelDownloadCollection();
211 // A callback invoked on the UI thread by the last download finder when the
212 // search for the most recent binary download is complete.
213 void OnLastDownloadFound(
214 scoped_ptr<ClientIncidentReport_DownloadDetails> last_download);
216 // Uploads an incident report if all data collection is complete. Incidents
217 // originating from profiles that do not participate in safe browsing are
218 // dropped.
219 void UploadIfCollectionComplete();
221 // Cancels all uploads, discarding all reports and responses in progress.
222 void CancelAllReportUploads();
224 // Continues an upload after checking for the CSD whitelist killswitch.
225 void OnKillSwitchResult(UploadContext* context, bool is_killswitch_on);
227 // Performs processing for a report after succesfully receiving a response.
228 void HandleResponse(const UploadContext& context);
230 // IncidentReportUploader::OnResultCallback implementation.
231 void OnReportUploadResult(UploadContext* context,
232 IncidentReportUploader::Result result,
233 scoped_ptr<ClientIncidentResponse> response);
235 // content::NotificationObserver methods.
236 virtual void Observe(int type,
237 const content::NotificationSource& source,
238 const content::NotificationDetails& details) override;
240 base::ThreadChecker thread_checker_;
242 // The safe browsing database manager, through which the whitelist killswitch
243 // is checked.
244 scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
246 // Accessor for an URL context with which reports will be sent.
247 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
249 // A pointer to a function that collects environment data. The function will
250 // be run by |environment_collection_task_runner_|. This is ordinarily
251 // CollectEnvironmentData, but may be overridden by tests; see
252 // SetCollectEnvironmentHook.
253 CollectEnvironmentDataFn collect_environment_data_fn_;
255 // The task runner on which environment collection takes place. This is
256 // ordinarily a runner in the browser's blocking pool that will skip the
257 // collection task at shutdown if it has not yet started.
258 scoped_refptr<base::TaskRunner> environment_collection_task_runner_;
260 // Registrar for observing profile lifecycle notifications.
261 content::NotificationRegistrar notification_registrar_;
263 // True when the asynchronous environment collection task has been fired off
264 // but has not yet completed.
265 bool environment_collection_pending_;
267 // True when an incident has been received and the service is waiting for the
268 // collation_timer_ to fire.
269 bool collation_timeout_pending_;
271 // A timer upon the firing of which the service will report received
272 // incidents.
273 base::DelayTimer<IncidentReportingService> collation_timer_;
275 // The report currently being assembled. This becomes non-NULL when an initial
276 // incident is reported, and returns to NULL when the report is sent for
277 // upload.
278 scoped_ptr<ClientIncidentReport> report_;
280 // The time at which the initial incident is reported.
281 base::Time first_incident_time_;
283 // The time at which the last incident is reported.
284 base::TimeTicks last_incident_time_;
286 // The time at which environmental data collection was initiated.
287 base::TimeTicks environment_collection_begin_;
289 // The time at which download collection was initiated.
290 base::TimeTicks last_download_begin_;
292 // Context data for all on-the-record profiles plus the process-wide (NULL)
293 // context.
294 ProfileContextCollection profiles_;
296 // Callbacks registered for performing delayed analysis.
297 DelayedCallbackRunner delayed_analysis_callbacks_;
299 // The collection of uploads in progress.
300 ScopedVector<UploadContext> uploads_;
302 // An object that asynchronously searches for the most recent binary download.
303 // Non-NULL while such a search is outstanding.
304 scoped_ptr<LastDownloadFinder> last_download_finder_;
306 // A factory for handing out weak pointers for AddIncident callbacks.
307 base::WeakPtrFactory<IncidentReportingService> receiver_weak_ptr_factory_;
309 // A factory for handing out weak pointers for internal asynchronous tasks
310 // that are posted during normal processing (e.g., environment collection,
311 // safe browsing database checks, and report uploads).
312 base::WeakPtrFactory<IncidentReportingService> weak_ptr_factory_;
314 DISALLOW_COPY_AND_ASSIGN(IncidentReportingService);
317 } // namespace safe_browsing
319 #endif // CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_INCIDENT_REPORTING_SERVICE_H_