[privacy_budget] Move base identifiability settings to //chrome/common.
These settings are directly controlled via feature flags and field trials. On the browser, they are used to filter out surfaces that should be excluded from the study. Such exclusions are meant as a privacy measure. On the renderer, they are used to prevent specific surfaces from being sampled in the first place. Such an exclusion is meant as a granular kill switch to account for unforeseen adverse effects of the act of sampling a surface. Browser-side filtering of reported data cannot address such issues. Directory layout including per-directory division of responsibilities is now described in //docs/privacy_budget_code_locations.md. Bug: 973801 Change-Id: Id0ba366a4f5625a59d5b40031d80764d3584a892 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2232892 Reviewed-by: John Abd-El-Malek <jam@chromium.org> Reviewed-by: Caleb Raitto <caraitto@chromium.org> Reviewed-by: Paul Jensen <pauljensen@chromium.org> Commit-Queue: Asanka Herath <asanka@chromium.org> Cr-Commit-Position: refs/heads/master@{#782006}
This commit is contained in:

committed by
Commit Bot

parent
b8ef830538
commit
d1b93008f1
chrome
browser
privacy_budget
common
BUILD.gn
privacy_budget
BUILD.gnDEPSOWNERSREADME.mdcontainer_ops.hcontainer_ops_unittest.ccfield_trial_param_conversions.ccfield_trial_param_conversions.hfield_trial_param_conversions_unittest.ccprivacy_budget_features.ccprivacy_budget_features.hprivacy_budget_settings_provider.ccprivacy_budget_settings_provider.hscoped_privacy_budget_config.ccscoped_privacy_budget_config.h
test
docs
third_party/blink
@ -2,22 +2,16 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//testing/test.gni")
|
||||
|
||||
source_set("privacy_budget") {
|
||||
sources = [
|
||||
"container_ops.h",
|
||||
"field_trial_param_conversions.cc",
|
||||
"field_trial_param_conversions.h",
|
||||
"identifiability_study_state.cc",
|
||||
"identifiability_study_state.h",
|
||||
"privacy_budget_features.cc",
|
||||
"privacy_budget_features.h",
|
||||
"privacy_budget_prefs.cc",
|
||||
"privacy_budget_prefs.h",
|
||||
"privacy_budget_ukm_entry_filter.cc",
|
||||
"privacy_budget_ukm_entry_filter.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//services/metrics/public/cpp:metrics_cpp",
|
||||
@ -29,24 +23,15 @@ source_set("privacy_budget") {
|
||||
|
||||
source_set("unit_tests") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"container_ops_unittest.cc",
|
||||
"field_trial_param_conversions_unittest.cc",
|
||||
"identifiability_study_state_unittest.cc",
|
||||
"privacy_budget_ukm_entry_filter_unittest.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":test_support",
|
||||
"//chrome/common/privacy_budget:test_support",
|
||||
"//chrome/test:test_support",
|
||||
"//testing/gtest",
|
||||
]
|
||||
}
|
||||
|
||||
static_library("test_support") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"scoped_privacy_budget_config.cc",
|
||||
"scoped_privacy_budget_config.h",
|
||||
]
|
||||
deps = [ "//base/test:test_support" ]
|
||||
}
|
||||
|
5
chrome/browser/privacy_budget/README.md
Normal file
5
chrome/browser/privacy_budget/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Privacy Budget: Persistent Study State and Reporting
|
||||
|
||||
See [Privacy Budget: Code
|
||||
Locations](../../../docs/privacy_budget_code_locations.md) for
|
||||
details.
|
@ -12,6 +12,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/metrics/crc32.h"
|
||||
@ -23,10 +24,10 @@
|
||||
#include "base/strings/string_piece_forward.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "chrome/browser/privacy_budget/container_ops.h"
|
||||
#include "chrome/browser/privacy_budget/field_trial_param_conversions.h"
|
||||
#include "chrome/browser/privacy_budget/privacy_budget_features.h"
|
||||
#include "chrome/browser/privacy_budget/privacy_budget_prefs.h"
|
||||
#include "chrome/common/privacy_budget/container_ops.h"
|
||||
#include "chrome/common/privacy_budget/field_trial_param_conversions.h"
|
||||
#include "chrome/common/privacy_budget/privacy_budget_features.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
|
||||
|
||||
@ -37,24 +38,16 @@ constexpr size_t kMruEntries = 1000;
|
||||
|
||||
} // namespace
|
||||
|
||||
constexpr int IdentifiabilityStudyState::kMaxSampledIdentifiableSurfaces;
|
||||
constexpr int IdentifiabilityStudyState::kMaxSamplingRateDenominator;
|
||||
constexpr int IdentifiabilityStudyState::kImplementationVersion;
|
||||
constexpr int IdentifiabilityStudyState::kGeneratorVersion;
|
||||
|
||||
IdentifiabilityStudyState::IdentifiabilityStudyState(PrefService* pref_service)
|
||||
: pref_service_(pref_service),
|
||||
generation_(features::kIdentifiabilityStudyGeneration.Get()),
|
||||
recent_surfaces_(kMruEntries),
|
||||
blocked_surfaces_(
|
||||
DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceSet>(
|
||||
features::kIdentifiabilityStudyBlockedMetrics.Get())),
|
||||
blocked_types_(
|
||||
DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceTypeSet>(
|
||||
features::kIdentifiabilityStudyBlockedTypes.Get())),
|
||||
surface_selection_rate_(base::ClampToRange<int>(
|
||||
features::kIdentifiabilityStudySurfaceSelectionRate.Get(),
|
||||
0,
|
||||
kMaxSamplingRateDenominator)),
|
||||
features::kMaxIdentifiabilityStudySurfaceSelectionRate)),
|
||||
per_surface_selection_rates_(
|
||||
DecodeIdentifiabilityFieldTrialParam<SurfaceSelectionRateMap>(
|
||||
features::kIdentifiabilityStudyPerSurfaceSettings.Get())),
|
||||
@ -64,12 +57,7 @@ IdentifiabilityStudyState::IdentifiabilityStudyState(PrefService* pref_service)
|
||||
max_active_surfaces_(base::ClampToRange<int>(
|
||||
features::kIdentifiabilityStudyMaxSurfaces.Get(),
|
||||
0,
|
||||
kMaxSampledIdentifiableSurfaces)),
|
||||
|
||||
// In practice there's really no point in enabling the feature with a max
|
||||
// active surface count of 0.
|
||||
enabled_(base::FeatureList::IsEnabled(features::kIdentifiabilityStudy) &&
|
||||
max_active_surfaces_ > 0) {
|
||||
features::kMaxIdentifiabilityStudyMaxSurfaces)) {
|
||||
InitFromPrefs();
|
||||
}
|
||||
|
||||
@ -82,7 +70,7 @@ int IdentifiabilityStudyState::generation() const {
|
||||
bool IdentifiabilityStudyState::ShouldSampleSurface(
|
||||
blink::IdentifiableSurface surface) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
if (!enabled())
|
||||
if (LIKELY(!IsActive()))
|
||||
return false;
|
||||
|
||||
if (base::Contains(active_surfaces_, surface))
|
||||
@ -98,15 +86,10 @@ bool IdentifiabilityStudyState::ShouldSampleSurface(
|
||||
if (recent_it != recent_surfaces_.end())
|
||||
return recent_it->second;
|
||||
|
||||
// By construction, there's no intersection between blocked_surfaces_ and
|
||||
// active_surfaces_. Hence we can check blocked_surfaces_ after
|
||||
// active_surfaces_.
|
||||
if (base::Contains(blocked_surfaces_, surface)) {
|
||||
recent_surfaces_.Put(surface, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (base::Contains(blocked_types_, surface.GetType())) {
|
||||
// By construction, there's no intersection between blocked and
|
||||
// `active_surfaces_`. Hence we can check for blocked surfaces after checking
|
||||
// `active_surfaces_`.
|
||||
if (IsSurfaceBlocked(surface)) {
|
||||
recent_surfaces_.Put(surface, false);
|
||||
return false;
|
||||
}
|
||||
@ -125,8 +108,7 @@ bool IdentifiabilityStudyState::ShouldSampleSurface(
|
||||
|
||||
bool IdentifiabilityStudyState::IsSurfaceBlocked(
|
||||
blink::IdentifiableSurface surface) const {
|
||||
return base::Contains(blocked_surfaces_, surface) ||
|
||||
base::Contains(blocked_types_, surface.GetType());
|
||||
return !settings_.IsSurfaceAllowed(surface);
|
||||
}
|
||||
|
||||
bool IdentifiabilityStudyState::DecideSurfaceInclusion(
|
||||
@ -167,13 +149,13 @@ bool IdentifiabilityStudyState::DecideSurfaceInclusion(
|
||||
#if DCHECK_IS_ON()
|
||||
void IdentifiabilityStudyState::CheckInvariants() const {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
DCHECK(!internal::Intersects(active_surfaces_, blocked_surfaces_));
|
||||
DCHECK(!internal::Intersects(active_surfaces_, settings_.blocked_surfaces()));
|
||||
DCHECK(!internal::Intersects(active_surfaces_, retired_surfaces_));
|
||||
DCHECK(active_surfaces_.size() <= max_active_surfaces_);
|
||||
DCHECK(!std::any_of(active_surfaces_.begin(), active_surfaces_.end(),
|
||||
[&](const auto& value) {
|
||||
return base::Contains(blocked_types_, value.GetType());
|
||||
}));
|
||||
DCHECK(std::all_of(active_surfaces_.begin(), active_surfaces_.end(),
|
||||
[&](const auto& value) {
|
||||
return settings_.IsTypeAllowed(value.GetType());
|
||||
}));
|
||||
}
|
||||
#else // DCHECK_IS_ON()
|
||||
void IdentifiabilityStudyState::CheckInvariants() const {}
|
||||
@ -185,7 +167,7 @@ void IdentifiabilityStudyState::InitFromPrefs() {
|
||||
DCHECK(retired_surfaces_.empty());
|
||||
|
||||
// None of the parameters should be relied upon if the study is not enabled.
|
||||
if (!enabled_)
|
||||
if (LIKELY(!IsActive()))
|
||||
return;
|
||||
|
||||
auto persisted_generation =
|
||||
|
@ -5,13 +5,12 @@
|
||||
#ifndef CHROME_BROWSER_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_STATE_H_
|
||||
#define CHROME_BROWSER_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_STATE_H_
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include "base/containers/mru_cache.h"
|
||||
#include "base/sequence_checker.h"
|
||||
#include "base/strings/string_piece_forward.h"
|
||||
#include "base/thread_annotations.h"
|
||||
#include "chrome/browser/privacy_budget/privacy_budget_prefs.h"
|
||||
#include "chrome/common/privacy_budget/privacy_budget_settings_provider.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
|
||||
#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
|
||||
@ -20,10 +19,24 @@ namespace test_utils {
|
||||
class InspectableIdentifiabilityStudySettings;
|
||||
} // namespace test_utils
|
||||
|
||||
// Current state of the identifiability study.
|
||||
//
|
||||
// Persists mutable state in a `PrefService`. This state includes:
|
||||
//
|
||||
// * Which identifiable surfaces are "active". I.e. currently being recorded.
|
||||
//
|
||||
// * Which identifiable surfaces are "retired". I.e. was active at some point
|
||||
// but was demoted due to some reason. Typically this happens if an active
|
||||
// surface is blocked by a settings change. These are kept around in order to
|
||||
// minimize the total number of surfaces that we record per client.
|
||||
//
|
||||
// * The PRNG seed that we use for various pseudo-random operations.
|
||||
//
|
||||
// * The study generation.
|
||||
class IdentifiabilityStudyState {
|
||||
public:
|
||||
// Construct from a PrefService. |pref_service| is used to retrieve and store
|
||||
// study parameters.
|
||||
// Construct from a PrefService. `pref_service` is used to retrieve and store
|
||||
// study state.
|
||||
explicit IdentifiabilityStudyState(PrefService* pref_service);
|
||||
|
||||
IdentifiabilityStudyState(IdentifiabilityStudyState&) = delete;
|
||||
@ -36,15 +49,15 @@ class IdentifiabilityStudyState {
|
||||
//
|
||||
// A client (i.e. a browser instance) participates in the study if all of the
|
||||
// following are true:
|
||||
// * |kIdentifiabilityStudy| feature is enabled.
|
||||
// * |kMaxSampledIdentifiableSurfaces| is non-zero.
|
||||
// * `kIdentifiabilityStudy` feature is enabled.
|
||||
// * `kIdentifiabilityStudyMaxSurfaces` is non-zero.
|
||||
//
|
||||
// In addition, none of this is relevant if UKM collection is disabled for the
|
||||
// client. If that was the case, this class would not be instantiated in the
|
||||
// first place.
|
||||
bool enabled() const { return enabled_; }
|
||||
bool IsActive() const { return settings_.IsActive(); }
|
||||
|
||||
// Returns the experiment generation as defined by the server-side
|
||||
// Returns the active experiment generation as defined by the server-side
|
||||
// configuration.
|
||||
//
|
||||
// The study generation is specified as part of the study configuration
|
||||
@ -53,23 +66,15 @@ class IdentifiabilityStudyState {
|
||||
// of study settings.
|
||||
int generation() const;
|
||||
|
||||
// Returns true if metrics collection is enabled for |surface|.
|
||||
// Returns true if metrics collection is enabled for `surface`.
|
||||
//
|
||||
// Calling this method may alter the state of the study settings.
|
||||
bool ShouldSampleSurface(blink::IdentifiableSurface surface);
|
||||
|
||||
// Returns true if the |surface| is blocked by configuration. Does not take
|
||||
// Returns true if the `surface` is blocked by configuration. Does not take
|
||||
// into account whether the surface is included in the study or not.
|
||||
bool IsSurfaceBlocked(blink::IdentifiableSurface surface) const;
|
||||
|
||||
// This is a hard coded maximum for the number of identifiable surfaces that
|
||||
// can be reported for a user. The actual ceiling for active surfaces cannot
|
||||
// exceed this value even if it's sent via a server-side configuration.
|
||||
static constexpr int kMaxSampledIdentifiableSurfaces = 10;
|
||||
|
||||
// Largest meaningful sampling denominator. Picked out of hat.
|
||||
static constexpr int kMaxSamplingRateDenominator = 1000000;
|
||||
|
||||
// A knob that we can use to split data sets from different versions of the
|
||||
// implementation where the differences could have material effects on the
|
||||
// data distribution.
|
||||
@ -77,16 +82,15 @@ class IdentifiabilityStudyState {
|
||||
// Should be incremented whenever a non-backwards-compatible change is made in
|
||||
// the code. This value is independent of any server controlled study
|
||||
// parameters.
|
||||
static constexpr int kImplementationVersion = 1;
|
||||
static constexpr int kGeneratorVersion = 1;
|
||||
|
||||
private:
|
||||
friend class test_utils::InspectableIdentifiabilityStudySettings;
|
||||
|
||||
using IdentifiableSurfaceSet =
|
||||
std::unordered_set<blink::IdentifiableSurface,
|
||||
blink::IdentifiableSurfaceHash>;
|
||||
PrivacyBudgetSettingsProvider::IdentifiableSurfaceSet;
|
||||
using IdentifiableSurfaceTypeSet =
|
||||
std::unordered_set<blink::IdentifiableSurface::Type>;
|
||||
PrivacyBudgetSettingsProvider::IdentifiableSurfaceTypeSet;
|
||||
using SurfaceSelectionRateMap =
|
||||
base::flat_map<blink::IdentifiableSurface,
|
||||
int,
|
||||
@ -101,10 +105,10 @@ class IdentifiabilityStudyState {
|
||||
// expensive. Noop otherwise.
|
||||
void CheckInvariants() const;
|
||||
|
||||
// Initialize from fields persisted in |pref_service_|.
|
||||
// Initialize from fields persisted in `pref_service_`.
|
||||
void InitFromPrefs();
|
||||
|
||||
// Write active and retired lists to |pref_service_|.
|
||||
// Write active and retired lists to `pref_service_`.
|
||||
void WriteToPrefs();
|
||||
|
||||
// Invoked at the start of the session after loading persisted active and
|
||||
@ -137,26 +141,28 @@ class IdentifiabilityStudyState {
|
||||
// Set of identifiable surfaces for which we will collect metrics. This set is
|
||||
// updated as we go unless it is already saturated.
|
||||
//
|
||||
// The set is considered saturated when the size is |max_active_surfaces_|.
|
||||
// The set is considered saturated when the size is `max_active_surfaces_`.
|
||||
//
|
||||
// Invariants:
|
||||
//
|
||||
// * |active_surfaces_| ∩ |blocked_surfaces_| = Ø.
|
||||
// * active_surfaces_ ∩ settings_.blocked_surfaces() = Ø.
|
||||
//
|
||||
// * |active_surfaces_| ∩ |retired_surfaces_| = Ø.
|
||||
// * active_surfaces_.GetType() ∩ settings_.blocked_types() = Ø.
|
||||
//
|
||||
// * |active_surfaces_.size()| ≤ |max_active_surfaces_|.
|
||||
// * active_surfaces_ ∩ retired_surfaces_ = Ø.
|
||||
//
|
||||
// * active_surfaces_.size() ≤ max_active_surfaces_.
|
||||
//
|
||||
IdentifiableSurfaceSet active_surfaces_;
|
||||
|
||||
// Set of identifiable surfaces that were once in the |active_surfaces_| set,
|
||||
// Set of identifiable surfaces that were once in the `active_surfaces_` set,
|
||||
// but are no longer.
|
||||
//
|
||||
// If |max_active_surfaces_| falls below the size of |allowed_surfaces_|, then
|
||||
// If `max_active_surfaces_` falls below the size of `allowed_surfaces_`, then
|
||||
// rather than drop the extra surfaces, they are moved here. If the
|
||||
// |max_active_surfaces_| increases again, then this class moves as many
|
||||
// surfaces as viable from this set to |active_surfaces_| subject to
|
||||
// |blocked_surfaces_|.
|
||||
// `max_active_surfaces_` increases again, then this class moves as many
|
||||
// surfaces as viable from this set to `active_surfaces_` subject to
|
||||
// `blocked_surfaces_`.
|
||||
//
|
||||
// This list persists throughout the lifetime of a UKM client ID and counts
|
||||
// towards the cumulative number of surfaces that has been associated with a
|
||||
@ -165,7 +171,7 @@ class IdentifiabilityStudyState {
|
||||
//
|
||||
// Invariants:
|
||||
//
|
||||
// * |active_surfaces_| ∩ |retired_surfaces_| = Ø.
|
||||
// * active_surfaces_ ∩ retired_surfaces_ = Ø.
|
||||
IdentifiableSurfaceSet retired_surfaces_;
|
||||
|
||||
// Cache for accelerating lookups for frequently encountered surfaces. The
|
||||
@ -175,56 +181,39 @@ class IdentifiabilityStudyState {
|
||||
blink::IdentifiableSurfaceHash>
|
||||
recent_surfaces_;
|
||||
|
||||
// Set of identifiable surfaces for which we will NOT collect metrics. This
|
||||
// list is server controlled.
|
||||
//
|
||||
// Invariants:
|
||||
//
|
||||
// * |active_surfaces_| ∩ |blocked_surfaces_| = Ø.
|
||||
const IdentifiableSurfaceSet blocked_surfaces_;
|
||||
|
||||
// Set of identifiable surface types for which we will NOT collect metrics.
|
||||
// This list is server controlled.
|
||||
//
|
||||
// Invariants:
|
||||
//
|
||||
// * For ∀ s ∈ |active_surfaces_|, s.Type ∉ |blocked_types_|.
|
||||
const IdentifiableSurfaceTypeSet blocked_types_;
|
||||
|
||||
// Root denominator of the rate of surface selection. Numerator is always 1.
|
||||
// Thus, given a new surface s that is not in |active_surfaces_| nor
|
||||
// |blocked_surfaces_|, the probability of that surface being added to
|
||||
// |active_surfaces_| is:
|
||||
// Thus, given a new surface s that is not in `active_surfaces_` nor
|
||||
// `blocked_surfaces_`, the probability of that surface being added to
|
||||
// `active_surfaces_` is:
|
||||
//
|
||||
// 1
|
||||
// 𝛲𝒓(surface s being added to the study) = ━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// |surface_selection_rate_|
|
||||
// 𝛲𝒓(surface s being added to the study) = ━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// surface_selection_rate_
|
||||
//
|
||||
// If |surface_selection_rate_| is 0, then it is considered the same as a
|
||||
// If `surface_selection_rate_` is 0, then it is considered the same as a
|
||||
// probability of zero.
|
||||
const int surface_selection_rate_ = 0;
|
||||
|
||||
// Per surface custom selection rates. The effective selection probability for
|
||||
// a surface is the |per_surface_selection_rates_[surface]| if it is defined.
|
||||
// Otherwise defaults to |surface_selection_rate_|
|
||||
// a surface is the `per_surface_selection_rates_[surface]` if it is defined.
|
||||
// Otherwise defaults to `surface_selection_rate_`
|
||||
const SurfaceSelectionRateMap per_surface_selection_rates_;
|
||||
|
||||
// Per surface *type* custom selection rates. Interpreted the same as
|
||||
// |per_surface_selection_rates_| except the surface type is used for lookup.
|
||||
// `per_surface_selection_rates_` except the surface type is used for lookup.
|
||||
const TypeSelectionRateMap per_type_selection_rates_;
|
||||
|
||||
// Hard cap on the number of identifiable surfaces we will sample per client.
|
||||
// This setting can be tweaked experimentally via
|
||||
// |kIdentifiabilityStudyMaxSurfaces|.
|
||||
// `kIdentifiabilityStudyMaxSurfaces`.
|
||||
//
|
||||
// Invariants:
|
||||
//
|
||||
// * |max_active_surfaces_| ≤ |kMaxSampledIdentifiableSurfaces|.
|
||||
// * max_active_surfaces_ ≤ kIdentifiabilityStudyMaxSurfaces.
|
||||
const size_t max_active_surfaces_;
|
||||
|
||||
// True if identifiability study is enabled. If this field is false, then none
|
||||
// of the other values are applicable.
|
||||
const bool enabled_ = false;
|
||||
// Overall study state and per-surface and per-type blocking.
|
||||
const PrivacyBudgetSettingsProvider settings_;
|
||||
|
||||
SEQUENCE_CHECKER(sequence_checker_);
|
||||
};
|
||||
|
@ -12,7 +12,8 @@
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "chrome/browser/privacy_budget/privacy_budget_prefs.h"
|
||||
#include "chrome/browser/privacy_budget/scoped_privacy_budget_config.h"
|
||||
#include "chrome/common/privacy_budget/privacy_budget_features.h"
|
||||
#include "chrome/common/privacy_budget/scoped_privacy_budget_config.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/prefs/testing_pref_service.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
@ -227,19 +228,18 @@ TEST_F(IdentifiabilityStudySettingsTest, UpdatesActive) {
|
||||
// Verify that the study parameters don't overflow.
|
||||
TEST(IdentifiabilityStudySettingsStandaloneTest, HighClamps) {
|
||||
auto params = test::ScopedPrivacyBudgetConfig::Parameters{};
|
||||
params.max_surfaces =
|
||||
IdentifiabilityStudyState::kMaxSampledIdentifiableSurfaces + 1;
|
||||
params.max_surfaces = features::kMaxIdentifiabilityStudyMaxSurfaces + 1;
|
||||
params.surface_selection_rate =
|
||||
IdentifiabilityStudyState::kMaxSamplingRateDenominator + 1;
|
||||
features::kMaxIdentifiabilityStudySurfaceSelectionRate + 1;
|
||||
test::ScopedPrivacyBudgetConfig config(params);
|
||||
|
||||
TestingPrefServiceSimple pref_service;
|
||||
prefs::RegisterPrivacyBudgetPrefs(pref_service.registry());
|
||||
test_utils::InspectableIdentifiabilityStudySettings settings(&pref_service);
|
||||
|
||||
EXPECT_EQ(IdentifiabilityStudyState::kMaxSampledIdentifiableSurfaces,
|
||||
EXPECT_EQ(features::kMaxIdentifiabilityStudyMaxSurfaces,
|
||||
settings.max_active_surfaces());
|
||||
EXPECT_EQ(IdentifiabilityStudyState::kMaxSamplingRateDenominator,
|
||||
EXPECT_EQ(features::kMaxIdentifiabilityStudySurfaceSelectionRate,
|
||||
settings.surface_selection_rate());
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ TEST(IdentifiabilityStudySettingsStandaloneTest, Disabled) {
|
||||
prefs::RegisterPrivacyBudgetPrefs(pref_service.registry());
|
||||
test_utils::InspectableIdentifiabilityStudySettings settings(&pref_service);
|
||||
|
||||
EXPECT_FALSE(settings.enabled());
|
||||
EXPECT_FALSE(settings.IsActive());
|
||||
EXPECT_FALSE(settings.ShouldSampleSurface(kRegularSurface1));
|
||||
EXPECT_FALSE(settings.ShouldSampleSurface(kRegularSurface2));
|
||||
EXPECT_FALSE(settings.ShouldSampleSurface(kRegularSurface3));
|
||||
|
@ -2,4 +2,4 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/browser/privacy_budget/container_ops.h"
|
||||
#include "chrome/common/privacy_budget/container_ops.h"
|
||||
|
@ -9,16 +9,19 @@
|
||||
|
||||
namespace prefs {
|
||||
|
||||
// Pref used for persisting |IdentifiabilityStudySettings::active_surfaces_|.
|
||||
// See documentation for IdentifiabilityStudyState for details on how these
|
||||
// values are used.
|
||||
|
||||
// Pref used for persisting |IdentifiabilityStudyState::active_surfaces_|.
|
||||
extern const char kPrivacyBudgetActiveSurfaces[];
|
||||
|
||||
// Pref used for persisting |IdentifiabilityStudySettings::retired_surfaces_|.
|
||||
// Pref used for persisting |IdentifiabilityStudyState::retired_surfaces_|.
|
||||
extern const char kPrivacyBudgetRetiredSurfaces[];
|
||||
|
||||
// Pref used for persisting |IdentifiabilityStudySettings::prng_seed_|.
|
||||
// Pref used for persisting |IdentifiabilityStudyState::prng_seed_|.
|
||||
extern const char kPrivacyBudgetSeed[];
|
||||
|
||||
// Pref used for persisting |IdentifiabilityStudySettings::generation_|.
|
||||
// Pref used for persisting |IdentifiabilityStudyState::generation_|.
|
||||
extern const char kPrivacyBudgetGeneration[];
|
||||
|
||||
void RegisterPrivacyBudgetPrefs(PrefRegistrySimple* registry);
|
||||
|
@ -13,13 +13,13 @@
|
||||
#include "services/metrics/public/mojom/ukm_interface.mojom.h"
|
||||
|
||||
PrivacyBudgetUkmEntryFilter::PrivacyBudgetUkmEntryFilter(
|
||||
IdentifiabilityStudyState* settings)
|
||||
: identifiability_study_settings_(settings) {}
|
||||
IdentifiabilityStudyState* state)
|
||||
: identifiability_study_state_(state) {}
|
||||
|
||||
bool PrivacyBudgetUkmEntryFilter::FilterEntry(
|
||||
ukm::mojom::UkmEntry* entry,
|
||||
base::flat_set<uint64_t>* removed_metric_hashes) const {
|
||||
const bool enabled = identifiability_study_settings_->enabled();
|
||||
const bool enabled = identifiability_study_state_->IsActive();
|
||||
|
||||
// We don't yet deal with any event other than Identifiability. All other
|
||||
// types of events pass through.
|
||||
@ -31,7 +31,7 @@ bool PrivacyBudgetUkmEntryFilter::FilterEntry(
|
||||
return false;
|
||||
|
||||
base::EraseIf(entry->metrics, [&](auto metric) {
|
||||
return !identifiability_study_settings_->ShouldSampleSurface(
|
||||
return !identifiability_study_state_->ShouldSampleSurface(
|
||||
blink::IdentifiableSurface::FromMetricHash(metric.first));
|
||||
});
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
class PrivacyBudgetUkmEntryFilter : public ukm::UkmEntryFilter {
|
||||
public:
|
||||
// |settings| must outlive PrivacyBudgetUkmEntryFilter.
|
||||
explicit PrivacyBudgetUkmEntryFilter(IdentifiabilityStudyState* settings);
|
||||
explicit PrivacyBudgetUkmEntryFilter(IdentifiabilityStudyState* state);
|
||||
|
||||
PrivacyBudgetUkmEntryFilter(const PrivacyBudgetUkmEntryFilter&) = delete;
|
||||
PrivacyBudgetUkmEntryFilter& operator=(const PrivacyBudgetUkmEntryFilter&) =
|
||||
@ -29,7 +29,7 @@ class PrivacyBudgetUkmEntryFilter : public ukm::UkmEntryFilter {
|
||||
base::flat_set<uint64_t>* removed_metric_hashes) const override;
|
||||
|
||||
private:
|
||||
IdentifiabilityStudyState* const identifiability_study_settings_;
|
||||
IdentifiabilityStudyState* const identifiability_study_state_;
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_PRIVACY_BUDGET_PRIVACY_BUDGET_UKM_ENTRY_FILTER_H_
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "base/containers/flat_map.h"
|
||||
#include "base/template_util.h"
|
||||
#include "chrome/browser/privacy_budget/scoped_privacy_budget_config.h"
|
||||
#include "chrome/common/privacy_budget/scoped_privacy_budget_config.h"
|
||||
#include "components/prefs/testing_pref_service.h"
|
||||
#include "services/metrics/public/cpp/ukm_builders.h"
|
||||
#include "services/metrics/public/mojom/ukm_interface.mojom.h"
|
||||
|
@ -184,6 +184,7 @@ static_library("common") {
|
||||
"//chrome/app/theme:theme_resources",
|
||||
"//chrome/common:constants",
|
||||
"//chrome/common/net",
|
||||
"//chrome/common/privacy_budget",
|
||||
"//chrome/common/profiler",
|
||||
"//chrome/common/qr_code_generator",
|
||||
"//chrome/common/search:mojo_bindings",
|
||||
|
50
chrome/common/privacy_budget/BUILD.gn
Normal file
50
chrome/common/privacy_budget/BUILD.gn
Normal file
@ -0,0 +1,50 @@
|
||||
# Copyright 2020 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.
|
||||
|
||||
source_set("privacy_budget") {
|
||||
sources = [
|
||||
"container_ops.h",
|
||||
"field_trial_param_conversions.cc",
|
||||
"field_trial_param_conversions.h",
|
||||
"privacy_budget_features.cc",
|
||||
"privacy_budget_features.h",
|
||||
"privacy_budget_settings_provider.cc",
|
||||
"privacy_budget_settings_provider.h",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
"//base",
|
||||
"//third_party/blink/public/common",
|
||||
]
|
||||
}
|
||||
|
||||
source_set("unit_tests") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"container_ops_unittest.cc",
|
||||
"field_trial_param_conversions_unittest.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":privacy_budget",
|
||||
"//base",
|
||||
"//testing/gtest",
|
||||
]
|
||||
}
|
||||
|
||||
source_set("test_support") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"scoped_privacy_budget_config.cc",
|
||||
"scoped_privacy_budget_config.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":privacy_budget",
|
||||
"//base/test:test_support",
|
||||
"//third_party/blink/public/common/privacy_budget",
|
||||
]
|
||||
}
|
3
chrome/common/privacy_budget/DEPS
Normal file
3
chrome/common/privacy_budget/DEPS
Normal file
@ -0,0 +1,3 @@
|
||||
include_rules = [
|
||||
"+third_party/blink/public/common/privacy_budget"
|
||||
]
|
4
chrome/common/privacy_budget/OWNERS
Normal file
4
chrome/common/privacy_budget/OWNERS
Normal file
@ -0,0 +1,4 @@
|
||||
file://third_party/blink/public/common/privacy_budget/OWNERS
|
||||
|
||||
# TEAM: privacy-sandbox-dev@chromium.org
|
||||
# COMPONENT: Privacy>Fingerprinting
|
6
chrome/common/privacy_budget/README.md
Normal file
6
chrome/common/privacy_budget/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Privacy Budget: Static Study Settings
|
||||
|
||||
See [Privacy Budget: Code
|
||||
Locations](../../../docs/privacy_budget_code_locations.md) for
|
||||
details.
|
||||
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_PRIVACY_BUDGET_CONTAINER_OPS_H_
|
||||
#define CHROME_BROWSER_PRIVACY_BUDGET_CONTAINER_OPS_H_
|
||||
#ifndef CHROME_COMMON_PRIVACY_BUDGET_CONTAINER_OPS_H_
|
||||
#define CHROME_COMMON_PRIVACY_BUDGET_CONTAINER_OPS_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
@ -80,4 +80,4 @@ bool Intersects(const T& left, const T& right) {
|
||||
|
||||
} // namespace internal
|
||||
|
||||
#endif // CHROME_BROWSER_PRIVACY_BUDGET_CONTAINER_OPS_H_
|
||||
#endif // CHROME_COMMON_PRIVACY_BUDGET_CONTAINER_OPS_H_
|
@ -2,9 +2,10 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/browser/privacy_budget/container_ops.h"
|
||||
#include <set>
|
||||
|
||||
#include "chrome/common/privacy_budget/container_ops.h"
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace internal {
|
@ -2,7 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/browser/privacy_budget/field_trial_param_conversions.h"
|
||||
#include "chrome/common/privacy_budget/field_trial_param_conversions.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
bool DecodeIdentifiabilityType(const base::StringPiece s,
|
@ -2,16 +2,17 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_PRIVACY_BUDGET_FIELD_TRIAL_PARAM_CONVERSIONS_H_
|
||||
#define CHROME_BROWSER_PRIVACY_BUDGET_FIELD_TRIAL_PARAM_CONVERSIONS_H_
|
||||
#ifndef CHROME_COMMON_PRIVACY_BUDGET_FIELD_TRIAL_PARAM_CONVERSIONS_H_
|
||||
#define CHROME_COMMON_PRIVACY_BUDGET_FIELD_TRIAL_PARAM_CONVERSIONS_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "base/notreached.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_piece.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "chrome/browser/privacy_budget/identifiability_study_state.h"
|
||||
#include "chrome/common/privacy_budget/privacy_budget_features.h"
|
||||
#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
|
||||
|
||||
// The Encode/Decode families of functions are meant to be used to encode
|
||||
@ -43,14 +44,14 @@ std::pair<V, bool> DecodeIdentifiabilityTypePair(base::StringPiece s) {
|
||||
base::SplitResult::SPLIT_WANT_NONEMPTY);
|
||||
if (pieces.size() != 2)
|
||||
return {V(), false};
|
||||
P from;
|
||||
int to;
|
||||
if (!DecodeIdentifiabilityType(pieces[0], &from) ||
|
||||
!base::StringToInt(pieces[1], &to))
|
||||
P type_id;
|
||||
int rate;
|
||||
if (!DecodeIdentifiabilityType(pieces[0], &type_id) ||
|
||||
!base::StringToInt(pieces[1], &rate))
|
||||
return {V(), false};
|
||||
if (to < 0 || to > IdentifiabilityStudyState::kMaxSamplingRateDenominator)
|
||||
if (rate < 0 || rate > features::kMaxIdentifiabilityStudySurfaceSelectionRate)
|
||||
return {V(), false};
|
||||
return {V(from, to), true};
|
||||
return {V(type_id, rate), true};
|
||||
}
|
||||
|
||||
template <
|
||||
@ -117,4 +118,4 @@ std::string EncodeIdentifiabilityFieldTrialParam(const T& source) {
|
||||
return base::JoinString(result, ",");
|
||||
}
|
||||
|
||||
#endif // CHROME_BROWSER_PRIVACY_BUDGET_FIELD_TRIAL_PARAM_CONVERSIONS_H_
|
||||
#endif // CHROME_COMMON_PRIVACY_BUDGET_FIELD_TRIAL_PARAM_CONVERSIONS_H_
|
@ -2,12 +2,11 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/browser/privacy_budget/field_trial_param_conversions.h"
|
||||
#include "chrome/common/privacy_budget/field_trial_param_conversions.h"
|
||||
|
||||
#include "chrome/browser/privacy_budget/scoped_privacy_budget_config.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
TEST(EncodeIdentifiabilityTypeTest, Surface) {
|
||||
TEST(FieldTrialParamConversionsTest, Surface) {
|
||||
auto original_surface = blink::IdentifiableSurface::FromMetricHash(100);
|
||||
EXPECT_EQ(std::string("100"), EncodeIdentifiabilityType(original_surface));
|
||||
|
||||
@ -21,7 +20,7 @@ TEST(EncodeIdentifiabilityTypeTest, Surface) {
|
||||
EXPECT_EQ(original_surface, decoded_surface);
|
||||
}
|
||||
|
||||
TEST(EncodeIdentifiabilityTypeTest, Type) {
|
||||
TEST(FieldTrialParamConversionsTest, Type) {
|
||||
auto original_type = blink::IdentifiableSurface::Type::kWebFeature;
|
||||
std::string encoded = EncodeIdentifiabilityType(original_type);
|
||||
EXPECT_EQ(std::string("1"), encoded);
|
||||
@ -31,7 +30,7 @@ TEST(EncodeIdentifiabilityTypeTest, Type) {
|
||||
EXPECT_EQ(original_type, foo);
|
||||
}
|
||||
|
||||
TEST(EncodeIdentifiabilityTypeTest, FieldTrialParam_Surface) {
|
||||
TEST(FieldTrialParamConversionsTest, FieldTrialParam_Surface) {
|
||||
std::map<blink::IdentifiableSurface, int> original_map;
|
||||
original_map[blink::IdentifiableSurface::FromMetricHash(100)] = 5;
|
||||
original_map[blink::IdentifiableSurface::FromMetricHash(UINT64_C(1) << 55)] =
|
||||
@ -45,7 +44,7 @@ TEST(EncodeIdentifiabilityTypeTest, FieldTrialParam_Surface) {
|
||||
EXPECT_EQ(original_map, decoded_map);
|
||||
}
|
||||
|
||||
TEST(EncodeIdentifiabilityTypeTest, FieldTrialParam_Type) {
|
||||
TEST(FieldTrialParamConversionsTest, FieldTrialParam_Type) {
|
||||
std::map<blink::IdentifiableSurface::Type, int> original_map;
|
||||
original_map[blink::IdentifiableSurface::Type::kReservedInternal] = 6;
|
||||
original_map[blink::IdentifiableSurface::Type::kWebFeature] = 5;
|
||||
@ -58,7 +57,7 @@ TEST(EncodeIdentifiabilityTypeTest, FieldTrialParam_Type) {
|
||||
EXPECT_EQ(original_map, decoded_map);
|
||||
}
|
||||
|
||||
TEST(EncodeIdentifiabilityTypeTest, DecodeBadSurface) {
|
||||
TEST(FieldTrialParamConversionsTest, DecodeBadSurface) {
|
||||
auto decoded_surface = blink::IdentifiableSurface();
|
||||
EXPECT_FALSE(DecodeIdentifiabilityType("foo", &decoded_surface));
|
||||
EXPECT_FALSE(DecodeIdentifiabilityType("-100", &decoded_surface));
|
||||
@ -66,7 +65,7 @@ TEST(EncodeIdentifiabilityTypeTest, DecodeBadSurface) {
|
||||
&decoded_surface));
|
||||
}
|
||||
|
||||
TEST(EncodeIdentifiabilityTypeTest, DecodeBadType) {
|
||||
TEST(FieldTrialParamConversionsTest, DecodeBadType) {
|
||||
auto decoded_type = blink::IdentifiableSurface::Type::kReservedInternal;
|
||||
EXPECT_FALSE(DecodeIdentifiabilityType("foo", &decoded_type));
|
||||
EXPECT_FALSE(DecodeIdentifiabilityType("-100", &decoded_type));
|
@ -2,9 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/browser/privacy_budget/privacy_budget_features.h"
|
||||
|
||||
#include "chrome/browser/privacy_budget/identifiability_study_state.h"
|
||||
#include "chrome/common/privacy_budget/privacy_budget_features.h"
|
||||
|
||||
namespace features {
|
||||
|
||||
@ -24,8 +22,7 @@ const base::FeatureParam<int> kIdentifiabilityStudySurfaceSelectionRate = {
|
||||
&kIdentifiabilityStudy, "Rho", 0};
|
||||
|
||||
const base::FeatureParam<int> kIdentifiabilityStudyMaxSurfaces = {
|
||||
&kIdentifiabilityStudy, "Max",
|
||||
IdentifiabilityStudyState::kMaxSampledIdentifiableSurfaces};
|
||||
&kIdentifiabilityStudy, "Max", kMaxIdentifiabilityStudyMaxSurfaces};
|
||||
|
||||
const base::FeatureParam<std::string> kIdentifiabilityStudyPerSurfaceSettings =
|
||||
{&kIdentifiabilityStudy, "HashRate", ""};
|
@ -2,10 +2,11 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_PRIVACY_BUDGET_PRIVACY_BUDGET_FEATURES_H_
|
||||
#define CHROME_BROWSER_PRIVACY_BUDGET_PRIVACY_BUDGET_FEATURES_H_
|
||||
#ifndef CHROME_COMMON_PRIVACY_BUDGET_PRIVACY_BUDGET_FEATURES_H_
|
||||
#define CHROME_COMMON_PRIVACY_BUDGET_PRIVACY_BUDGET_FEATURES_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/feature_list.h"
|
||||
#include "base/metrics/field_trial_params.h"
|
||||
|
||||
@ -67,6 +68,9 @@ extern const base::FeatureParam<std::string> kIdentifiabilityStudyBlockedTypes;
|
||||
// Parameter type: int
|
||||
extern const base::FeatureParam<int> kIdentifiabilityStudySurfaceSelectionRate;
|
||||
|
||||
// Largest meaningful sampling denominator. Picked out of hat.
|
||||
constexpr int kMaxIdentifiabilityStudySurfaceSelectionRate = 1000000;
|
||||
|
||||
// The maximum number of surfaces that can be included in the identifiability
|
||||
// study.
|
||||
//
|
||||
@ -74,6 +78,15 @@ extern const base::FeatureParam<int> kIdentifiabilityStudySurfaceSelectionRate;
|
||||
// Parameter type: int
|
||||
extern const base::FeatureParam<int> kIdentifiabilityStudyMaxSurfaces;
|
||||
|
||||
// This is a hardcoded maximum for the number of identifiable surfaces that
|
||||
// can be reported for a user. The actual ceiling for active surfaces cannot
|
||||
// exceed this value even if it's sent via a server-side configuration.
|
||||
//
|
||||
// In other words this is the maximum value that can be configured via
|
||||
// `kIdentifiabilityStudyMaxSurfaces`. Hence it's the
|
||||
// `kMaxIdentifiabilityStudyMaxSurfaces`.
|
||||
constexpr int kMaxIdentifiabilityStudyMaxSurfaces = 10;
|
||||
|
||||
// Selection rate for clusters of related surfaces.
|
||||
//
|
||||
// Parameter name: "HashRate"
|
||||
@ -98,4 +111,4 @@ extern const base::FeatureParam<std::string>
|
||||
|
||||
} // namespace features
|
||||
|
||||
#endif // CHROME_BROWSER_PRIVACY_BUDGET_PRIVACY_BUDGET_FEATURES_H_
|
||||
#endif // CHROME_COMMON_PRIVACY_BUDGET_PRIVACY_BUDGET_FEATURES_H_
|
@ -0,0 +1,55 @@
|
||||
// Copyright 2020 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 "chrome/common/privacy_budget/privacy_budget_settings_provider.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/stl_util.h"
|
||||
#include "chrome/common/privacy_budget/field_trial_param_conversions.h"
|
||||
#include "chrome/common/privacy_budget/privacy_budget_features.h"
|
||||
#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
|
||||
|
||||
PrivacyBudgetSettingsProvider::PrivacyBudgetSettingsProvider()
|
||||
: blocked_surfaces_(
|
||||
DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceSet>(
|
||||
features::kIdentifiabilityStudyBlockedMetrics.Get())),
|
||||
blocked_types_(
|
||||
DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceTypeSet>(
|
||||
features::kIdentifiabilityStudyBlockedTypes.Get())),
|
||||
|
||||
// In practice there's really no point in enabling the feature with a max
|
||||
// active surface count of 0.
|
||||
enabled_(base::FeatureList::IsEnabled(features::kIdentifiabilityStudy) &&
|
||||
features::kIdentifiabilityStudySurfaceSelectionRate.Get() > 0) {}
|
||||
|
||||
PrivacyBudgetSettingsProvider::PrivacyBudgetSettingsProvider(
|
||||
const PrivacyBudgetSettingsProvider&) = default;
|
||||
PrivacyBudgetSettingsProvider::PrivacyBudgetSettingsProvider(
|
||||
PrivacyBudgetSettingsProvider&&) = default;
|
||||
PrivacyBudgetSettingsProvider::~PrivacyBudgetSettingsProvider() = default;
|
||||
|
||||
bool PrivacyBudgetSettingsProvider::IsActive() const {
|
||||
return enabled_;
|
||||
}
|
||||
|
||||
bool PrivacyBudgetSettingsProvider::IsAnyTypeOrSurfaceBlocked() const {
|
||||
return !blocked_surfaces_.empty() || !blocked_types_.empty();
|
||||
}
|
||||
|
||||
bool PrivacyBudgetSettingsProvider::IsSurfaceAllowed(
|
||||
blink::IdentifiableSurface surface) const {
|
||||
return !base::Contains(blocked_surfaces_, surface) &&
|
||||
IsTypeAllowed(surface.GetType());
|
||||
}
|
||||
|
||||
bool PrivacyBudgetSettingsProvider::IsTypeAllowed(
|
||||
blink::IdentifiableSurface::Type type) const {
|
||||
return !base::Contains(blocked_types_, type);
|
||||
}
|
||||
|
||||
std::unique_ptr<PrivacyBudgetSettingsProvider>
|
||||
PrivacyBudgetSettingsProvider::Clone() const {
|
||||
return std::make_unique<PrivacyBudgetSettingsProvider>(*this);
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
// Copyright 2020 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.
|
||||
|
||||
#ifndef CHROME_COMMON_PRIVACY_BUDGET_PRIVACY_BUDGET_SETTINGS_PROVIDER_H_
|
||||
#define CHROME_COMMON_PRIVACY_BUDGET_PRIVACY_BUDGET_SETTINGS_PROVIDER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings_provider.h"
|
||||
#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
|
||||
|
||||
// A IdentifiabilityStudySettingsProvider that's based on the identifiability
|
||||
// study feature flags and field trial configuration.
|
||||
//
|
||||
// These features and field trial parameters are found in
|
||||
// privacy_budget_features.h.
|
||||
//
|
||||
// In the browser process these settings are used to filter out metrics that
|
||||
// should be excluded from the study. In the renderer they are used to prevent
|
||||
// certain surfaces from being sampled at all.
|
||||
//
|
||||
// Note: The ONLY parameters that should be exposed to the renderer are those
|
||||
// that are shared across a large number of clients since it is possible to
|
||||
// indirectly observe the set of surfaces that are sampled. Thus the set of
|
||||
// sampled surfaces itself could become an identifier.
|
||||
//
|
||||
// Renderer-exposed controls are meant to act as a granular kill switches in
|
||||
// cases where the act of sampling itself has unforeseen adverse side-effects.
|
||||
// Filtering done in the browser are privacy controls and cannot address
|
||||
// issues arising at the point of sampling.
|
||||
class PrivacyBudgetSettingsProvider final
|
||||
: public blink::IdentifiabilityStudySettingsProvider {
|
||||
public:
|
||||
using IdentifiableSurfaceSet =
|
||||
std::unordered_set<blink::IdentifiableSurface,
|
||||
blink::IdentifiableSurfaceHash>;
|
||||
using IdentifiableSurfaceTypeSet =
|
||||
std::unordered_set<blink::IdentifiableSurface::Type>;
|
||||
|
||||
PrivacyBudgetSettingsProvider();
|
||||
PrivacyBudgetSettingsProvider(const PrivacyBudgetSettingsProvider&);
|
||||
PrivacyBudgetSettingsProvider(PrivacyBudgetSettingsProvider&&);
|
||||
~PrivacyBudgetSettingsProvider() override;
|
||||
|
||||
bool operator=(const PrivacyBudgetSettingsProvider&) const = delete;
|
||||
bool operator=(const PrivacyBudgetSettingsProvider&&) const = delete;
|
||||
|
||||
// blink::IdentifiabilityStudySettingsProvider
|
||||
bool IsActive() const override;
|
||||
bool IsAnyTypeOrSurfaceBlocked() const override;
|
||||
bool IsSurfaceAllowed(blink::IdentifiableSurface surface) const override;
|
||||
bool IsTypeAllowed(blink::IdentifiableSurface::Type type) const override;
|
||||
|
||||
const IdentifiableSurfaceSet& blocked_surfaces() const {
|
||||
return blocked_surfaces_;
|
||||
}
|
||||
const IdentifiableSurfaceTypeSet& blocked_types() const {
|
||||
return blocked_types_;
|
||||
}
|
||||
|
||||
// Useful for passing these around.
|
||||
std::unique_ptr<PrivacyBudgetSettingsProvider> Clone() const;
|
||||
|
||||
private:
|
||||
// Set of identifiable surfaces for which we will NOT collect metrics. This
|
||||
// list is server controlled.
|
||||
const IdentifiableSurfaceSet blocked_surfaces_;
|
||||
|
||||
// Set of identifiable surface types for which we will NOT collect metrics.
|
||||
// This list is server controlled.
|
||||
const IdentifiableSurfaceTypeSet blocked_types_;
|
||||
|
||||
// True if identifiability study is enabled. If this field is false, then none
|
||||
// of the other values are applicable.
|
||||
const bool enabled_ = false;
|
||||
};
|
||||
|
||||
#endif // CHROME_COMMON_PRIVACY_BUDGET_PRIVACY_BUDGET_SETTINGS_PROVIDER_H_
|
@ -2,10 +2,10 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/browser/privacy_budget/scoped_privacy_budget_config.h"
|
||||
#include "chrome/common/privacy_budget/scoped_privacy_budget_config.h"
|
||||
|
||||
#include "chrome/browser/privacy_budget/field_trial_param_conversions.h"
|
||||
#include "chrome/browser/privacy_budget/privacy_budget_features.h"
|
||||
#include "chrome/common/privacy_budget/field_trial_param_conversions.h"
|
||||
#include "chrome/common/privacy_budget/privacy_budget_features.h"
|
||||
#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
|
||||
|
||||
namespace test {
|
||||
@ -14,6 +14,7 @@ ScopedPrivacyBudgetConfig::Parameters::Parameters() = default;
|
||||
ScopedPrivacyBudgetConfig::Parameters::Parameters(const Parameters&) = default;
|
||||
ScopedPrivacyBudgetConfig::Parameters::Parameters(Parameters&&) = default;
|
||||
ScopedPrivacyBudgetConfig::Parameters::~Parameters() = default;
|
||||
|
||||
ScopedPrivacyBudgetConfig::~ScopedPrivacyBudgetConfig() = default;
|
||||
ScopedPrivacyBudgetConfig::ScopedPrivacyBudgetConfig() = default;
|
||||
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_PRIVACY_BUDGET_SCOPED_PRIVACY_BUDGET_CONFIG_H_
|
||||
#define CHROME_BROWSER_PRIVACY_BUDGET_SCOPED_PRIVACY_BUDGET_CONFIG_H_
|
||||
#ifndef CHROME_COMMON_PRIVACY_BUDGET_SCOPED_PRIVACY_BUDGET_CONFIG_H_
|
||||
#define CHROME_COMMON_PRIVACY_BUDGET_SCOPED_PRIVACY_BUDGET_CONFIG_H_
|
||||
|
||||
#include <limits>
|
||||
#include <map>
|
||||
@ -15,9 +15,9 @@
|
||||
|
||||
namespace test {
|
||||
|
||||
// Configures the privacy budget feature settings. One can also configure the
|
||||
// service manually by controlling the global feature lists directly. This class
|
||||
// is merely a convenience.
|
||||
// Configures the privacy budget feature settings for testing. One can also
|
||||
// configure the service manually by setting the global feature lists
|
||||
// directly. This class is merely a convenience.
|
||||
//
|
||||
// For testing only.
|
||||
//
|
||||
@ -74,4 +74,4 @@ class ScopedPrivacyBudgetConfig {
|
||||
|
||||
} // namespace test
|
||||
|
||||
#endif // CHROME_BROWSER_PRIVACY_BUDGET_SCOPED_PRIVACY_BUDGET_CONFIG_H_
|
||||
#endif // CHROME_COMMON_PRIVACY_BUDGET_SCOPED_PRIVACY_BUDGET_CONFIG_H_
|
@ -3742,6 +3742,7 @@ test("unit_tests") {
|
||||
"//chrome/browser/updates/announcement_notification:unit_tests",
|
||||
"//chrome/common:test_support",
|
||||
"//chrome/common/media_router:test_support",
|
||||
"//chrome/common/privacy_budget:unit_tests",
|
||||
"//components/account_id",
|
||||
"//components/autofill/content/renderer:test_support",
|
||||
"//components/browser_sync:test_support",
|
||||
|
68
docs/privacy_budget_code_locations.md
Normal file
68
docs/privacy_budget_code_locations.md
Normal file
@ -0,0 +1,68 @@
|
||||
# Privacy Budget: Code Locations
|
||||
|
||||
Following on from the high level [Privacy
|
||||
Budget](https://github.com/bslassey/privacy-budget) explainer, the current
|
||||
implementation focuses on measuring the identifiability of various web exposed
|
||||
features. Hence the word `Identifiability` occurs often in the code and
|
||||
documentation.
|
||||
|
||||
This document focuses on code layout for Privacy Budget. Concepts and background
|
||||
for the identifiability study are out of scope.
|
||||
|
||||
TODO(asanka): Link to study documents once they are checked in.
|
||||
|
||||
## Core Metrics and Aggregation
|
||||
|
||||
Locations:
|
||||
|
||||
* [`third_party/blink/public/common/privacy_budget`](../third_party/blink/public/common/privacy_budget)
|
||||
* [`third_party/blink/common/privacy_budget`](../third_party/blink/common/privacy_budget)
|
||||
|
||||
Includes:
|
||||
|
||||
* Core logic and primitives for constructing identifiability metrics.
|
||||
|
||||
This is what one would use when reporting identifiability study samples.
|
||||
Centralized logic makes it easier to construct consistent and stable samples.
|
||||
|
||||
* Per-process aggregation of metrics.
|
||||
|
||||
Aggregation minimizes the amount of information being communicated across
|
||||
process boundaries.
|
||||
|
||||
The code in this directory is shared across `//content`, `//chrome`, and
|
||||
`//third_party/blink`. Hence its placement in `blink/public/common`.
|
||||
|
||||
In addition, this directory also contains logic for per-process aggregation of
|
||||
metrics so that they can be efficiently communicated across process boundaries.
|
||||
|
||||
## Static study settings
|
||||
|
||||
Locations:
|
||||
|
||||
* [`chrome/common/privacy_budget`](../chrome/common/privacy_budget)
|
||||
|
||||
Logic for accessing per-session settings based on externally supplied field
|
||||
trial configurations. The full set of externally controlled settings are
|
||||
in
|
||||
[`privacy_budget_features.h`](../chrome/common/privacy_budget/privacy_budget_features.h).
|
||||
|
||||
At a high level, these settings control such things as:
|
||||
|
||||
* Whether the study is active.
|
||||
* Which identifiable surfaces should *not* be sampled.
|
||||
* Parameters for how surfaces are selected for sampling.
|
||||
|
||||
Both the browser and the renderer need to access these settings. The browser
|
||||
needs them for filtering and reporting. The renderer needs them to avoid
|
||||
sampling surfaces where sampling itself is harmful for performance or stability
|
||||
reasons.
|
||||
|
||||
## Persistent study state and reporting
|
||||
|
||||
Locations:
|
||||
* [`chrome/browser/privacy_budget`](../chrome/browser/privacy_budget)
|
||||
|
||||
Per-client state is primarily used and exposed by `IdentifiabilityStudyState`
|
||||
([Source](../chrome/browser/privacy_budget/identifiability_study_state.h)).
|
||||
|
6
third_party/blink/common/privacy_budget/README.md
vendored
Normal file
6
third_party/blink/common/privacy_budget/README.md
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
# Privacy Budget: Core Metrics and Aggregation
|
||||
|
||||
See [Privacy Budget: Code
|
||||
Locations](../../../../docs/privacy_budget_code_locations.md) for
|
||||
details.
|
||||
|
6
third_party/blink/public/common/privacy_budget/README.md
vendored
Normal file
6
third_party/blink/public/common/privacy_budget/README.md
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
# Privacy Budget: Core Metrics and Aggregation
|
||||
|
||||
See [Privacy Budget: Code
|
||||
Locations](../../../../../docs/privacy_budget_code_locations.md) for
|
||||
details.
|
||||
|
@ -24,6 +24,12 @@ namespace blink {
|
||||
// * Immutable.
|
||||
// * Efficient enough to pass by value.
|
||||
//
|
||||
// Internally, an identifiable surface is represented as a 64-bit unsigned
|
||||
// integer that can be used as the metric hash for reporting metrics via UKM.
|
||||
//
|
||||
// The least-significant |kTypeBits| of the value is used to store
|
||||
// a IdentifiableSurface::Type value. The remainder stores the 56
|
||||
// least-significant bits of an IdentifiableToken.
|
||||
class IdentifiableSurface {
|
||||
public:
|
||||
// Number of bits used by Type.
|
||||
@ -39,8 +45,7 @@ class IdentifiableSurface {
|
||||
// Type of identifiable surface.
|
||||
//
|
||||
// Even though the data type is uint64_t, we can only use 8 bits due to how we
|
||||
// pack the surface type and a digest of the input into a 64 bits. See
|
||||
// README.md in this directory for details on encoding.
|
||||
// pack the surface type and a digest of the input into a 64 bits.
|
||||
//
|
||||
// These values are used for aggregation across versions. Entries should not
|
||||
// be renumbered and numeric values should never be reused.
|
||||
@ -100,6 +105,9 @@ class IdentifiableSurface {
|
||||
constexpr bool IsValid() const { return metric_hash_ != kInvalidHash; }
|
||||
|
||||
private:
|
||||
constexpr explicit IdentifiableSurface(uint64_t metric_hash)
|
||||
: metric_hash_(metric_hash) {}
|
||||
|
||||
// Returns a 64-bit metric key given an IdentifiableSurfaceType and a 64 bit
|
||||
// input digest.
|
||||
//
|
||||
@ -122,8 +130,6 @@ class IdentifiableSurface {
|
||||
metric >> kTypeBits);
|
||||
}
|
||||
|
||||
constexpr explicit IdentifiableSurface(uint64_t metric_hash)
|
||||
: metric_hash_(metric_hash) {}
|
||||
uint64_t metric_hash_;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user