1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_SETTINGS_H_
6 #define THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_SETTINGS_H_
7 
8 #include <memory>
9 
10 #include "third_party/blink/public/common/common_export.h"
11 #include "third_party/blink/public/common/privacy_budget/identifiability_study_settings_provider.h"
12 #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
13 #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-forward.h"
14 
15 namespace blink {
16 
17 // Determines whether the identifiability study is active and if so whether a
18 // given surface or surface type should be sampled.
19 //
20 // This class can used from multiple threads and does not require
21 // synchronization.
22 //
23 // See documentation on individual methods for notes on thread safety.
24 //
25 // Guidelines for when and how to use it can be found in:
26 //
27 //     //docs/privacy_budget_instrumentation.md#gating
28 //
29 class BLINK_COMMON_EXPORT IdentifiabilityStudySettings {
30  public:
31   // Constructs a default IdentifiabilityStudySettings instance. By default the
32   // settings instance acts as if the study is disabled, and implicitly as if
33   // all surfaces and types are blocked.
34   IdentifiabilityStudySettings();
35 
36   // Constructs a IdentifiabilityStudySettings instance which reflects the state
37   // specified by |provider|.
38   explicit IdentifiabilityStudySettings(
39       std::unique_ptr<IdentifiabilityStudySettingsProvider> provider);
40 
41   ~IdentifiabilityStudySettings();
42 
43   // Get a pointer to an instance of IdentifiabilityStudySettings for the
44   // process.
45   //
46   // This method and the returned object is safe to use from any thread and is
47   // never destroyed.
48   //
49   // On the browser process, the returned instance is authoritative. On all
50   // other processes the returned instance should be considered advisory. It's
51   // only meant as an optimization to avoid calculating things unnecessarily.
52   static const IdentifiabilityStudySettings* Get();
53 
54   // Initialize the process-wide settings instance with the specified settings
55   // provider. Should only be called once per process and only from the main
56   // thread.
57   //
58   // For testing, you can use ResetStateForTesting().
59   static void SetGlobalProvider(
60       std::unique_ptr<IdentifiabilityStudySettingsProvider> provider);
61 
62   // Returns true if the study is active for this client. Once if it returns
63   // true, it doesn't return false at any point after. The converse is not true.
64   bool IsActive() const;
65 
66   // Returns true if |surface| is allowed to be sampled. Be sure to check
67   // ShouldSample before actually collecting a sample.
68   //
69   // Will always return false if IsActive() is false. I.e. If the study is
70   // inactive, all surfaces are considered to be blocked. Hence it is sufficient
71   // to call this function directly instead of calling IsActive() before it.
72   bool IsSurfaceAllowed(IdentifiableSurface surface) const;
73 
74   // Returns true if |type| is allowed to be sampled. Be sure to check
75   // ShouldSample before actually collecting a sample.
76   //
77   // Will always return false if IsActive() is false. I.e. If the study is
78   // inactive, all surface types are considered to be blocked. Hence it is
79   // sufficient to call this function directly instead of calling IsActive()
80   // before it.
81   bool IsTypeAllowed(IdentifiableSurface::Type type) const;
82 
83   // Returns true if |surface| should be sampled.
84   //
85   // Will always return false if IsActive() is false or if IsSurfaceAllowed() is
86   // false. I.e. If the study is inactive, all surfaces are considered to be
87   // blocked. Hence it is sufficient to call this function directly instead of
88   // calling IsActive() before it.
89   bool ShouldSample(IdentifiableSurface surface) const;
90 
91   // Returns true if |type| should be sampled.
92   //
93   // Will always return false if IsActive() is false or if IsTypeAllowed() is
94   // false. I.e. If the study is inactive, all surface types are considered to
95   // be blocked. Hence it is sufficient to call this function directly instead
96   // of calling IsActive() before it.
97   bool ShouldSample(IdentifiableSurface::Type type) const;
98 
99   // Convenience method for determining whether the surface constructable from
100   // the type (|kWebFeature|) and the |feature| is allowed. See IsSurfaceAllowed
101   // for more detail.
102   bool IsWebFeatureAllowed(mojom::WebFeature feature) const;
103 
104   // Only used for testing. Resets internal state and violates API contracts
105   // made above about the lifetime of IdentifiabilityStudySettings*.
106   static void ResetStateForTesting();
107 
108   IdentifiabilityStudySettings(IdentifiabilityStudySettings&&) = delete;
109   IdentifiabilityStudySettings(const IdentifiabilityStudySettings&) = delete;
110   IdentifiabilityStudySettings& operator=(const IdentifiabilityStudySettings&) =
111       delete;
112 
113  private:
114   const std::unique_ptr<IdentifiabilityStudySettingsProvider> provider_;
115   const bool is_enabled_ = false;
116   const bool is_any_surface_or_type_blocked_ = false;
117 };
118 
119 }  // namespace blink
120 
121 #endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_SETTINGS_H_
122