[go: nahoru, domu]

blob: 69800147a797bbb4b4b1f66da37abd831e787789 [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 CONTENT_BROWSER_FIRST_PARTY_SETS_FIRST_PARTY_SETS_HANDLER_IMPL_H_
#define CONTENT_BROWSER_FIRST_PARTY_SETS_FIRST_PARTY_SETS_HANDLER_IMPL_H_
#include <string>
#include <utility>
#include "base/callback.h"
#include "base/containers/circular_deque.h"
#include "base/files/file.h"
#include "base/files/file_path.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/values.h"
#include "base/version.h"
#include "content/browser/first_party_sets/first_party_set_parser.h"
#include "content/browser/first_party_sets/first_party_sets_handler_database_helper.h"
#include "content/browser/first_party_sets/first_party_sets_loader.h"
#include "content/browser/first_party_sets/local_set_declaration.h"
#include "content/common/content_export.h"
#include "content/public/browser/first_party_sets_handler.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 "third_party/abseil-cpp/absl/types/optional.h"
namespace net {
class FirstPartySetEntry;
class SchemefulSite;
} // namespace net
namespace content {
class BrowserContext;
// Class FirstPartySetsHandlerImpl 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 FirstPartySetsHandlerImpl : public FirstPartySetsHandler {
public:
// The outcome types of clearing site data for data types covered in
// FirstPartySetsSiteDataRemover. We only clear
// `BrowsingDataRemover::DATA_TYPE_COOKIES` and
// `BrowsingDataRemover::DATA_TYPE_DOM_STORAGE` for now. Cache is "cleared"
// with a different approach.
//
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class ClearSiteDataOutcomeType {
kSuccess = 0,
// Failed to clear data type of `BrowsingDataRemover::DATA_TYPE_COOKIES`.
kCookieFailed = 1,
// Failed to clear data type of
// `BrowsingDataRemover::DATA_TYPE_DOM_STORAGE`.
kStorageFailed = 2,
// Failed to clear both `BrowsingDataRemover::DATA_TYPE_COOKIES` and
// `BrowsingDataRemover::DATA_TYPE_DOM_STORAGE` data types.
kCookieAndStorageFailed = 3,
kMaxValue = kCookieAndStorageFailed,
};
using SetsReadyOnceCallback =
base::OnceCallback<void(net::GlobalFirstPartySets)>;
static FirstPartySetsHandlerImpl* GetInstance();
~FirstPartySetsHandlerImpl() override;
FirstPartySetsHandlerImpl(const FirstPartySetsHandlerImpl&) = delete;
FirstPartySetsHandlerImpl& operator=(const FirstPartySetsHandlerImpl&) =
delete;
// This method reads the persisted First-Party Sets from the file under
// `user_data_dir` and sets the First-Party Set that was provided via the
// flag(s).
//
// If First-Party Sets is disabled, then this method still needs to read the
// persisted sets, since we may still need to clear data from a previous
// invocation of Chromium which had First-Party Sets enabled.
//
// Must be called exactly once.
void Init(const base::FilePath& user_data_dir,
const LocalSetDeclaration& local_set);
// Factory method that exposes the ctor for testing.
static FirstPartySetsHandlerImpl CreateForTesting(
bool enabled,
bool embedder_will_provide_public_sets);
// Returns the fully-parsed and validated global First-Party Sets data.
// Returns the data synchronously via an optional if it's already available,
// or via an asynchronously-invoked callback if the data is not ready yet.
//
// This function makes a clone of the underlying data.
//
// If `callback` is null, it will not be invoked, even if the First-Party Sets
// data is not ready yet.
//
// Must not be called if First-Party Sets is disabled.
[[nodiscard]] absl::optional<net::GlobalFirstPartySets> GetSets(
SetsReadyOnceCallback callback);
// FirstPartySetsHandler
bool IsEnabled() const override;
void SetPublicFirstPartySets(const base::Version& version,
base::File sets_file) override;
absl::optional<net::FirstPartySetEntry> FindEntry(
const net::SchemefulSite& site,
const net::FirstPartySetsContextConfig& config) const override;
void GetContextConfigForPolicy(
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,
const net::SchemefulSite* top_frame_site,
const std::set<net::SchemefulSite>& party_context,
const net::FirstPartySetsContextConfig& config,
base::OnceCallback<void(net::FirstPartySetMetadata)> callback) override;
void GetPersistedGlobalSetsForTesting(
const std::string& browser_context_id,
base::OnceCallback<void(absl::optional<net::GlobalFirstPartySets>)>
callback);
void HasBrowserContextClearedForTesting(
const std::string& browser_context_id,
base::OnceCallback<void(absl::optional<bool>)> callback);
void SynchronouslyResetDBHelperForTesting() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
db_helper_.SynchronouslyResetForTest(); // IN-TEST
}
// Computes information needed by the FirstPartySetsAccessDelegate in order
// to update the browser's list of First-Party Sets to respect a profile's
// setting for the per-profile FirstPartySetsOverrides policy.
static net::FirstPartySetsContextConfig ComputeEnterpriseContextConfig(
const net::GlobalFirstPartySets& browser_sets,
const FirstPartySetParser::ParsedPolicySetLists& policy);
private:
friend class base::NoDestructor<FirstPartySetsHandlerImpl>;
FirstPartySetsHandlerImpl(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);
// 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,
const absl::optional<net::SchemefulSite>& top_frame_site,
const std::set<net::SchemefulSite>& party_context,
const net::FirstPartySetsContextConfig& config,
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) 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::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.
absl::optional<net::GlobalFirstPartySets> global_sets_
GUARDED_BY_CONTEXT(sequence_checker_);
bool enabled_ GUARDED_BY_CONTEXT(sequence_checker_);
bool embedder_will_provide_public_sets_ GUARDED_BY_CONTEXT(sequence_checker_);
// We use a OnceCallback to ensure we only pass along the sets once
// during Chrome's lifetime (modulo reconfiguring the network service).
base::circular_deque<base::OnceClosure> on_sets_ready_callbacks_
GUARDED_BY_CONTEXT(sequence_checker_);
std::unique_ptr<FirstPartySetsLoader> sets_loader_
GUARDED_BY_CONTEXT(sequence_checker_);
// Timer starting when the instance is constructed. Used for metrics.
base::ElapsedTimer construction_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_H_