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_METRIC_BUILDER_H_ 6 #define THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_METRIC_BUILDER_H_ 7 8 #include <cstdint> 9 10 #include "base/metrics/ukm_source_id.h" 11 #include "services/metrics/public/cpp/ukm_entry_builder_base.h" 12 #include "third_party/blink/public/common/common_export.h" 13 #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" 14 15 namespace blink { 16 17 // IdentifiabilityMetricBuilder builds an identifiability metric encoded into a 18 // UkmEntry. 19 // 20 // This UkmEntry can be recorded via a UkmRecorder. 21 // 22 // # Encoding 23 // 24 // All identifiability metrics are represented using the tuple 25 // 26 // < identifiable_surface_type, input, output >. 27 // 28 // A typical URL-Keyed-Metrics (UKM) entry looks like the following: 29 // 30 // struct UkmEntry { 31 // int64 source_id; 32 // uint64 event_hash; 33 // map<uint64,int64> metrics; 34 // }; 35 // 36 // (From //services/metrics/public/mojom/ukm_interface.mojom) 37 // 38 // This class encodes the former into the latter. 39 // 40 // The |source_id| is one that is known to UKM. Follow UKM guidelines for how to 41 // generate or determine the |source_id| corresponding to a document or URL. 42 // 43 // The |event_hash| is a digest of the UKM event name via 44 // |base::HashMetricName()|. For identifiability metrics, this is always 45 // UINT64_C(287024497009309687) which corresponds to 'Identifiability'. 46 // 47 // Metrics for *regular* UKM consist of a mapping from a metric ID to a metric 48 // value. The metric ID is a digest of the metric name as determined by 49 // base::DigestForMetrics(), similar to how an |event_hash| is derived from the 50 // event name. 51 // 52 // However, for identifiability metrics, the method for generating metric IDs 53 // is: 54 // 55 // metrics_hash = (input << 8) | identifiable_surface_type; 56 // 57 // The |identifiable_surface_type| is an enumeration identifying the input 58 // identifier defined in |IdentifiableSurface::Type|. 59 // 60 // We lose the 8 MSBs of |input|. Retaining the lower bits allow us to use small 61 // (i.e. under 56-bits) numbers as-is without losing information. 62 // 63 // The |IdentifiableSurface| class encapsulates this translation. 64 // 65 // The |metrics| field in |UkmEntry| thus contains a mapping from the resulting 66 // |metric_hash| to the output of the identifiable surface encoded into 64-bits. 67 // 68 // To generate a 64-bit hash of a random binary blob, use 69 // |blink::DigestForMetrics()|. For numbers with fewer than 56 70 // significant bits, you can use the number itself as the input hash. 71 // 72 // As mentioned in |identifiability_metrics.h|, this function is **not** a 73 // cryptographic hash function. While it is expected to have a reasonable 74 // distribution for a uniform input, it should be assumed that finding 75 // collisions is trivial. 76 // 77 // E.g.: 78 // 79 // 1. A simple web exposed API that's represented using a |WebFeature| 80 // constant. Values are defined in 81 // blink/public/mojom/web_feature/web_feature.mojom. 82 // 83 // identifiable_surface = IdentifiableSurface::FromTypeAndInput( 84 // IdentifiableSurface::Type::kWebFeature, 85 // blink::mojom::WebFeature::kDeviceOrientationSecureOrigin); 86 // output = DigestForMetrics(result_as_binary_blob); 87 // 88 // 2. A surface that takes a non-trivial input represented as a binary blob: 89 // 90 // identifiable_surface = IdentifiableSurface::FromTypeAndInput( 91 // IdentifiableSurface::Type::kFancySurface, 92 // DigestForMetrics(input_as_binary_blob)); 93 // output = DigestForMetrics(result_as_binary_blob); 94 class BLINK_COMMON_EXPORT IdentifiabilityMetricBuilder 95 : public ukm::internal::UkmEntryBuilderBase { 96 public: 97 // Construct a metrics builder for the given |source_id|. The source must be 98 // known to UKM. 99 explicit IdentifiabilityMetricBuilder(base::UkmSourceId source_id); 100 ~IdentifiabilityMetricBuilder() override; 101 102 // Set the metric using a previously constructed |IdentifiableSurface|. 103 IdentifiabilityMetricBuilder& Set(IdentifiableSurface surface, 104 int64_t result); 105 106 // Set the metric using a surface type, input and result. 107 IdentifiabilityMetricBuilder& Set(IdentifiableSurface::Type surface_type, 108 int64_t input, 109 int64_t result); 110 }; 111 112 } // namespace blink 113 114 #endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_METRIC_BUILDER_H_ 115