1// Copyright 2023 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14syntax = "proto3"; 15 16package cobalt; 17 18option java_multiple_files = true; 19option java_package = "com.google.cobalt"; 20 21//////////////////////////////////////////////////////////////////////////////// 22// NOTE: This file is used by the Cobalt client and the Cobalt servers. 23// The source-of-truth of this file is located in Cobalt's open source code 24// repository, and the file is copied to Android where it is used by the Cobalt 25// client. Do not edit the copy of this file in this Android repo as those edits 26// will be overwritten when the file is next copied. 27//////////////////////////////////////////////////////////////////////////////// 28 29// An Observation is a piece of data sent from a Cobalt client to the Cobalt 30// server as input to a Report. 31// 32// Observations are associated with a specific Metric. They are built on a 33// Fuchsia client based on the Events logged for that Metric. Observations are 34// associated with a specific Report. They are built for the purpose of 35// generating that Report. They are transmitted from the Fuchsia client to 36// the Cobalt server where they are aggregated and analyzed in order to generate 37// the Report. 38// 39// Observations may store their data using special privacy-preserving encodings. 40// The specification of how to do this is part of the definition of a Report. 41// Observations are built for a particular Report and so use an encoding 42// appropriate for that Report. 43// 44// There are different types of Observations that are appropriate for different 45// types of Metrics and different types of Reports. 46// 47// An Observation is always transmitted and stored along with 48// some ObservationMetadata that describes, among other things, which Metric 49// and which Report it is for and on which day the Observation was formed. 50// 51// Observations are transmitted from the client to the server encrypted, inside 52// the |ciphertext| field of an EncryptedMessage. Many encrypted Observations 53// are transmitted together inside of an ObservationBatch. 54message Observation { 55 // Next observation_type ID: 9 56 // Next general ID: 1002; 57 reserved 1, 2, 3, 4, 5, 6, 7, 8, 1000; 58 59 // An Observation has one of the following types. 60 oneof observation_type { 61 SumAndCountObservation sum_and_count = 9; 62 IntegerObservation integer = 10; 63 IndexHistogramObservation index_histogram = 11; 64 StringHistogramObservation string_histogram = 12; 65 PrivateIndexObservation private_index = 13; 66 ReportParticipationObservation report_participation = 10000; 67 } 68 69 // A quasi-unique identifier for this observation. This is randomly generated 70 // on the client and used on the server as part of a fully-unique identifier. 71 // This field allows the operation of sending an Observation to the Cobalt 72 // server to be idempotent: If the same Observation is transmitted twice then 73 // the server will store the observation only once. 74 bytes random_id = 1001; 75} 76 77// Observations of type SumAndCountObservation contain one or more triples of 78// event vectors, a signed integer recording a sum and an unsigned integer 79// recording a count. 80// 81// This type of observation is used only for the FLEETWIDE_MEANS report type. 82message SumAndCountObservation { 83 message SumAndCount { 84 // Event vector to which the sum and count are associated. 85 repeated uint32 event_codes = 1; 86 87 // The device-level sum. 88 sint64 sum = 2; 89 90 // the device-level count. 91 uint64 count = 3; 92 } 93 94 repeated SumAndCount sums_and_counts = 1; 95} 96 97// Observations of type IntegerObservation contain one or more pairs of 98// event vectors and signed integers. 99// 100// This type of observation is used for the following report types: 101// FLEETWIDE_OCCURRENCE_COUNTS 102// HOURLY_VALUE_NUMERIC_STATS 103// HOURLY_VALUE_HISTOGRAMS 104// UNIQUE_DEVICE_COUNTS 105// UNIQUE_DEVICE_NUMERIC_STATS 106// UNIQUE_DEVICE_HISTOGRAMS 107message IntegerObservation { 108 message Value { 109 // Event vector to which the value is associated. 110 repeated uint32 event_codes = 1; 111 112 // The value depends upon the report type. 113 // 114 // FLEETWIDE_OCCURRENCE_COUNTS 115 // Device-level count of events with the associated event vector. 116 // Value is between 0 and the configured maximum count (inclusive). 117 // 118 // UNIQUE_DEVICE_COUNTS 119 // 1 if the associated event vector was observed. 120 // 121 // HOURLY_VALUE_NUMERIC_STATS 122 // UNIQUE_DEVICE_NUMERIC_STATS 123 // HOURLY_VALUE_HISTOGRAMS 124 // UNIQUE_DEVICE_HISTOGRAMS 125 // Device-level aggregate value for the associated event vector. 126 sint64 value = 2; 127 } 128 129 repeated Value values = 1; 130} 131 132// IndexHistogram represents a list of counts for each bucket of a histogram 133// associated with a particular event vector. 134message IndexHistogram { 135 // Event vector to which the histogram is associated. 136 repeated uint32 event_codes = 1; 137 138 // bucket_counts[i] is the count for the bucket_indices[i]th index in the 139 // histogram. 140 repeated uint32 bucket_indices = 2; 141 repeated sint64 bucket_counts = 3; 142} 143 144// Observations of type IndexHistogramObservation contain one or more pairs of 145// event vectors and lists of bucket counts. 146// 147// This type of observation is used with the FLEETWIDE_HISTOGRAMS report type. 148message IndexHistogramObservation { 149 repeated IndexHistogram index_histograms = 1; 150} 151 152// Observations of the type StringHistogramObservation contain a list of strings 153// mapping string hashes to indices and one or more pairs of event vectors 154// and lists of bucket counts. 155// 156// This type of observation is used for the following report types: 157// STRING_COUNTS 158// UNIQUE_DEVICE_STRING_COUNTS 159message StringHistogramObservation { 160 // TODO(b/322409910): Delete string_hashes after clients stop sending 161 // the field. 162 repeated bytes string_hashes = 1 [deprecated = true]; 163 164 // List of hashes of strings (hashed using Farmhash Fingerprint64). 165 // The string that hashes to the bytes value in the ith position in 166 // |string_hashes| corresponds to the bucket with index i in each of the 167 // |bucket_indices| values in |string_histograms|. 168 // 169 // Only one of `string_hashes` or `string_hashes_ff64` should be used. 170 repeated bytes string_hashes_ff64 = 3; 171 172 repeated IndexHistogram string_histograms = 2; 173} 174 175// An observation of type PrivateIndexObservation contains a single integer. 176// Observations of this type are produced by the PrivacyEncoder: given a single 177// Observation of some other type, the PrivacyEncoder outputs one or more 178// PrivateIndexObservations. All data for reports with a nontrivial 179// privacy mechanism will be transported from client to server in the form of 180// PrivateIndexObservations. 181// 182// The field |index| of a PrivateIndexObservation is an index into an 183// enumeration of the set of possible Observations of another type (after 184// bucketing some parameters, as specified in the ReportDefinition for which the 185// Observation was generated.) The details of this enumeration depend on the 186// type of Observation which was given to the PrivacyEncoder. 187message PrivateIndexObservation { 188 uint64 index = 1; 189} 190 191// A pair consisting of a bucket index and a count. Each bucket is 192// an integer range. The definition of the buckets and their indices 193// is given in the MetricDefinition. 194// TODO(b/262785064): don't use this for the public LoggerInterface. 195message HistogramBucket { 196 // The index of one of the buckets. 197 uint32 index = 1; 198 // The count for that bucket. 199 uint64 count = 2; 200} 201 202// Observations of this type are used to signal that a given device was 203// collecting data for a given report, over some window of time. This 204// Observation type has no required fields. 205// 206// ReportParticipationObservations are produced by the PrivacyEncoder and 207// consumed by the ReportGenerator for reports that use local differential 208// privacy. 209message ReportParticipationObservation {} 210