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 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
// Copyright 2023 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_FIRST_PARTY_SETS_FIRST_PARTY_SETS_HANDLER_IMPL_INSTANCE_H_
#define CONTENT_BROWSER_FIRST_PARTY_SETS_FIRST_PARTY_SETS_HANDLER_IMPL_INSTANCE_H_
#include <optional>
#include <string>
#include <utility>
#include "base/containers/circular_deque.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/functional/callback.h"
#include "base/no_destructor.h"
#include "base/sequence_checker.h"
#include "base/thread_annotations.h"
#include "base/threading/sequence_bound.h"
#include "base/timer/elapsed_timer.h"
#include "base/types/optional_ref.h"
#include "base/values.h"
#include "base/version.h"
#include "content/browser/first_party_sets/first_party_sets_handler_database_helper.h"
#include "content/browser/first_party_sets/first_party_sets_handler_impl.h"
#include "content/browser/first_party_sets/first_party_sets_loader.h"
#include "content/common/content_export.h"
#include "net/first_party_sets/first_party_sets_cache_filter.h"
#include "net/first_party_sets/first_party_sets_context_config.h"
#include "net/first_party_sets/global_first_party_sets.h"
#include "net/first_party_sets/local_set_declaration.h"
namespace net {
class FirstPartySetEntry;
class SchemefulSite;
} // namespace net
namespace content {
class BrowserContext;
// Class FirstPartySetsHandlerImplInstance is a singleton, it allows an embedder
// to provide First-Party Sets inputs from custom sources, then parses/merges
// the inputs to form the current First-Party Sets data, compares them with the
// persisted First-Party Sets data used during the last browser session to get
// a list of sites that changed the First-Party Set they are part of, invokes
// the provided callback with the current First-Party Sets data, and writes
// the current First-Party Sets data to disk.
class CONTENT_EXPORT FirstPartySetsHandlerImplInstance
: public FirstPartySetsHandlerImpl {
public:
~FirstPartySetsHandlerImplInstance() override;
FirstPartySetsHandlerImplInstance(const FirstPartySetsHandlerImplInstance&) =
delete;
FirstPartySetsHandlerImplInstance& operator=(
const FirstPartySetsHandlerImplInstance&) = delete;
// Factory method that exposes the ctor for testing.
static FirstPartySetsHandlerImplInstance CreateForTesting(
bool enabled,
bool embedder_will_provide_public_sets);
// FirstPartySetsHandlerImpl:
void Init(const base::FilePath& user_data_dir,
const net::LocalSetDeclaration& local_set) override;
[[nodiscard]] std::optional<net::GlobalFirstPartySets> GetSets(
base::OnceCallback<void(net::GlobalFirstPartySets)> callback) override;
// FirstPartySetsHandler:
bool IsEnabled() const override;
void SetPublicFirstPartySets(const base::Version& version,
base::File sets_file) override;
std::optional<net::FirstPartySetEntry> FindEntry(
const net::SchemefulSite& site,
const net::FirstPartySetsContextConfig& config) const override;
void GetContextConfigForPolicy(
base::optional_ref<const base::Value::Dict> policy,
base::OnceCallback<void(net::FirstPartySetsContextConfig)> callback)
override;
void ClearSiteDataOnChangedSetsForContext(
base::RepeatingCallback<BrowserContext*()> browser_context_getter,
const std::string& browser_context_id,
net::FirstPartySetsContextConfig context_config,
base::OnceCallback<void(net::FirstPartySetsContextConfig,
net::FirstPartySetsCacheFilter)> callback)
override;
void ComputeFirstPartySetMetadata(
const net::SchemefulSite& site,
base::optional_ref<const net::SchemefulSite> top_frame_site,
const net::FirstPartySetsContextConfig& config,
base::OnceCallback<void(net::FirstPartySetMetadata)> callback) override;
bool ForEachEffectiveSetEntry(
const net::FirstPartySetsContextConfig& config,
base::FunctionRef<bool(const net::SchemefulSite&,
const net::FirstPartySetEntry&)> f) const override;
void GetPersistedSetsForTesting(
const std::string& browser_context_id,
base::OnceCallback<
void(std::optional<std::pair<net::GlobalFirstPartySets,
net::FirstPartySetsContextConfig>>)>
callback);
void HasBrowserContextClearedForTesting(
const std::string& browser_context_id,
base::OnceCallback<void(std::optional<bool>)> callback);
void SynchronouslyResetDBHelperForTesting() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
db_helper_.SynchronouslyResetForTest(); // IN-TEST
}
private:
friend class base::NoDestructor<FirstPartySetsHandlerImplInstance>;
FirstPartySetsHandlerImplInstance(bool enabled,
bool embedder_will_provide_public_sets);
// Sets the global First-Party Sets data. Must be called exactly once.
void SetCompleteSets(net::GlobalFirstPartySets sets);
// Sets `db_helper_`, which will initialize the underlying First-Party Sets
// database under `user_data_dir`. Must be called exactly once.
void SetDatabase(const base::FilePath& user_data_dir);
// Enqueues a task to be performed once initialization is complete.
void EnqueuePendingTask(base::OnceClosure run_task);
// Invokes any pending queries.
void InvokePendingQueries();
// Returns the global First-Party Sets. This clones the underlying
// data.
//
// Must be called after the list has been initialized.
net::GlobalFirstPartySets GetGlobalSetsSync() const;
// Performs the actual state clearing for the given context. Must not be
// called until initialization is complete.
void ClearSiteDataOnChangedSetsForContextInternal(
base::RepeatingCallback<BrowserContext*()> browser_context_getter,
const std::string& browser_context_id,
net::FirstPartySetsContextConfig context_config,
base::OnceCallback<void(net::FirstPartySetsContextConfig,
net::FirstPartySetsCacheFilter)> callback);
// Like ComputeFirstPartySetMetadata, but passes the result into the provided
// callback. Must not be called before `global_sets_` has been set.
void ComputeFirstPartySetMetadataInternal(
const net::SchemefulSite& site,
base::optional_ref<const net::SchemefulSite> top_frame_site,
const net::FirstPartySetsContextConfig& config,
const base::ElapsedTimer& timer,
base::OnceCallback<void(net::FirstPartySetMetadata)> callback) const;
// Parses the policy and computes the config that represents the changes
// needed to apply `policy` to `global_sets_`.
net::FirstPartySetsContextConfig GetContextConfigForPolicyInternal(
const base::Value::Dict& policy,
base::optional_ref<const base::ElapsedTimer> timer) const;
void OnGetSitesToClear(
base::RepeatingCallback<BrowserContext*()> browser_context_getter,
const std::string& browser_context_id,
net::FirstPartySetsContextConfig context_config,
base::OnceCallback<void(net::FirstPartySetsContextConfig,
net::FirstPartySetsCacheFilter)> callback,
std::optional<std::pair<std::vector<net::SchemefulSite>,
net::FirstPartySetsCacheFilter>> sites_to_clear)
const;
// `failed_data_types` is a bitmask used to indicate data types from
// BrowsingDataRemover::DataType enum that were failed to remove. 0 indicates
// success.
void DidClearSiteDataOnChangedSetsForContext(
const std::string& browser_context_id,
net::FirstPartySetsContextConfig context_config,
net::FirstPartySetsCacheFilter cache_filter,
base::OnceCallback<void(net::FirstPartySetsContextConfig,
net::FirstPartySetsCacheFilter)> callback,
uint64_t failed_data_types) const;
// Whether Init has been called already or not.
bool initialized_ = false;
// The global First-Party Sets, after parsing and validation.
//
// This is nullopt until all of the required inputs have been received.
std::optional<net::GlobalFirstPartySets> global_sets_
GUARDED_BY_CONTEXT(sequence_checker_);
// Whether the First-Party Sets feature should behave as "enabled" or not,
// according to the embedder.
const bool enabled_ GUARDED_BY_CONTEXT(sequence_checker_);
// A queue of tasks waiting to run once this instance has the full
// GlobalFirstPartySets instance. If `enabled_` is true, then this queue is
// non-null until `global_sets_` is non-nullopt. Otherwise, it is always
// nullptr.
std::unique_ptr<base::circular_deque<base::OnceClosure>>
on_sets_ready_callbacks_ GUARDED_BY_CONTEXT(sequence_checker_);
// A helper object to handle loading and combining First-Party Sets from
// different sources (i.e. the command-line flag and the list provided by the
// embedder). This is nullptr if `enabled_` is false; and it is nullptr after
// `global_sets_` has been set.
std::unique_ptr<FirstPartySetsLoader> sets_loader_
GUARDED_BY_CONTEXT(sequence_checker_);
// Timer starting when the first async task was enqueued, if any. Used for
// metrics.
std::optional<base::ElapsedTimer> first_async_task_timer_
GUARDED_BY_CONTEXT(sequence_checker_);
// Access the underlying DB on a database sequence to make sure none of DB
// operations that support blocking are called directly on the main thread.
base::SequenceBound<FirstPartySetsHandlerDatabaseHelper> db_helper_;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace content
#endif // CONTENT_BROWSER_FIRST_PARTY_SETS_FIRST_PARTY_SETS_HANDLER_IMPL_INSTANCE_H_
|