1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
// 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_
|