blob: ac15661e995a2e5e58cc62b390205c63dc3a73f5 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_BROWSING_DATA_CONTENT_BROWSING_DATA_MODEL_H_
#define COMPONENTS_BROWSING_DATA_CONTENT_BROWSING_DATA_MODEL_H_
#include <iterator>
#include <map>
#include "base/containers/enum_set.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ref.h"
#include "components/browsing_data/content/browsing_data_quota_helper.h"
#include "content/public/browser/attribution_data_model.h"
#include "content/public/browser/interest_group_manager.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
#include "url/origin.h"
namespace content {
class BrowserContext;
class StoragePartition;
}
// Provides a model interface into a collection of Browsing Data for use in the
// UI. Exposes a uniform view into browsing data based on the concept of
// "data owners", which denote which entity the data should be closely
// associated with in UI surfaces.
// TODO(crbug.com/1271155): Implementation in progress, should not be used.
class BrowsingDataModel {
public:
// The entity that logically owns a set of data. All browsing data will be
// grouped by its owner.
using DataOwner = absl::variant<std::string, // Hostname
url::Origin>;
// Storage types which are represented by the model. Some types have
// incomplete implementations, and are marked as such.
// TODO(crbug.com/1271155): Complete implementations for all browsing data.
enum class StorageType {
kTrustTokens = 1, // Only issuance information considered.
kSharedStorage = 2,
kInterestGroup,
kAttributionReporting,
kPartitionedQuotaStorage, // Not fetched from disk or deleted.
kUnpartitionedQuotaStorage,
kFirstType = kTrustTokens,
kLastType = kUnpartitionedQuotaStorage,
kExtendedDelegateRange =
64, // This is needed to include delegate values when adding delegate
// browsing data to the model.
};
using StorageTypeSet = base::EnumSet<StorageType,
StorageType::kFirstType,
StorageType::kExtendedDelegateRange>;
// The information which uniquely identifies this browsing data. The set of
// data an entry represents can be pulled from the relevant storage backends
// using this information.
typedef absl::variant<url::Origin, // Single origin, e.g. Trust Tokens
blink::StorageKey, // Partitioned JS storage
content::InterestGroupManager::InterestGroupDataKey,
content::AttributionDataModel::DataKey
// TODO(crbug.com/1271155): Additional backend keys.
>
DataKey;
// Information about the data pointed at by a DataKey.
struct DataDetails {
~DataDetails();
bool operator==(const DataDetails& other) const;
// An EnumSet of storage types for this data.
StorageTypeSet storage_types;
// The on-disk size of this storage.
uint64_t storage_size = 0;
// The number of cookies included in this storage. This is only included to
// support legacy UI surfaces.
// TODO(crbug.com/1359998): Remove this when UI no longer requires it.
uint64_t cookie_count = 0;
};
// A view of a single "unit" of browsing data. Considered a "view" as it holds
// references to data contained within the model.
struct BrowsingDataEntryView {
~BrowsingDataEntryView();
BrowsingDataEntryView(const BrowsingDataEntryView& other) = delete;
// Returns true if |origin| is within this browsing data's owning entity.
bool Matches(const url::Origin& origin) const;
// The logical owner of this browsing data. This is the entity which this
// information will be most strongly associated with in UX surfaces.
const raw_ref<const DataOwner, DanglingUntriaged> data_owner;
// The unique identifier for the data represented by this entry.
const raw_ref<const DataKey, DanglingUntriaged> data_key;
// Information about the data represented by this entry.
const raw_ref<const DataDetails, DanglingUntriaged> data_details;
private:
friend class BrowsingDataModel;
BrowsingDataEntryView(const DataOwner& data_owner,
const DataKey& data_key,
const DataDetails& data_details);
};
// A delegate to handle non components/ data type retrieval and deletion.
class Delegate {
public:
//
struct DelegateEntry {
DelegateEntry(DataKey data_key,
StorageType storage_type,
uint64_t storage_size);
DelegateEntry(const DelegateEntry& other);
~DelegateEntry();
DataKey data_key;
StorageType storage_type;
uint64_t storage_size;
};
// Retrieves all possible data keys with its associated storage size.
virtual void GetAllDataKeys(
base::OnceCallback<void(std::vector<DelegateEntry>)> callback) = 0;
// Removes all data that matches the data key.
virtual void RemoveDataKey(DataKey data_key,
StorageTypeSet storage_types,
base::OnceClosure callback) = 0;
// Returns the owner of the data identified by the given DataKey and
// StorageType, or nullopt if the delegate does not manage the entity that
// owns the given data.
virtual absl::optional<DataOwner> GetDataOwner(
DataKey data_key,
StorageType storage_type) const = 0;
virtual ~Delegate() = default;
};
// The model provides a single interface for retrieving browsing data, in the
// form of an Input iterator (read-only, increment only, no random access)
// over BrowsingDataEntryViews.
// Iterators are invalidated whenever the model is updated.
using DataKeyEntries = std::map<DataKey, DataDetails>;
using BrowsingDataEntries = std::map<DataOwner, DataKeyEntries>;
struct Iterator {
~Iterator();
Iterator(const Iterator& iterator);
bool operator==(const Iterator& other) const;
bool operator!=(const Iterator& other) const;
// Input iterator functionality. These declarations allow STL functions to
// make use of the iterator interface.
// More details: https://en.cppreference.com/w/cpp/iterator/iterator_tags
using iterator_category = std::input_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = BrowsingDataEntryView;
using pointer = BrowsingDataEntryView*;
using reference = BrowsingDataEntryView&;
BrowsingDataEntryView operator*() const;
Iterator& operator++();
private:
friend class BrowsingDataModel;
Iterator(BrowsingDataEntries::const_iterator outer_iterator,
BrowsingDataEntries::const_iterator end_outer_iterator);
BrowsingDataEntries::const_iterator outer_iterator_;
DataKeyEntries::const_iterator inner_iterator_;
const BrowsingDataEntries::const_iterator outer_end_iterator_;
};
Iterator begin() const;
Iterator end() const;
virtual ~BrowsingDataModel();
// Returns number of entries within the Model.
size_t size() const { return browsing_data_entries_.size(); }
// Consults supported storage backends to create and populate a Model based
// on the current state of `browser_context`.
static void BuildFromDisk(
content::BrowserContext* browser_context,
std::unique_ptr<Delegate> delegate,
base::OnceCallback<void(std::unique_ptr<BrowsingDataModel>)>
complete_callback);
// Consults supported storage backends to create and populate a Model based
// on the current state of `storage_partition`.
static void BuildFromNonDefaultStoragePartition(
content::StoragePartition* storage_partition,
std::unique_ptr<Delegate> delegate,
base::OnceCallback<void(std::unique_ptr<BrowsingDataModel>)>
complete_callback);
// Creates and returns an empty model, for population via AddBrowsingData().
static std::unique_ptr<BrowsingDataModel> BuildEmpty(
content::StoragePartition* storage_partition,
std::unique_ptr<Delegate> delegate);
// Directly add browsing data to the Model. The appropriate BrowsingDataEntry
// will be created or modified. Typically this should only be used when the
// model was created using BuildEmpty().
void AddBrowsingData(const DataKey& data_key,
StorageType storage_type,
uint64_t storage_size,
// TODO(crbug.com/1359998): Deprecate cookie count.
uint64_t cookie_count = 0);
// Removes all browsing data associated with `data_owner`, reaches out to
// all supported storage backends to remove the data, and updates the model.
// Deletion at more granularity than `data_owner` is purposefully not
// supported by this model. UI that wishes to support such deletion should
// consider whether it is really required, and if so, implement it separately.
// The in-memory representation of the model is updated immediately, while
// actual deletion from disk occurs async, completion reported by `completed`.
// Invalidates any iterators.
// Virtual to allow an in-memory only fake to be created.
virtual void RemoveBrowsingData(const DataOwner& data_owner,
base::OnceClosure completed);
protected:
friend class BrowsingDataModelTest;
static void BuildFromStoragePartition(
content::StoragePartition* storage_partition,
std::unique_ptr<Delegate> delegate,
base::OnceCallback<void(std::unique_ptr<BrowsingDataModel>)>
complete_callback);
// Private as one of the static BuildX functions should be used instead.
explicit BrowsingDataModel(
content::StoragePartition* storage_partition,
std::unique_ptr<Delegate> delegate
// TODO(crbug.com/1271155): Inject other dependencies.
);
// Pulls information from disk and populate the model.
// Virtual to allow an in-memory only fake to be created.
virtual void PopulateFromDisk(base::OnceClosure finished_callback);
// Backing data structure for this model. Is a map from data owners to a
// list of tuples (stored as a map) of <DataKey, DataDetails>. Building the
// model requires updating existing entries as data becomes available, so
// fast lookup is required. Similarly, keying the outer map on data owner
// supports removal by data owner performantly.
BrowsingDataEntries browsing_data_entries_;
// Non-owning pointers to storage backends. All derivable from a browser
// context, but broken out to allow easier injection in tests.
// TODO(crbug.com/1271155): More backends to come, they should all be broken
// out from the browser context at the appropriate level.
raw_ptr<content::StoragePartition> storage_partition_;
// Used to handle quota managed data on IO thread.
scoped_refptr<BrowsingDataQuotaHelper> quota_helper_;
// Owning pointer to the delegate responsible for non components/ data
// retrieval and removal.
std::unique_ptr<Delegate> delegate_;
};
#endif // COMPONENTS_BROWSING_DATA_CONTENT_BROWSING_DATA_MODEL_H_