summaryrefslogtreecommitdiffstats
path: root/ios/chrome/browser/browsing_data/browsing_data_remover_helper.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ios/chrome/browser/browsing_data/browsing_data_remover_helper.cc')
-rw-r--r--ios/chrome/browser/browsing_data/browsing_data_remover_helper.cc98
1 files changed, 98 insertions, 0 deletions
diff --git a/ios/chrome/browser/browsing_data/browsing_data_remover_helper.cc b/ios/chrome/browser/browsing_data/browsing_data_remover_helper.cc
new file mode 100644
index 0000000..3df5741
--- /dev/null
+++ b/ios/chrome/browser/browsing_data/browsing_data_remover_helper.cc
@@ -0,0 +1,98 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ios/chrome/browser/browsing_data/browsing_data_remover_helper.h"
+
+#include <utility>
+
+#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+
+BrowsingDataRemoverHelper::BrowsingDataRemoverHelper()
+ : current_remover_(nullptr) {}
+
+BrowsingDataRemoverHelper::~BrowsingDataRemoverHelper() {
+ DCHECK(pending_removals_.empty());
+}
+
+BrowsingDataRemoverHelper::BrowsingDataRemovalInfo::BrowsingDataRemovalInfo(
+ int remove_mask,
+ const base::Closure& callback)
+ : remove_mask(remove_mask) {
+ callbacks.push_back(callback);
+}
+
+BrowsingDataRemoverHelper::BrowsingDataRemovalInfo::~BrowsingDataRemovalInfo() {
+}
+
+void BrowsingDataRemoverHelper::Remove(ios::ChromeBrowserState* browser_state,
+ int remove_mask,
+ const base::Closure& callback) {
+ DCHECK(browser_state);
+ DCHECK(!browser_state->IsOffTheRecord());
+ // IOSChromeBrowsingDataRemover::Callbacks are called before
+ // OnIOSChromeBrowsingDataRemoverDone() and after
+ // IOSChromeBrowsingDataRemover::is_removing() is set to false. In this
+ // window, |current_remover_| needs to be checked as well.
+ if (current_remover_ || IOSChromeBrowsingDataRemover::is_removing()) {
+ // IOSChromeBrowsingDataRemover is not re-entrant. If it is already running,
+ // add the browser_state to |pending_removals_| for later deletion. If the
+ // browser_state is already scheduled for removal of browsing data, update
+ // the remove mask and callbacks.
+ DCHECK(current_remover_);
+ auto pending_removals_iter = pending_removals_.find(browser_state);
+ if (pending_removals_iter == pending_removals_.end()) {
+ scoped_ptr<BrowsingDataRemovalInfo> removal_info(
+ new BrowsingDataRemovalInfo(remove_mask, callback));
+ pending_removals_[browser_state] = std::move(removal_info);
+ } else {
+ pending_removals_iter->second->remove_mask |= remove_mask;
+ pending_removals_iter->second->callbacks.push_back(callback);
+ }
+ } else {
+ scoped_ptr<BrowsingDataRemovalInfo> removal_info(
+ new BrowsingDataRemovalInfo(remove_mask, callback));
+ DoRemove(browser_state, std::move(removal_info));
+ }
+}
+
+void BrowsingDataRemoverHelper::OnIOSChromeBrowsingDataRemoverDone() {
+ current_remover_ = nullptr;
+
+ DCHECK(current_removal_info_);
+ // Inform clients of the currently finished removal operation that browsing
+ // data was removed.
+ for (const auto& callback : current_removal_info_->callbacks) {
+ if (!callback.is_null()) {
+ callback.Run();
+ }
+ }
+ current_removal_info_.reset();
+
+ if (pending_removals_.empty())
+ return;
+
+ ios::ChromeBrowserState* next_browser_state =
+ pending_removals_.begin()->first;
+ scoped_ptr<BrowsingDataRemovalInfo> removal_info =
+ std::move(pending_removals_[next_browser_state]);
+ pending_removals_.erase(next_browser_state);
+ DoRemove(next_browser_state, std::move(removal_info));
+}
+
+void BrowsingDataRemoverHelper::DoRemove(
+ ios::ChromeBrowserState* browser_state,
+ scoped_ptr<BrowsingDataRemovalInfo> removal_info) {
+ DCHECK(!current_remover_ && !IOSChromeBrowsingDataRemover::is_removing());
+
+ current_removal_info_ = std::move(removal_info);
+
+ // IOSChromeBrowsingDataRemover deletes itself.
+ IOSChromeBrowsingDataRemover* remover =
+ IOSChromeBrowsingDataRemover::CreateForPeriod(
+ browser_state, IOSChromeBrowsingDataRemover::EVERYTHING);
+ remover->AddObserver(this);
+ current_remover_ = remover;
+ int remove_mask = current_removal_info_->remove_mask;
+ remover->Remove(remove_mask);
+}