net_export_file_writer.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. // Copyright (c) 2013 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. #ifndef COMPONENTS_NET_LOG_NET_EXPORT_FILE_WRITER_H_
  5. #define COMPONENTS_NET_LOG_NET_EXPORT_FILE_WRITER_H_
  6. #include <memory>
  7. #include <string>
  8. #include "base/callback.h"
  9. #include "base/command_line.h"
  10. #include "base/files/file.h"
  11. #include "base/files/file_path.h"
  12. #include "base/gtest_prod_util.h"
  13. #include "base/memory/ref_counted.h"
  14. #include "base/memory/weak_ptr.h"
  15. #include "base/observer_list.h"
  16. #include "base/threading/thread_checker.h"
  17. #include "base/values.h"
  18. #include "mojo/public/cpp/bindings/remote.h"
  19. #include "net/log/net_log_capture_mode.h"
  20. #include "services/network/public/mojom/net_log.mojom.h"
  21. #include "services/network/public/mojom/network_service.mojom.h"
  22. namespace base {
  23. class TaskRunner;
  24. } // namespace base
  25. namespace network {
  26. namespace mojom {
  27. class NetworkContext;
  28. }
  29. } // namespace network
  30. namespace net_log {
  31. // NetExportFileWriter is used exclusively as a support class for
  32. // chrome://net-export/. There's a single instance created globally that acts as
  33. // the interface to all NetExportMessageHandlers which can tell it to start or
  34. // stop logging in response to user actions from chrome://net-export/ UIs.
  35. // Because there's only one instance, the logging state can be shared between
  36. // multiple instances of the chrome://net-export/ UI. Internally, it manages a
  37. // pipe to an instance of network::NetLogExporter and handles the
  38. // attaching/detaching of it to the NetLog. This class is used by the iOS and
  39. // non-iOS implementations of chrome://net-export/.
  40. //
  41. // NetExportFileWriter maintains the current logging state using the members
  42. // |state_|, |log_exists_|, |log_capture_mode_known_|, |log_capture_mode_|.
  43. // Its three main commands are Initialize(), StartNetLog(), and StopNetLog().
  44. // These are the only functions that may cause NetExportFileWriter to change
  45. // state. Initialize() must be called before NetExportFileWriter can process any
  46. // other commands. A portion of the initialization needs to run on the
  47. // |file_task_runner_|.
  48. //
  49. // This class is created and destroyed on the UI thread, and all public entry
  50. // points are to be called on the UI thread. Internally, the class may run some
  51. // code on the |file_task_runner_|.
  52. class NetExportFileWriter {
  53. public:
  54. // Special value meaning "can use an unlimited number of bytes".
  55. static constexpr uint64_t kNoLimit =
  56. network::mojom::NetLogExporter::kUnlimitedFileSize;
  57. // The observer interface to be implemented by code that wishes to be notified
  58. // of NetExportFileWriter's state changes.
  59. class StateObserver {
  60. public:
  61. virtual void OnNewState(const base::Value::Dict& state) = 0;
  62. };
  63. // Struct used to store the results of setting up the default log directory
  64. // and log path.
  65. struct DefaultLogPathResults {
  66. bool default_log_path_success;
  67. base::FilePath default_log_path;
  68. bool log_exists;
  69. };
  70. using FilePathCallback = base::OnceCallback<void(const base::FilePath&)>;
  71. using DirectoryGetter = base::RepeatingCallback<bool(base::FilePath*)>;
  72. // Constructs a NetExportFileWriter. Only one instance is created in browser
  73. // process.
  74. NetExportFileWriter();
  75. NetExportFileWriter(const NetExportFileWriter&) = delete;
  76. NetExportFileWriter& operator=(const NetExportFileWriter&) = delete;
  77. ~NetExportFileWriter();
  78. // Attaches a StateObserver. |observer| will be notified of state changes to
  79. // NetExportFileWriter. State changes may occur in response to Initiailze(),
  80. // StartNetLog(), or StopNetLog(). StateObserver::OnNewState() will be called
  81. // asynchronously relative to the command that caused the state change.
  82. // |observer| must remain alive until RemoveObserver() is called.
  83. void AddObserver(StateObserver* observer);
  84. // Detaches a StateObserver.
  85. void RemoveObserver(StateObserver* observer);
  86. // Initializes NetExportFileWriter if not initialized. Calling this function
  87. // again is OK.
  88. void Initialize();
  89. // Starts collecting NetLog data into the file at |log_path|. If |log_path| is
  90. // empty, the default log path is used. If NetExportFileWriter is already
  91. // logging, this is a no-op and |capture_mode| is ignored.
  92. //
  93. // |max_file_size| places a bound on how large the log file can grow. To make
  94. // it grow unboundedly pass kNoLimit.
  95. //
  96. // |network_context| will be used to append net info (from net::GetInfo())
  97. // at end of logging once StopNetLog is called.
  98. void StartNetLog(const base::FilePath& log_path,
  99. net::NetLogCaptureMode capture_mode,
  100. uint64_t max_file_size,
  101. const base::CommandLine::StringType& command_line_string,
  102. const std::string& channel_string,
  103. network::mojom::NetworkContext* network_context);
  104. // Stops collecting NetLog data into the file. It is a no-op if
  105. // NetExportFileWriter is currently not logging.
  106. //
  107. // |polled_data| is a JSON dictionary that will be appended to the end of the
  108. // log; it's for adding additional info to the log that aren't events.
  109. void StopNetLog(base::Value::Dict polled_data = base::Value::Dict());
  110. // Creates a DictionaryValue summary of the state of the NetExportFileWriter
  111. base::Value::Dict GetState() const;
  112. // Gets the log filepath. |path_callback| will be used to notify the caller
  113. // when the filepath is retrieved. |path_callback| will be executed with an
  114. // empty filepath if any of the following occurs:
  115. // (1) The NetExportFileWriter is not initialized.
  116. // (2) The log file does not exist.
  117. // (3) The NetExportFileWriter is currently logging.
  118. //
  119. // |path_callback| will be executed at the end of GetFilePathToCompletedLog()
  120. // asynchronously.
  121. void GetFilePathToCompletedLog(FilePathCallback path_callback) const;
  122. // Converts to/from the string representation of a capture mode used by
  123. // net_export.js.
  124. static std::string CaptureModeToString(net::NetLogCaptureMode capture_mode);
  125. static net::NetLogCaptureMode CaptureModeFromString(
  126. const std::string& capture_mode_string);
  127. // Overrides the getter used to retrieve the default log base directory during
  128. // initialization. Should only be used by unit tests.
  129. void SetDefaultLogBaseDirectoryGetterForTest(const DirectoryGetter& getter);
  130. private:
  131. friend class NetExportFileWriterTest;
  132. // The possible logging states of NetExportFileWriter.
  133. enum State {
  134. STATE_UNINITIALIZED,
  135. // Currently in the process of initializing.
  136. STATE_INITIALIZING,
  137. // Not currently logging to file.
  138. STATE_NOT_LOGGING,
  139. // Currently in the process of starting the log.
  140. STATE_STARTING_LOG,
  141. // Currently logging to file.
  142. STATE_LOGGING,
  143. // Currently in the process of stopping the log.
  144. STATE_STOPPING_LOG,
  145. };
  146. void NotifyStateObservers();
  147. // Posts NotifyStateObservers() to the current thread.
  148. void NotifyStateObserversAsync();
  149. // Called internally by Initialize(). Will initialize NetExportFileWriter's
  150. // state variables after the default log directory is set up and the default
  151. // log path is determined on the |file_task_runner_|.
  152. void SetStateAfterSetUpDefaultLogPath(
  153. const DefaultLogPathResults& set_up_default_log_path_results);
  154. // Called internally by StartNetLog(). Contains tasks to be done to start
  155. // logging after the output file has been created.
  156. void StartNetLogAfterCreateFile(net::NetLogCaptureMode capture_mode,
  157. uint64_t max_file_size,
  158. base::Value::Dict custom_constants,
  159. base::File log_file);
  160. void OnStartResult(net::NetLogCaptureMode capture_mode, int result);
  161. void OnStopResult(int result);
  162. void OnConnectionError();
  163. // Contains tasks to be done after |net_log_exporter_| has completely
  164. // stopped writing.
  165. void ResetExporterThenSetStateNotLogging();
  166. // Creates a new file for writing at |path|, trying to overwrite any existing
  167. // file. Called on |file_task_runner_|.
  168. static base::File CreateOutputFile(base::FilePath path);
  169. // All members are accessed solely from the main thread (the thread that
  170. // |thread_checker_| is bound to).
  171. base::ThreadChecker thread_checker_;
  172. // Task runners for file-specific and net-specific tasks that must run on a
  173. // file or net task runner.
  174. scoped_refptr<base::TaskRunner> file_task_runner_;
  175. State state_; // Current logging state of NetExportFileWriter.
  176. bool log_exists_; // Whether or not a log file exists on disk.
  177. bool log_capture_mode_known_;
  178. net::NetLogCaptureMode log_capture_mode_;
  179. base::FilePath log_path_; // base::FilePath to the NetLog file.
  180. // Used to ask the network service to do the actual exporting.
  181. mojo::Remote<network::mojom::NetLogExporter> net_log_exporter_;
  182. // List of StateObservers to notify on state changes.
  183. base::ObserverList<StateObserver, true>::Unchecked state_observer_list_;
  184. // Used by unit tests to override the default log base directory retrieved
  185. // during initialization. This getter is initialized to base::GetTempDir().
  186. DirectoryGetter default_log_base_dir_getter_;
  187. base::WeakPtrFactory<NetExportFileWriter> weak_ptr_factory_{this};
  188. };
  189. } // namespace net_log
  190. #endif // COMPONENTS_NET_LOG_NET_EXPORT_FILE_WRITER_H_