1 // Copyright 2018 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_MEDIA_WEBRTC_WEBRTC_EVENT_LOG_UPLOADER_H_
6 #define CHROME_BROWSER_MEDIA_WEBRTC_WEBRTC_EVENT_LOG_UPLOADER_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "base/files/file_path.h"
12 #include "base/memory/scoped_refptr.h"
13 #include "base/sequenced_task_runner.h"
14 #include "chrome/browser/media/webrtc/webrtc_event_log_history.h"
15 #include "chrome/browser/media/webrtc/webrtc_event_log_manager_common.h"
16 #include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
17 
18 namespace network {
19 class SimpleURLLoader;
20 }  // namespace network
21 
22 namespace webrtc_event_logging {
23 
24 // A sublcass of this interface will take ownership of a file, and either
25 // upload it to a remote server (actual implementation), or pretend to do so
26 // (in unit tests). Upon completion, success/failure will be reported by posting
27 // an UploadResultCallback task to the task queue on which this object lives.
28 class WebRtcEventLogUploader {
29  public:
30   using UploadResultCallback =
31       base::OnceCallback<void(const base::FilePath& log_file,
32                               bool upload_successful)>;
33 
34   // Since we'll need more than one instance of the abstract
35   // WebRtcEventLogUploader, we'll need an abstract factory for it.
36   class Factory {
37    public:
38     virtual ~Factory() = default;
39 
40     // Creates uploaders.
41     // This takes ownership of the file. The caller must not attempt to access
42     // the file after invoking Create(). Even deleting the file due to
43     // the user clearing cache, is to be done through the uploader's Cancel,
44     // and not through direct access of the caller to the file. The file may
45     // be touched again only after |this| is destroyed.
46     virtual std::unique_ptr<WebRtcEventLogUploader> Create(
47         const WebRtcLogFileInfo& log_file,
48         UploadResultCallback callback) = 0;
49   };
50 
51   virtual ~WebRtcEventLogUploader() = default;
52 
53   // Getter for the details of the file this uploader is handling.
54   // Can be called for ongoing, completed, failed or cancelled uploads.
55   virtual const WebRtcLogFileInfo& GetWebRtcLogFileInfo() const = 0;
56 
57   // Cancels the upload, then deletes the log file and its history file.
58   // (These files are deleted even if the upload has been completed by the time
59   // Cancel is called.)
60   virtual void Cancel() = 0;
61 };
62 
63 // Primary implementation of WebRtcEventLogUploader. Uploads log files to crash.
64 // Deletes log files whether they were successfully uploaded or not.
65 class WebRtcEventLogUploaderImpl : public WebRtcEventLogUploader {
66  public:
67   class Factory : public WebRtcEventLogUploader::Factory {
68    public:
69     explicit Factory(scoped_refptr<base::SequencedTaskRunner> task_runner);
70 
71     ~Factory() override;
72 
73     std::unique_ptr<WebRtcEventLogUploader> Create(
74         const WebRtcLogFileInfo& log_file,
75         UploadResultCallback callback) override;
76 
77    protected:
78     friend class WebRtcEventLogUploaderImplTest;
79 
80     std::unique_ptr<WebRtcEventLogUploader> CreateWithCustomMaxSizeForTesting(
81         const WebRtcLogFileInfo& log_file,
82         UploadResultCallback callback,
83         size_t max_remote_log_file_size_bytes);
84 
85    private:
86     scoped_refptr<base::SequencedTaskRunner> task_runner_;
87   };
88 
89   WebRtcEventLogUploaderImpl(
90       scoped_refptr<base::SequencedTaskRunner> task_runner,
91       const WebRtcLogFileInfo& log_file,
92       UploadResultCallback callback,
93       size_t max_remote_log_file_size_bytes);
94   ~WebRtcEventLogUploaderImpl() override;
95 
96   const WebRtcLogFileInfo& GetWebRtcLogFileInfo() const override;
97 
98   void Cancel() override;
99 
100  private:
101   friend class WebRtcEventLogUploaderImplTest;
102 
103   // Primes the log file for uploading. Returns true if the file could be read,
104   // in which case |upload_data| will be populated with the data to be uploaded
105   // (both the log file's contents as well as history for Crash).
106   // TODO(crbug.com/775415): Avoid reading the entire file into memory.
107   bool PrepareUploadData(std::string* upload_data);
108 
109   // Initiates the file's upload.
110   void StartUpload(const std::string& upload_data);
111 
112   // Callback invoked when the file upload has finished.
113   // If the |url_loader_| instance it was bound to is deleted before
114   // its invocation, the callback will not be called.
115   void OnURLLoadComplete(std::unique_ptr<std::string> response_body);
116 
117   // Cleanup and posting of the result callback.
118   void ReportResult(bool upload_successful, bool delete_history_file = false);
119 
120   // Remove the log file which is owned by |this|.
121   void DeleteLogFile();
122 
123   // Remove the log file which is owned by |this|.
124   void DeleteHistoryFile();
125 
126   // The URL used for uploading the logs.
127   static const char kUploadURL[];
128 
129   // The object lives on this IO-capable task runner.
130   scoped_refptr<base::SequencedTaskRunner> task_runner_;
131 
132   // Housekeeping information about the uploaded file (path, time of last
133   // modification, associated BrowserContext).
134   const WebRtcLogFileInfo log_file_;
135 
136   // Callback posted back to signal success or failure.
137   UploadResultCallback callback_;
138 
139   // Maximum allowed file size. In production code, this is a hard-coded,
140   // but unit tests may set other values.
141   const size_t max_log_file_size_bytes_;
142 
143   // Owns a history file which allows the state of the uploaded log to be
144   // remembered after it has been uploaded and/or deleted.
145   std::unique_ptr<WebRtcEventLogHistoryFileWriter> history_file_writer_;
146 
147   // This object is in charge of the actual upload.
148   std::unique_ptr<network::SimpleURLLoader> url_loader_;
149 
150   // Allows releasing |this| while a task from |url_loader_| is still pending.
151   base::WeakPtrFactory<WebRtcEventLogUploaderImpl> weak_ptr_factory_{this};
152 };
153 
154 }  // namespace webrtc_event_logging
155 
156 #endif  // CHROME_BROWSER_MEDIA_WEBRTC_WEBRTC_EVENT_LOG_UPLOADER_H_
157