File: variations_layers.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (134 lines) | stat: -rw-r--r-- 5,489 bytes parent folder | download | duplicates (2)
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
// Copyright 2020 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_VARIATIONS_VARIATIONS_LAYERS_H_
#define COMPONENTS_VARIATIONS_VARIATIONS_LAYERS_H_

#include <map>
#include <optional>

#include "base/component_export.h"
#include "base/metrics/field_trial.h"
#include "base/types/optional_ref.h"
#include "components/variations/entropy_provider.h"
#include "components/variations/processed_study.h"
#include "components/variations/proto/layer.pb.h"
#include "components/variations/proto/variations_seed.pb.h"

namespace variations {

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class InvalidLayerReason {
  kInvalidId = 0,
  kNoSlots = 1,
  kNoMembers = 2,
  kInvalidEntropyMode = 3,
  kSlotsDoNotDivideLowEntropyDomain = 4,
  kInvalidSlotBounds = 5,
  kUnknownFields = 6,
  LayerIDNotUnique = 7,
  kLimitedLayerDropped = 8,
  kDuplicatedLayerMemberID = 9,
  kMaxValue = kDuplicatedLayerMemberID,
};

// A view over the layers defined within a variations seed.
//
// A layer defines a collection of mutually exclusive members. For each client,
// at most one member will be assigned as its active member. Studies may be
// conditioned on a particular member being active, in order to avoid overlap
// with studies that require a different member to be active.
class COMPONENT_EXPORT(VARIATIONS) VariationsLayers {
 public:
  // Instantiates a `VariationsLayers` object with `seed` and
  // `entropy_providers`.
  VariationsLayers(const VariationsSeed& seed,
                   const EntropyProviders& entropy_providers);

  VariationsLayers();
  ~VariationsLayers();

  VariationsLayers(const VariationsLayers&) = delete;
  VariationsLayers& operator=(const VariationsLayers&) = delete;

  // True iff the layer members each have valid start and end values, and are
  // non-overlapping. Valid start and end values means that 1) end must be >=
  // start, and 2) they each refer to a slot that's within the range defined in
  // the layer.
  static bool AreSlotBoundsValid(const Layer& layer_proto);

  // True iff a high entropy provider can be used to randomize the study.
  static bool AllowsHighEntropy(const Study& study);

  // Checks whether the layer member reference object is referencing the given
  // `layer_member_id`.
  static bool IsReferencingLayerMemberId(
      const LayerMemberReference& layer_member_reference,
      uint32_t layer_member_id);

  // Checks if the client's slot for that layer is associated with a layer
  // member. Returns whether the layer that's associated with the `layer_id` is
  // active. If not, for the same `layer_id`, IsLayerMemberActive() and
  // ActiveLayerMemberDependsOnHighEntropy() will always be false, and
  // GetRemainderEntropy() will return an entropy provider that always
  // randomizes to a fixed value (revealing no entropy).
  bool IsLayerActive(uint32_t layer_id) const;

  // Returns whether any of the layer members referenced are active.
  bool IsLayerMemberActive(
      const LayerMemberReference& layer_member_reference) const;

  // Returns true if the layer has an active member and is configured to use
  // DEFAULT entropy, which means that any study conditioned on it would leak
  // information about the client's high entropy source (including whether or
  // not the client _has_ a high entropy source).
  bool ActiveLayerMemberDependsOnHighEntropy(uint32_t layer_id) const;

  // Returns the entropy provider that should be used to randomize the group
  // assignments of the given study. Or an empty optional if there is no
  // suitable entropy provider. The caller should drop the study upon receiving
  // an empty optional.
  base::optional_ref<const base::FieldTrial::EntropyProvider>
  SelectEntropyProviderForStudy(
      const ProcessedStudy& processed_study,
      const EntropyProviders& entropy_providers) const;

 private:
  struct LayerInfo {
    // Which layer member is active in the layer.
    uint32_t active_member_id;
    // The type of entropy the layer was configured to use.
    Layer::EntropyMode entropy_mode;
    // If this layer has an active member, this is the remaining entropy from
    // that selection, which can be used for uniform randomization of studies
    // conditioned on that layer member.
    // See ComputeRemainderEntropy() for details.
    NormalizedMurmurHashEntropyProvider remainder_entropy;
  };

  void ConstructLayer(const EntropyProviders& entropy_providers,
                      const Layer& layer_proto);

  // Finds the layer with the given `layer_id`. Returns nullptr if there isn't a
  // layer with this id or the layer is invalid.
  const LayerInfo* FindActiveLayer(uint32_t layer_id) const;

  // Gets an EntropyProvider for low entropy randomization of studies
  // conditioned on the layer's active member.
  const base::FieldTrial::EntropyProvider& GetRemainderEntropy(
      uint32_t layer_id) const;

  // Returns the entropy mode of layer with `layer_id`. The optional will not
  // have a value if there isn't a layer with this id, the layer is invalid, or
  // the layer is not active.
  std::optional<Layer::EntropyMode> GetEntropyMode(uint32_t layer_id) const;

  NormalizedMurmurHashEntropyProvider nil_entropy_;
  std::map<uint32_t, LayerInfo> active_member_for_layer_;
};

}  // namespace variations

#endif  // COMPONENTS_VARIATIONS_VARIATIONS_LAYERS_H_