ash_tracing_request.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // Copyright 2021 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 ASH_HUD_DISPLAY_ASH_TRACING_REQUEST_H_
  5. #define ASH_HUD_DISPLAY_ASH_TRACING_REQUEST_H_
  6. #include <sys/stat.h>
  7. #include <memory>
  8. #include "base/callback_forward.h"
  9. #include "base/files/file.h"
  10. #include "base/files/file_path.h"
  11. #include "base/files/platform_file.h"
  12. #include "base/memory/weak_ptr.h"
  13. #include "base/sequence_checker.h"
  14. #include "base/time/time.h"
  15. #include "ash/ash_export.h"
  16. namespace ash {
  17. namespace hud_display {
  18. class AshTracingManager;
  19. class AshTracingHandler;
  20. // This is needed for testing to override File IO.
  21. class ASH_EXPORT AshTraceDestinationIO {
  22. public:
  23. virtual ~AshTraceDestinationIO();
  24. // Overrides base::CreateDirectory.
  25. virtual bool CreateDirectory(const base::FilePath& path) = 0;
  26. // Overrides base::File::File(). Returns pair {File file, bool success}.
  27. // Test implementation may return success with invalid file.
  28. virtual std::tuple<base::File, bool> CreateTracingFile(
  29. const base::FilePath& path) = 0;
  30. // Implements memfd_create(2). Returns pair {int fd, bool success}.
  31. // Test implementation may return success with invalid fd.
  32. virtual std::tuple<base::PlatformFile, bool> CreateMemFD(
  33. const char* name,
  34. unsigned int flags) = 0;
  35. // Takes GetPlatformFile() from AshTraceDestination and returns true if
  36. // given fd is valid for storing traces. Checks for -1 in regular case,
  37. // and checks internal status in tests.
  38. virtual bool CanWriteFile(base::PlatformFile fd) = 0;
  39. virtual int fstat(base::PlatformFile fd, struct stat* statbuf) = 0;
  40. virtual ssize_t sendfile(base::PlatformFile out_fd,
  41. base::PlatformFile in_fd,
  42. off_t* offset,
  43. size_t size) = 0;
  44. };
  45. class ASH_EXPORT AshTraceDestination {
  46. public:
  47. AshTraceDestination();
  48. AshTraceDestination(std::unique_ptr<AshTraceDestinationIO> io,
  49. const base::FilePath& path,
  50. base::File&& file,
  51. base::PlatformFile memfd);
  52. AshTraceDestination(const AshTraceDestination&) = delete;
  53. AshTraceDestination& operator=(const AshTraceDestination&) = delete;
  54. ~AshTraceDestination();
  55. const base::FilePath& path() const { return path_; }
  56. // Returns PlatformFile for storing trace.
  57. // Can be memfd or file depending on the setup.
  58. base::PlatformFile GetPlatformFile() const;
  59. // Reurns true if GetPlatformFile() will return valid file descriptor.
  60. // In tests when test IO layer is used returns true if test IO layer will
  61. // succeed saving file.
  62. bool CanWriteFile() const;
  63. // Close all files.
  64. void Done();
  65. AshTraceDestinationIO* io() const { return io_.get(); }
  66. private:
  67. std::unique_ptr<AshTraceDestinationIO> io_;
  68. base::FilePath path_;
  69. base::File file_;
  70. base::PlatformFile memfd_ = base::kInvalidPlatformFile;
  71. };
  72. class AshTracingRequest {
  73. public:
  74. enum class Status {
  75. kEmpty, // Object created.
  76. kInitialized, // File data is initialized
  77. kStarted, // Tracing is in progress.
  78. kStopping, // Tracing is being stopped.
  79. kPendingMount, // Tracing is complete, waiting for home directory mount.
  80. kWritingFile, // Writing trace file from memory to file after user login.
  81. kCompleted, // Trace file is written. Object has valid path.
  82. };
  83. // Will start tracing (asynchronously).
  84. explicit AshTracingRequest(AshTracingManager* tracing_manager);
  85. AshTracingRequest(const AshTracingRequest&) = delete;
  86. AshTracingRequest& operator=(const AshTracingRequest&) = delete;
  87. ~AshTracingRequest();
  88. void Stop();
  89. // Receive notifications from AshTracingHandler.
  90. void OnTracingStarted();
  91. void OnTracingFinished();
  92. // Will trigger trace file write if needed.
  93. void OnUserLoggedIn();
  94. // Returns file descriptor that will actually be used for tracing.
  95. base::PlatformFile GetPlatformFile() const;
  96. Status status() const { return status_; }
  97. const std::string& error_message() const { return error_message_; }
  98. // Tests generate specific fake IO.
  99. static ASH_EXPORT void SetAshTraceDestinationIOCreatorForTesting(
  100. std::unique_ptr<AshTraceDestinationIO> (*creator)(void));
  101. static ASH_EXPORT void ResetAshTraceDestinationIOCreatorForTesting();
  102. // Tests explicitly check AshTraceDestination behavior and they need to
  103. // be able to generate ThreadPool tasks to crete AshTraceDestination.
  104. // So this function will return a task that can be sent to IO-enabled
  105. // sequence runner to create AshTraceDestination.
  106. using AshTraceDestinationUniquePtr = std::unique_ptr<AshTraceDestination>;
  107. using GenerateTraceDestinationTask =
  108. base::OnceCallback<AshTraceDestinationUniquePtr(void)>;
  109. ASH_EXPORT static GenerateTraceDestinationTask
  110. CreateGenerateTraceDestinationTaskForTesting(
  111. std::unique_ptr<AshTraceDestinationIO> io,
  112. base::Time timestamp);
  113. ASH_EXPORT const AshTraceDestination* GetTraceDestinationForTesting() const;
  114. private:
  115. // Starts tracing after `destination` was initialized on the ThreadPool.
  116. void OnTraceDestinationInitialized(
  117. std::unique_ptr<AshTraceDestination> destination);
  118. // Marks file export operation completed.
  119. void OnPendingFileStored(std::unique_ptr<AshTraceDestination> destination,
  120. bool success,
  121. std::string error_message);
  122. // Stores memory trace file to permanent location.
  123. void StorePendingFile();
  124. // Trace status
  125. Status status_ = Status::kEmpty;
  126. // When trace was started.
  127. const base::Time timestamp_;
  128. bool user_logged_in_ = false;
  129. AshTracingManager* tracing_manager_;
  130. // This object is deleted once tracing is stopped.
  131. std::unique_ptr<AshTracingHandler> tracing_handler_;
  132. // Non-empty if error has occurred.
  133. std::string error_message_;
  134. std::unique_ptr<AshTraceDestination> trace_destination_;
  135. SEQUENCE_CHECKER(my_sequence_checker_);
  136. base::WeakPtrFactory<AshTracingRequest> weak_factory_{this};
  137. };
  138. } // namespace hud_display
  139. } // namespace ash
  140. #endif // ASH_HUD_DISPLAY_ASH_TRACING_REQUEST_H_