| // 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. |
| |
| edition = "2023"; |
| |
| option optimize_for = LITE_RUNTIME; |
| option java_package = "org.chromium.components.variations"; |
| |
| package variations; |
| |
| // A Layer divides Variations clients into disjoint LayerMembers based on client |
| // entropy values, allowing potentially conflicting studies to be performed on |
| // separate client subsets. |
| |
| // Each layer consists of N slots, and each Chrome client instance will randomly |
| // select a specific slot to be "active" within that layer based on the layer's |
| // salt and the client's entropy source value. That slot will be part of a range |
| // within a specific LayerMember. Each study that participates in a layer points |
| // to a particular LayerMember within that layer. Only the studies pointing to |
| // the active LayerMember will be active for a given client. |
| // Example: |
| // LayerFoo: |
| // num_slots=10: |0, 1, 2, 3, 4, 5, 6, 7, 8, 9| |
| // LayerMembers: <0 - 3>, <4 - 9> |
| // ^Member1^ ^Member2^. |
| // |
| // In this example, the Member1 LayerMember has four slots and |
| // Member2 has six out of ten total. This means studies pointing to |
| // Member1 will receive ~40% of the population and Member2 ~60%. |
| |
| // Next tag: 6 |
| message Layer { |
| message LayerMember { |
| message SlotRange { |
| // First slot in the range (inclusive). This range has to be |
| // in the [0..`num_slots`) range of the layer. |
| uint32 start = 1; |
| // Last slot in the range (inclusive). |
| uint32 end = 2; |
| } |
| |
| // An id (unique within the Layer) that studies will use to refer to this |
| // particular member. |
| uint32 id = 1; |
| // Ranges of slots that belong to this member. These slot ranges must not |
| // overlap with the slot ranges of other members within the layer, so |
| // that at most one member within the layer will be active. The ranges must |
| // be listed in increasing order. |
| repeated SlotRange slots = 2; |
| } |
| |
| // ID for the layer, must be unique across all layers. Studies will specify |
| // a <layer_id, layer_member_id> pair to become part of a layer. |
| uint32 id = 1; |
| |
| // Total number of slots within the layer. There are constraints on the number |
| // of slots when a low entropy source is used (100, initially) to alleviate |
| // skew in the bucket populations. |
| uint32 num_slots = 2; |
| |
| // Layer members, which occupy disjoint subsets of the [0, `num_slots`) range. |
| // Not all slots have to be used, and normally won't in order to reserve space |
| // within the layer. Each study that participates in a layer is associated |
| // with a single layer member. |
| repeated LayerMember members = 3; |
| |
| // A salt which is used as an input to a hash function together with the |
| // output of the chosen entropy source, to choose an active slot within the |
| // layer. If salt is unset or 0, the layer id will be used instead. |
| uint32 salt = 4; |
| |
| enum EntropyMode { |
| option features.enum_type = CLOSED; |
| |
| // Use the default entropy source when selecting slots. This will use the |
| // high entropy source for the clients that have it, and falls back to the |
| // low entropy source for other clients. |
| DEFAULT = 0; |
| |
| // Use the low entropy source. |
| LOW = 1; |
| |
| // Use the limited entropy source. |
| LIMITED = 2; |
| } |
| |
| // Which of the above entropy modes should be used to select a slot. |
| EntropyMode entropy_mode = 5; |
| } |
| |
| // A Study can optionally specify a LayerMemberReference which will constrain it |
| // to one or more layer members of the specified layer. |
| message LayerMemberReference { |
| // Reference to the layer with this specific ID. |
| uint32 layer_id = 1; |
| |
| // References to members within the above layer. |
| // |
| // New code should use `layer_member_ids` instead. Older clients only support |
| // `layer_member_id`, and values in `layer_member_ids` are ignored. Newer |
| // clients support both fields for backward compatibility. A study that uses |
| // `layer_member_ids` needs to have a `min_version` that is greater than |
| // the minimum version that supports `layer_member_ids`. |
| // TODO(crbug.com/345611804): Amend this comment with the minimum version when |
| // it is known. |
| // |
| // Specifying more than one `layer_member_id` can be used to adjust the active |
| // percentage of a study: |
| // - Adding a `layer_member_id` will result in clients randomized to that |
| // layer member to be part of this study (and be randomized into its |
| // groups). |
| // - Removing a `layer_member_id` will take out clients randomized to that |
| // layer member from the study. |
| // |
| uint32 layer_member_id = 2; |
| repeated uint32 layer_member_ids = 3; |
| } |