| // Copyright 2021 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_SUPPORT_TOOL_SUPPORT_TOOL_HANDLER_H_ |
| #define CHROME_BROWSER_SUPPORT_TOOL_SUPPORT_TOOL_HANDLER_H_ |
| |
| #include <memory> |
| #include <optional> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "base/files/file_path.h" |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/functional/callback_forward.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/sequence_checker.h" |
| #include "base/task/sequenced_task_runner.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/support_tool/data_collector.h" |
| #include "chrome/browser/support_tool/support_packet_metadata.h" |
| #include "components/feedback/redaction_tool/pii_types.h" |
| #include "components/feedback/redaction_tool/redaction_tool.h" |
| #include "components/feedback/system_logs/system_logs_source.h" |
| |
| using SupportToolDataCollectedCallback = |
| base::OnceCallback<void(const PIIMap&, std::set<SupportToolError>)>; |
| |
| using SupportToolDataExportedCallback = |
| base::OnceCallback<void(base::FilePath, std::set<SupportToolError>)>; |
| |
| // The SupportToolHandler collects debug data from a list of DataCollectors. |
| // |
| // EXAMPLE: |
| // class Foo { |
| // public: |
| // void ProcessCollectedData(const PIIMap& detected, |
| // std::set<SupportToolError> errors) |
| // { |
| // // Do something with the detected PII. |
| // // Check if error is returned. |
| // if(!errors.empty()) { |
| // // do something with the error. |
| // } |
| // } |
| // void GetSupportData() { |
| // handler_.AddSource(std::make_unique<DataCollectorOne>()); |
| // handler_.AddSource(std::make_unique<DataCollectorTwo>()); |
| // handler_.CollectSupportData(base::BindOnce(&Foo::ProcessCollectedData, |
| // weak_ptr_factory_.GetWeakPtr())); |
| // } |
| // void OnDataExported(base::FilePath path, std::set<SupportToolError> errors) |
| // { |
| // // Do something about the data that has been exported. |
| // // Check and do something if any errors returned. |
| // } |
| // void ExportSupportData() { |
| // std::set<PIIMap> pii_to_keep; |
| // // Add some PIITypes to keep into the pii_to_keep set. |
| // base::FilePath target_path{"directory_to_export_data"}; |
| // handler_.ExportCollectedData(pii_to_keep, |
| // target_path, |
| // base::BindOnce(&Foo::OnDataExported, |
| // weak_ptr_factory_.GetWeakPtr())); |
| // } |
| // private: |
| // // The class has a SupportToolHandler member. |
| // SupportToolHandler handler_; |
| // base::WeakPtrFactory<Foo> weak_ptr_factory_{this}; |
| // }; |
| |
| class SupportToolHandler { |
| public: |
| // Intended to be used for unit tests. Initializes `case_id_`, |
| // `email_address_` and `issue_description_` as empty string. |
| SupportToolHandler(); |
| SupportToolHandler(std::string case_id, |
| std::string email_address, |
| std::string issue_description, |
| std::optional<std::string> upload_id); |
| ~SupportToolHandler(); |
| |
| // Returns the support case ID. |
| const std::string& GetCaseId(); |
| |
| // Returns the timestamp of data collection start. Must be called after |
| // CollectSupportData() has been called. |
| const base::Time& GetDataCollectionTimestamp(); |
| |
| // Adds `collector` to the list of DataCollectors the SupportToolHandler |
| // will collect data from. |
| void AddDataCollector(std::unique_ptr<DataCollector> collector); |
| |
| // Collects data from the DataCollectors added to the handler. This function |
| // should be called only once on an instance of SupportToolHandler. |
| void CollectSupportData( |
| SupportToolDataCollectedCallback on_data_collection_done_callback); |
| |
| // Exports collected data to the `target_path` and archives the file. Runs |
| // `on_data_exported_callback` with the set of errors in case of an error and |
| // the exported filepath. The filepath given to callback will be empty if the |
| // export couldn't happen due to an error. This function should be called only |
| // once on an instance of SupportToolHandler. |
| void ExportCollectedData( |
| std::set<redaction::PIIType> pii_types_to_keep, |
| base::FilePath target_path, |
| SupportToolDataExportedCallback on_data_exported_callback); |
| |
| // Returns reference to `data_collectors_` for testing. |
| const std::vector<std::unique_ptr<DataCollector>>& |
| GetDataCollectorsForTesting(); |
| |
| private: |
| // OnDataCollected is called when a single DataCollector finished collecting |
| // data. Runs `barrier_closure` to make the handler wait until all |
| // DataCollectors finish collecting. |
| void OnDataCollected(base::RepeatingClosure barrier_closure, |
| std::optional<SupportToolError> error); |
| |
| // OnAllDataCollected is called by a BarrierClosure when all DataCollectors |
| // finish collecting data. Returns the detected PII by running |
| // `on_data_collection_done_callback_`. |
| void OnAllDataCollected(); |
| |
| void OnMetadataContentsPopulated(); |
| |
| // Adds the contents of `pii_map` to `detected_pii_` of this instance. |
| void AddDetectedPII(const PIIMap& pii_map); |
| |
| // Exports collected data into the `tmp_path`. Creates a path for each |
| // DataCollector with their name. The DataCollectors will export their output |
| // to that path then the contents of the `tmp_path` will be put inside a zip |
| // archive on `target_path`. |
| void ExportIntoTempDir(std::set<redaction::PIIType> pii_types_to_keep, |
| base::FilePath target_path, |
| base::FilePath tmp_path); |
| |
| // OnDataCollectorDoneExporting is called when a single DataCollector finished |
| // exporting data. Runs `barrier_closure` to make the handler wait until all |
| // DataCollectors finish collecting. |
| void OnDataCollectorDoneExporting(base::RepeatingClosure barrier_closure, |
| std::optional<SupportToolError> error); |
| |
| // OnAllDataCollectorsDoneExporting is called by a BarrierClosure when all |
| // DataCollectors finish exporting data to their given filepaths. Calls |
| // `metadata_` to add the metadata file to `tmp_path`. |
| void OnAllDataCollectorsDoneExporting( |
| base::FilePath tmp_path, |
| base::FilePath target_path, |
| std::set<redaction::PIIType> pii_types_to_keep); |
| |
| // OnMetadataFileWritten is called when metadata file is written. Archives |
| // the data exported by DataCollectors inside a .zip archive and calls |
| // OnDataExportDone(). |
| void OnMetadataFileWritten(base::FilePath tmp_path, |
| base::FilePath target_path); |
| |
| // Cleans up the temporary directory created to store the output files and |
| // then calls `on_data_export_done_callback_`. |
| void OnDataExportDone(base::FilePath exported_path); |
| |
| // Cleans up `this.temp_dir_`. We need to clean-up the temporary directory |
| // explicitly since SupportToolHandler will work on UI thread and all file |
| // operation must be done in a worker thread to not block UI thread. We can |
| // only pass the file path between threads as sharing the ScopedTempDir object |
| // is not safe to pass between threads. |
| void CleanUp(); |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| base::Time data_collection_timestamp_; |
| SupportPacketMetadata metadata_; |
| PIIMap detected_pii_; |
| std::vector<std::unique_ptr<DataCollector>> data_collectors_; |
| // Stores the set of errors that are returned from DataCollector calls. Reset |
| // the set each time SupportToolHandler starts executing a function. |
| std::set<SupportToolError> collected_errors_; |
| SupportToolDataCollectedCallback on_data_collection_done_callback_; |
| SupportToolDataExportedCallback on_data_export_done_callback_; |
| // Temporary directory for storing the output files. Will be deleted when the |
| // data export is done or on destruction of the SupportToolHandler instance if |
| // it hasn't been removed before. |
| base::FilePath temp_dir_; |
| // SequencedTaskRunner and RedactionToolContainer for the data collectors that |
| // will need to use redaction::RedactionTool for masking PII from the |
| // collected logs. |
| scoped_refptr<base::SequencedTaskRunner> task_runner_for_redaction_tool_; |
| scoped_refptr<redaction::RedactionToolContainer> redaction_tool_container_; |
| base::WeakPtrFactory<SupportToolHandler> weak_ptr_factory_{this}; |
| }; |
| |
| #endif // CHROME_BROWSER_SUPPORT_TOOL_SUPPORT_TOOL_HANDLER_H_ |