fix: rework lifetime mgmt of ClearDataTask
/ClearDataOperation
(#47361)
* fix: rework lifetime mgmt of ClearDataTask/ClearDataOperation * Update shell/browser/api/electron_api_session.cc Co-authored-by: Robo <hop2deep@gmail.com> * Update shell/browser/api/electron_api_session.cc Co-authored-by: Robo <hop2deep@gmail.com> * Update shell/browser/api/electron_api_session.cc Co-authored-by: Robo <hop2deep@gmail.com> * Update shell/browser/api/electron_api_session.cc Co-authored-by: Robo <hop2deep@gmail.com> --------- Co-authored-by: Robo <hop2deep@gmail.com>
This commit is contained in:
parent
0b84c68229
commit
06bc59be88
1 changed files with 38 additions and 26 deletions
|
@ -84,6 +84,7 @@
|
|||
#include "shell/common/gin_converters/time_converter.h"
|
||||
#include "shell/common/gin_converters/usb_protected_classes_converter.h"
|
||||
#include "shell/common/gin_converters/value_converter.h"
|
||||
#include "shell/common/gin_helper/cleaned_up_at_exit.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
|
@ -198,9 +199,11 @@ std::vector<std::string> GetDataTypesFromMask(
|
|||
|
||||
// Represents a task to clear browsing data for the `clearData` API method.
|
||||
//
|
||||
// This type manages its own lifetime, deleting itself once the task finishes
|
||||
// completely.
|
||||
class ClearDataTask {
|
||||
// This type manages its own lifetime,
|
||||
// 1) deleting itself once all the operations created by this task are
|
||||
// completed. 2) through gin_helper::CleanedUpAtExit, ensuring it's destroyed
|
||||
// before the node environment shuts down.
|
||||
class ClearDataTask : public gin_helper::CleanedUpAtExit {
|
||||
public:
|
||||
// Starts running a task. This function will return before the task is
|
||||
// finished, but will resolve or reject the |promise| when it finishes.
|
||||
|
@ -211,7 +214,7 @@ class ClearDataTask {
|
|||
std::vector<url::Origin> origins,
|
||||
BrowsingDataFilterBuilder::Mode filter_mode,
|
||||
BrowsingDataFilterBuilder::OriginMatchingMode origin_matching_mode) {
|
||||
std::shared_ptr<ClearDataTask> task(new ClearDataTask(std::move(promise)));
|
||||
auto* task = new ClearDataTask(std::move(promise));
|
||||
|
||||
// This method counts as an operation. This is important so we can call
|
||||
// `OnOperationFinished` at the end of this method as a fallback if all the
|
||||
|
@ -255,42 +258,36 @@ class ClearDataTask {
|
|||
}
|
||||
|
||||
// This static method counts as an operation.
|
||||
task->OnOperationFinished(std::nullopt);
|
||||
task->OnOperationFinished(nullptr, std::nullopt);
|
||||
}
|
||||
|
||||
private:
|
||||
// An individual |content::BrowsingDataRemover::Remove...| operation as part
|
||||
// of a full |ClearDataTask|. This class manages its own lifetime, cleaning
|
||||
// itself up after the operation completes and notifies the task of the
|
||||
// result.
|
||||
// of a full |ClearDataTask|. This class is owned by ClearDataTask and cleaned
|
||||
// up either when the operation completes or when ClearDataTask is destroyed.
|
||||
class ClearDataOperation : private BrowsingDataRemover::Observer {
|
||||
public:
|
||||
static void Run(std::shared_ptr<ClearDataTask> task,
|
||||
BrowsingDataRemover* remover,
|
||||
BrowsingDataRemover::DataType data_type_mask,
|
||||
std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) {
|
||||
auto* operation = new ClearDataOperation(task, remover);
|
||||
ClearDataOperation(ClearDataTask* task, BrowsingDataRemover* remover)
|
||||
: task_(task) {
|
||||
observation_.Observe(remover);
|
||||
}
|
||||
|
||||
void Start(BrowsingDataRemover* remover,
|
||||
BrowsingDataRemover::DataType data_type_mask,
|
||||
std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) {
|
||||
remover->RemoveWithFilterAndReply(base::Time::Min(), base::Time::Max(),
|
||||
data_type_mask, kClearOriginTypeAll,
|
||||
std::move(filter_builder), operation);
|
||||
std::move(filter_builder), this);
|
||||
}
|
||||
|
||||
// BrowsingDataRemover::Observer:
|
||||
void OnBrowsingDataRemoverDone(
|
||||
BrowsingDataRemover::DataType failed_data_types) override {
|
||||
task_->OnOperationFinished(failed_data_types);
|
||||
delete this;
|
||||
task_->OnOperationFinished(this, failed_data_types);
|
||||
}
|
||||
|
||||
private:
|
||||
ClearDataOperation(std::shared_ptr<ClearDataTask> task,
|
||||
BrowsingDataRemover* remover)
|
||||
: task_(task) {
|
||||
observation_.Observe(remover);
|
||||
}
|
||||
|
||||
std::shared_ptr<ClearDataTask> task_;
|
||||
raw_ptr<ClearDataTask> task_;
|
||||
base::ScopedObservation<BrowsingDataRemover, BrowsingDataRemover::Observer>
|
||||
observation_{this};
|
||||
};
|
||||
|
@ -299,18 +296,20 @@ class ClearDataTask {
|
|||
: promise_(std::move(promise)) {}
|
||||
|
||||
static void StartOperation(
|
||||
std::shared_ptr<ClearDataTask> task,
|
||||
ClearDataTask* task,
|
||||
BrowsingDataRemover* remover,
|
||||
BrowsingDataRemover::DataType data_type_mask,
|
||||
std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) {
|
||||
// Track this operation
|
||||
task->operations_running_ += 1;
|
||||
|
||||
ClearDataOperation::Run(task, remover, data_type_mask,
|
||||
std::move(filter_builder));
|
||||
auto& operation = task->operations_.emplace_back(
|
||||
std::make_unique<ClearDataOperation>(task, remover));
|
||||
operation->Start(remover, data_type_mask, std::move(filter_builder));
|
||||
}
|
||||
|
||||
void OnOperationFinished(
|
||||
ClearDataOperation* operation,
|
||||
std::optional<BrowsingDataRemover::DataType> failed_data_types) {
|
||||
DCHECK_GT(operations_running_, 0);
|
||||
operations_running_ -= 1;
|
||||
|
@ -319,6 +318,16 @@ class ClearDataTask {
|
|||
failed_data_types_ |= failed_data_types.value();
|
||||
}
|
||||
|
||||
if (operation) {
|
||||
operations_.erase(
|
||||
std::remove_if(
|
||||
operations_.begin(), operations_.end(),
|
||||
[operation](const std::unique_ptr<ClearDataOperation>& op) {
|
||||
return op.get() == operation;
|
||||
}),
|
||||
operations_.end());
|
||||
}
|
||||
|
||||
// If this is the last operation, then the task is finished
|
||||
if (operations_running_ == 0) {
|
||||
OnTaskFinished();
|
||||
|
@ -346,11 +355,14 @@ class ClearDataTask {
|
|||
|
||||
promise_.Reject(error);
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
int operations_running_ = 0;
|
||||
BrowsingDataRemover::DataType failed_data_types_ = 0ULL;
|
||||
gin_helper::Promise<void> promise_;
|
||||
std::vector<std::unique_ptr<ClearDataOperation>> operations_;
|
||||
};
|
||||
|
||||
base::Value::Dict createProxyConfig(ProxyPrefs::ProxyMode proxy_mode,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue