| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_LOGGING_H_ |
| #define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_LOGGING_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include "base/auto_reset.h" |
| #include "base/containers/circular_deque.h" |
| #include "base/files/file_path.h" |
| #include "base/functional/callback_forward.h" |
| #include "base/memory/raw_ref.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/one_shot_event.h" |
| #include "base/task/sequenced_task_runner.h" |
| #include "base/task/task_traits.h" |
| #include "base/timer/timer.h" |
| #include "base/values.h" |
| #include "chrome/browser/web_applications/file_utils_wrapper.h" |
| #include "chrome/browser/web_applications/web_app_constants.h" |
| #include "chrome/browser/web_applications/web_app_install_info.h" |
| #include "chrome/browser/web_applications/web_app_install_utils.h" |
| #include "components/webapps/browser/installable/installable_metrics.h" |
| #include "components/webapps/common/web_app_id.h" |
| |
| class Profile; |
| |
| namespace base { |
| class Clock; |
| class ListValue; |
| class Value; |
| class DictValue; |
| class DelayTimer; |
| } // namespace base |
| |
| namespace webapps { |
| enum class WebAppUrlLoaderResult; |
| } |
| |
| namespace web_app { |
| class FileUtilsWrapper; |
| |
| enum class PersistableLogMode { |
| // Logs are stored in memory only. Any logs on disk will be deleted. |
| kInMemory, |
| // Logs are periodically persisted to disk with file rotation. The latest log |
| // on disk is loaded into memory on startup. |
| kPersistToDisk, |
| }; |
| |
| // This class is used to hold log entries and optionally save logs to disk, with |
| // file rotation to prevent files that are too large. |
| // |
| // The log is used to display debug information on the |
| // chrome://web-app-internals page. |
| class PersistableLog { |
| public: |
| static std::unique_ptr<PersistableLog> Create( |
| const base::FilePath& log_file, |
| PersistableLogMode mode, |
| int max_log_entries_in_memory, |
| scoped_refptr<FileUtilsWrapper> file_utils); |
| |
| // `clock` must be non-null and outlive the log. |
| static std::unique_ptr<PersistableLog> CreateForTesting( |
| const base::FilePath& log_file, |
| PersistableLogMode mode, |
| int max_log_entries_in_memory, |
| scoped_refptr<FileUtilsWrapper> file_utils, |
| scoped_refptr<base::SequencedTaskRunner> log_writing_task_runner, |
| scoped_refptr<base::SequencedTaskRunner> log_deletion_task_runner, |
| const base::Clock* clock); |
| |
| static base::FilePath GetLogPath(Profile* profile, |
| std::string_view log_filename); |
| static int GetMaxInMemoryLogEntries(); |
| static PersistableLogMode GetMode(); |
| |
| static base::AutoReset<int> SetMaxLogFileSizeBytesForTesting(int size); |
| |
| ~PersistableLog(); |
| |
| // Appends a value to the log, always populating a timestamp under the key |
| // "timestamp_ms" if it is not already present. |
| void Append(base::DictValue object); |
| // Shortcut method for calling Append with "value" set to `value`, and |
| // "timestamp_ms" set to the current time. |
| void AppendValue(base::Value value); |
| |
| // Returns the log entries in descending order of time (newest entry is at the |
| // front). |
| const base::circular_deque<base::DictValue>& GetEntries() const; |
| |
| // Helper method to convert the log entries to a ListValue. |
| base::ListValue CloneToList() const; |
| |
| private: |
| PersistableLog( |
| const base::FilePath& log_file, |
| PersistableLogMode mode, |
| int max_log_entries_in_memory, |
| scoped_refptr<FileUtilsWrapper> file_utils, |
| scoped_refptr<base::SequencedTaskRunner> log_writing_task_runner, |
| scoped_refptr<base::SequencedTaskRunner> log_deletion_task_runner, |
| const base::Clock* clock); |
| |
| void OnLatestLogLoaded(std::optional<base::ListValue> loaded_log); |
| void MaybeWriteCurrentLog(); |
| |
| const base::FilePath log_file_; |
| const PersistableLogMode mode_; |
| const scoped_refptr<FileUtilsWrapper> file_utils_; |
| const int max_log_entries_in_memory_; |
| |
| // Task runners for file operations. Injected for testing. |
| const scoped_refptr<base::SequencedTaskRunner> log_writing_task_runner_; |
| const scoped_refptr<base::SequencedTaskRunner> log_deletion_task_runner_; |
| |
| // Clock for timestamping. Injected for testing. |
| const raw_ref<const base::Clock> clock_; |
| |
| base::OneShotEvent on_load_complete_; |
| base::DelayTimer log_write_timer_; |
| |
| // This is the log that is currently in memory, and is in descending order of |
| // time (newest entry is at the front). |
| base::circular_deque<base::DictValue> log_; |
| |
| // This is the log that is currently being written to disk. The log is in |
| // descending order of time (newest entry is at the end). |
| base::ListValue current_log_for_disk_; |
| int current_disk_log_entry_count_ = 0; |
| |
| base::WeakPtrFactory<PersistableLog> weak_ptr_factory_{this}; |
| }; |
| |
| // Returns a dictionary value containing errors from the downloaded icons. If |
| // there are no errors, returns a an empty dict. |
| base::DictValue LogDownloadedIconsErrors( |
| IconsDownloadedResult icons_downloaded_result, |
| const IconsMap& icons_map, |
| const DownloadedIconsHttpResults& icons_http_results); |
| |
| } // namespace web_app |
| |
| #endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_LOGGING_H_ |