| 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 |