blob: 816fa256d9e3d6e712a7cec80751d26e56f4bc3d [file] [log] [blame]
[email protected]1eab4e92014-05-09 02:17:191// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]48372252013-12-20 12:18:012// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]1eab4e92014-05-09 02:17:195#ifndef COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_H_
6#define COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_H_
[email protected]48372252013-12-20 12:18:017
Robbie McElrathd956f862018-07-09 22:01:028#include <list>
[email protected]48372252013-12-20 12:18:019#include <queue>
Ahmed Fakhryaf8ab052017-07-21 21:39:0710#include <vector>
[email protected]48372252013-12-20 12:18:0111
Ahmed Fakhryaf8ab052017-07-21 21:39:0712#include "base/files/file_path.h"
avibc5337b2015-12-25 23:16:3313#include "base/macros.h"
Ahmed Fakhryaf8ab052017-07-21 21:39:0714#include "base/memory/ref_counted.h"
[email protected]48372252013-12-20 12:18:0115#include "base/memory/weak_ptr.h"
Ahmed Fakhryaf8ab052017-07-21 21:39:0716#include "base/single_thread_task_runner.h"
[email protected]48372252013-12-20 12:18:0117#include "base/time/time.h"
18#include "base/timer/timer.h"
Ahmed Fakhry7ff0cdb2017-08-22 20:11:4519#include "components/keyed_service/core/keyed_service.h"
Ahmed Fakhryaf8ab052017-07-21 21:39:0720#include "url/gurl.h"
[email protected]48372252013-12-20 12:18:0121
Ahmed Fakhry7ff0cdb2017-08-22 20:11:4522namespace content {
23class BrowserContext;
24} // namespace content
25
Robbie McElrathd956f862018-07-09 22:01:0226namespace network {
27struct ResourceRequest;
28class SimpleURLLoader;
29class SharedURLLoaderFactory;
30} // namespace network
Ahmed Fakhry7ff0cdb2017-08-22 20:11:4531
[email protected]48372252013-12-20 12:18:0132namespace feedback {
33
[email protected]90cc2a9a2014-02-28 22:05:5534class FeedbackReport;
[email protected]48372252013-12-20 12:18:0135
36// FeedbackUploader is used to add a feedback report to the queue of reports
37// being uploaded. In case uploading a report fails, it is written to disk and
38// tried again when it's turn comes up next in the queue.
Ahmed Fakhry7ff0cdb2017-08-22 20:11:4539class FeedbackUploader : public KeyedService,
40 public base::SupportsWeakPtr<FeedbackUploader> {
[email protected]48372252013-12-20 12:18:0141 public:
Robbie McElrathd956f862018-07-09 22:01:0242 FeedbackUploader(
43 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
44 content::BrowserContext* context,
45 scoped_refptr<base::SingleThreadTaskRunner> task_runner);
Ahmed Fakhry7ff0cdb2017-08-22 20:11:4546 ~FeedbackUploader() override;
[email protected]48372252013-12-20 12:18:0147
Ahmed Fakhryaf8ab052017-07-21 21:39:0748 static void SetMinimumRetryDelayForTesting(base::TimeDelta delay);
[email protected]48372252013-12-20 12:18:0149
Ahmed Fakhryaf8ab052017-07-21 21:39:0750 // Queues a report for uploading.
Ahmed Fakhrydaa7d4232018-07-02 18:11:3651 void QueueReport(std::unique_ptr<std::string> data);
[email protected]77f7fe892014-03-18 00:00:0652
[email protected]1eab4e92014-05-09 02:17:1953 bool QueueEmpty() const { return reports_queue_.empty(); }
54
Ahmed Fakhry7ff0cdb2017-08-22 20:11:4555 content::BrowserContext* context() { return context_; }
56
Ahmed Fakhryaf8ab052017-07-21 21:39:0757 const base::FilePath& feedback_reports_path() const {
58 return feedback_reports_path_;
59 }
60
61 scoped_refptr<base::SingleThreadTaskRunner> task_runner() const {
62 return task_runner_;
63 }
64
65 base::TimeDelta retry_delay() const { return retry_delay_; }
66
[email protected]77f7fe892014-03-18 00:00:0667 protected:
Ahmed Fakhry7ff0cdb2017-08-22 20:11:4568 // Virtual to give implementers a chance to do work before the report is
69 // disptached. Implementers can then call
70 // FeedbackUploader::StartSendingReport() when ready so that the report is
71 // dispatched.
72 virtual void StartDispatchingReport();
73
Ahmed Fakhryaf8ab052017-07-21 21:39:0774 // Invoked when a feedback report upload succeeds. It will reset the
75 // |retry_delay_| to its minimum value and schedules the next report upload if
76 // any.
77 void OnReportUploadSuccess();
78
Ahmed Fakhry7ff0cdb2017-08-22 20:11:4579 // Invoked when |report_being_dispatched_| fails to upload. If |should_retry|
80 // is true, it will double the |retry_delay_| and reenqueue
81 // |report_being_dispatched_| with the new delay. All subsequent retries will
82 // keep increasing the delay until a successful upload is encountered.
83 void OnReportUploadFailure(bool should_retry);
84
85 const scoped_refptr<FeedbackReport>& report_being_dispatched() const {
86 return report_being_dispatched_;
87 }
Ahmed Fakhryaf8ab052017-07-21 21:39:0788
89 private:
[email protected]48372252013-12-20 12:18:0190 friend class FeedbackUploaderTest;
[email protected]1eab4e92014-05-09 02:17:1991
Robbie McElrathd956f862018-07-09 22:01:0292 // This is a std::list so that iterators remain valid during modifications.
93 using UrlLoaderList = std::list<std::unique_ptr<network::SimpleURLLoader>>;
94
[email protected]48372252013-12-20 12:18:0195 struct ReportsUploadTimeComparator {
dcheng972bc39f2014-09-04 04:22:3896 bool operator()(const scoped_refptr<FeedbackReport>& a,
97 const scoped_refptr<FeedbackReport>& b) const;
[email protected]48372252013-12-20 12:18:0198 };
99
Ahmed Fakhry7ff0cdb2017-08-22 20:11:45100 // Called from DispatchReport() to give implementers a chance to add extra
101 // headers to the upload request before it's sent.
Robbie McElrathd956f862018-07-09 22:01:02102 virtual void AppendExtraHeadersToUploadRequest(
103 network::ResourceRequest* resource_request);
Ahmed Fakhry7ff0cdb2017-08-22 20:11:45104
105 // Uploads the |report_being_dispatched_| to be uploaded. It must
106 // call either OnReportUploadSuccess() or OnReportUploadFailure() so that
107 // dispatching reports can progress.
108 void DispatchReport();
[email protected]90cc2a9a2014-02-28 22:05:55109
Robbie McElrathd956f862018-07-09 22:01:02110 void OnDispatchComplete(UrlLoaderList::iterator it,
111 std::unique_ptr<std::string> response_body);
112
[email protected]48372252013-12-20 12:18:01113 // Update our timer for uploading the next report.
114 void UpdateUploadTimer();
115
Ahmed Fakhrydaa7d4232018-07-02 18:11:36116 void QueueReportWithDelay(std::unique_ptr<std::string> data,
117 base::TimeDelta delay);
[email protected]77f7fe892014-03-18 00:00:06118
Robbie McElrathd956f862018-07-09 22:01:02119 // URLLoaderFactory used for network requests.
120 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
121
Ahmed Fakhry7ff0cdb2017-08-22 20:11:45122 // Browser context this uploader was created for.
123 content::BrowserContext* context_;
124
Ahmed Fakhryaf8ab052017-07-21 21:39:07125 const base::FilePath feedback_reports_path_;
[email protected]48372252013-12-20 12:18:01126
[email protected]48372252013-12-20 12:18:01127 // Timer to upload the next report at.
danakj8c3eb802015-09-24 07:53:00128 base::OneShotTimer upload_timer_;
Ahmed Fakhryaf8ab052017-07-21 21:39:07129
130 // See comment of |FeedbackUploaderFactory::task_runner_|.
131 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
132
Ahmed Fakhry7ff0cdb2017-08-22 20:11:45133 scoped_refptr<FeedbackReport> report_being_dispatched_;
134
135 const GURL feedback_post_url_;
136
[email protected]48372252013-12-20 12:18:01137 // Priority queue of reports prioritized by the time the report is supposed
138 // to be uploaded at.
[email protected]90cc2a9a2014-02-28 22:05:55139 std::priority_queue<scoped_refptr<FeedbackReport>,
Ahmed Fakhryaf8ab052017-07-21 21:39:07140 std::vector<scoped_refptr<FeedbackReport>>,
141 ReportsUploadTimeComparator>
142 reports_queue_;
[email protected]48372252013-12-20 12:18:01143
[email protected]48372252013-12-20 12:18:01144 base::TimeDelta retry_delay_;
Ahmed Fakhry7ff0cdb2017-08-22 20:11:45145
146 // True when a report is currently being dispatched. Only a single report
147 // at-a-time should be dispatched.
148 bool is_dispatching_;
[email protected]48372252013-12-20 12:18:01149
Robbie McElrathd956f862018-07-09 22:01:02150 UrlLoaderList uploads_in_progress_;
151
[email protected]48372252013-12-20 12:18:01152 DISALLOW_COPY_AND_ASSIGN(FeedbackUploader);
153};
154
155} // namespace feedback
156
[email protected]1eab4e92014-05-09 02:17:19157#endif // COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_H_