blob: e4f2a5e9977462c517e7647618f5a2de34e6e095 [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_BROWSING_DATA_BROWSING_DATA_REMOVER_IMPL_H_
#define CONTENT_BROWSER_BROWSING_DATA_BROWSING_DATA_REMOVER_IMPL_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include "base/cancelable_callback.h"
#include "base/containers/queue.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/supports_user_data.h"
#include "base/synchronization/waitable_event_watcher.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/storage_partition_config.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "url/origin.h"
namespace content {
class BrowserContext;
class BrowsingDataFilterBuilder;
class StoragePartition;
class CONTENT_EXPORT BrowsingDataRemoverImpl
: public BrowsingDataRemover,
public base::SupportsUserData::Data {
public:
explicit BrowsingDataRemoverImpl(BrowserContext* browser_context);
BrowsingDataRemoverImpl(const BrowsingDataRemoverImpl&) = delete;
BrowsingDataRemoverImpl& operator=(const BrowsingDataRemoverImpl&) = delete;
~BrowsingDataRemoverImpl() override;
// Is the BrowsingDataRemoverImpl currently in the process of removing data?
bool IsRemovingForTesting() { return is_removing_; }
// Removes storage buckets of a storage key.
// If |storage_partition_config| is null, the operation will take place
// on the profile's default storage partition.
void RemoveStorageBucketsAndReply(
const std::optional<StoragePartitionConfig> storage_partition_config,
const blink::StorageKey& storage_key,
const std::set<std::string>& storage_buckets,
base::OnceClosure callback);
// BrowsingDataRemover implementation:
void SetEmbedderDelegate(
BrowsingDataRemoverDelegate* embedder_delegate) override;
bool DoesOriginMatchMaskForTesting(
uint64_t origin_type_mask,
const url::Origin& origin,
storage::SpecialStoragePolicy* special_storage_policy) override;
void Remove(const base::Time& delete_begin,
const base::Time& delete_end,
uint64_t remove_mask,
uint64_t origin_type_mask) override;
void RemoveWithFilter(
const base::Time& delete_begin,
const base::Time& delete_end,
uint64_t remove_mask,
uint64_t origin_type_mask,
std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) override;
void RemoveAndReply(const base::Time& delete_begin,
const base::Time& delete_end,
uint64_t remove_mask,
uint64_t origin_type_mask,
Observer* observer) override;
void RemoveWithFilterAndReply(
const base::Time& delete_begin,
const base::Time& delete_end,
uint64_t remove_mask,
uint64_t origin_type_mask,
std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
Observer* observer) override;
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
void SetWouldCompleteCallbackForTesting(
const base::RepeatingCallback<
void(base::OnceClosure continue_to_completion)>& callback) override;
const base::Time& GetLastUsedBeginTimeForTesting() override;
uint64_t GetLastUsedRemovalMaskForTesting() override;
uint64_t GetLastUsedOriginTypeMaskForTesting() override;
std::optional<StoragePartitionConfig>
GetLastUsedStoragePartitionConfigForTesting() override;
uint64_t GetPendingTaskCountForTesting() override;
void ClearClientHintCacheAndReply(const url::Origin& origin,
base::OnceClosure callback);
// Used for testing.
void OverrideStoragePartitionForTesting(
const StoragePartitionConfig& storage_partition_config,
StoragePartition* storage_partition);
protected:
// A common reduction of all public Remove[WithFilter][AndReply] methods.
virtual void RemoveInternal(
const base::Time& delete_begin,
const base::Time& delete_end,
uint64_t remove_mask,
uint64_t origin_type_mask,
std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
Observer* observer);
private:
// Testing the private RemovalTask.
FRIEND_TEST_ALL_PREFIXES(BrowsingDataRemoverImplTest, MultipleTasks);
FRIEND_TEST_ALL_PREFIXES(BrowsingDataRemoverImplTest, MultipleIdenticalTasks);
// For debugging purposes. Please add new deletion tasks at the end.
// This enum is recorded in a histogram, so don't change or reuse ids.
// LINT.IfChange(TracingDataType)
enum class TracingDataType {
kSynchronous = 1,
kEmbedderData = 2,
kStoragePartition = 3,
kHttpCache = 4,
kHttpAndMediaCaches = 5,
kReportingCache = 6,
kChannelIds = 7,
kNetworkHistory = 8,
kAuthCache = 9,
kCodeCaches = 10,
kNetworkErrorLogging = 11,
kTrustTokens = 12,
kConversions = 13,
kDeferredCookies = 14,
kSharedStorage = 15,
kPreflightCache = 16,
kSharedDictionary = 17,
kPrefetchCache = 18,
kPrerenderCache = 19,
kMaxValue = kPrerenderCache,
};
// LINT.ThenChange(//tools/metrics/histograms/metadata/history/enums.xml:BrowsingDataRemoverTasks)
// Returns the suffix for the History.ClearBrowsingData.Duration.Task.{Task}
// histogram
const char* GetHistogramSuffix(TracingDataType task);
// Represents a single removal task. Contains all parameters needed to execute
// it and a pointer to the observer that added it. CONTENT_EXPORTed to be
// visible in tests.
struct CONTENT_EXPORT RemovalTask {
RemovalTask(const base::Time& delete_begin,
const base::Time& delete_end,
uint64_t remove_mask,
uint64_t origin_type_mask,
std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
Observer* observer);
RemovalTask(RemovalTask&& other) noexcept;
~RemovalTask();
// Returns true if the deletion parameters are equal.
// Does not compare |observer| and |task_started|.
bool IsSameDeletion(const RemovalTask& other);
base::Time delete_begin;
base::Time delete_end;
uint64_t remove_mask;
uint64_t origin_type_mask;
std::unique_ptr<BrowsingDataFilterBuilder> filter_builder;
std::vector<raw_ptr<Observer, VectorExperimental>> observers;
base::TimeTicks task_started;
};
// Setter for |is_removing_|; DCHECKs that we can only start removing if we're
// not already removing, and vice-versa.
void SetRemoving(bool is_removing);
// Executes the next removal task. Called after the previous task was finished
// or directly from Remove() if the task queue was empty.
void RunNextTask();
// Removes the specified items related to browsing for a specific host. If the
// provided |remove_url| is empty, data is removed for all origins; otherwise,
// it is restricted by the origin filter origin (where implemented yet). The
// |origin_type_mask| parameter defines the set of origins from which data
// should be removed (protected, unprotected, or both).
// TODO(ttr314): Remove "(where implemented yet)" constraint above once
// crbug.com/113621 is done.
// TODO(crbug.com/40458377): Support all backends w/ origin filter.
void RemoveImpl(const base::Time& delete_begin,
const base::Time& delete_end,
uint64_t remove_mask,
BrowsingDataFilterBuilder* filter_builder,
uint64_t origin_type_mask);
void OnDelegateDone(base::OnceClosure completion_closure,
uint64_t failed_data_types);
// Notifies observers and transitions to the idle state.
void Notify();
// Called by the closures returned by CreateTaskCompletionClosure().
// Checks if all tasks have completed, and if so, calls Notify().
void OnTaskComplete(TracingDataType data_type, base::TimeTicks started);
// Called when the storage buckets data has been removed.
void DidRemoveStorageBuckets(base::OnceClosure callback);
// Increments the number of pending tasks by one, and returns a OnceClosure
// that calls OnTaskComplete(). The Remover is complete once all the closures
// created by this method have been invoked.
base::OnceClosure CreateTaskCompletionClosure(TracingDataType data_type);
// Same as CreateTaskCompletionClosure() but guarantees that
// OnTaskComplete() is called if the task is dropped. That can typically
// happen when the connection is closed while an interface call is made.
base::OnceClosure CreateTaskCompletionClosureForMojo(
TracingDataType data_type);
// Records unfinished tasks from |pending_sub_tasks_| after a delay.
void RecordUnfinishedSubTasks();
StoragePartition* GetStoragePartition(
std::optional<StoragePartitionConfig> storage_partition_config);
// This does the actual clearing of the client hint cache for the provided
// origin. It should be invoked only via ClearClientHintCacheAndReply.
void ClearClientHintCacheAndReplyImpl(const url::Origin& origin,
base::OnceClosure callback);
// Like GetWeakPtr(), but returns a weak pointer to BrowsingDataRemoverImpl
// for internal purposes.
base::WeakPtr<BrowsingDataRemoverImpl> GetWeakPtr();
// The browser context we're to remove from.
raw_ptr<BrowserContext> browser_context_;
// A delegate to delete the embedder-specific data. Owned by the embedder.
raw_ptr<BrowsingDataRemoverDelegate, DanglingUntriaged> embedder_delegate_;
// Start time to delete from.
base::Time delete_begin_;
// End time to delete to.
base::Time delete_end_;
// The removal mask for the current removal operation.
uint64_t remove_mask_ = 0;
// From which types of origins should we remove data?
uint64_t origin_type_mask_ = 0;
// The StoragePartition from which data should be removed, or the default
// if absent.
std::optional<StoragePartitionConfig> storage_partition_config_ =
std::nullopt;
std::vector<std::string> domains_for_deferred_cookie_deletion_;
// True if Remove has been invoked.
bool is_removing_;
// Removal tasks to be processed.
std::deque<RemovalTask> task_queue_;
// If non-null, the |would_complete_callback_| is called each time an instance
// is about to complete a browsing data removal process, and has the ability
// to artificially delay completion. Used for testing.
base::RepeatingCallback<void(base::OnceClosure continue_to_completion)>
would_complete_callback_;
// Records which tasks of a deletion are currently active.
std::set<TracingDataType> pending_sub_tasks_;
uint64_t failed_data_types_ = 0;
// Fires after some time to track slow tasks. Cancelled when all tasks
// are finished.
base::CancelableOnceClosure slow_pending_tasks_closure_;
// Observers of the global state and individual tasks.
base::ObserverList<Observer, true>::Unchecked observer_list_;
// We do not own the StoragePartitions.
std::map<StoragePartitionConfig, raw_ptr<StoragePartition>>
storage_partitions_for_testing_;
base::WeakPtrFactory<BrowsingDataRemoverImpl> weak_ptr_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_BROWSING_DATA_BROWSING_DATA_REMOVER_IMPL_H_