xref: /aosp_15_r20/external/mobile-data-download/proto/metadata.proto (revision 6fa6b5e213d87a73421ed761ee7d492115d5f98c)
1// Copyright 2022 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.
14// The main purpose of mirroring external protos here is to separate API and
15// storage protos. The same tag numbers are used for making migration work.
16
17syntax = "proto2";
18
19package mdi.download.internal;
20
21import "google/protobuf/any.proto";
22import "google/protobuf/timestamp.proto";
23import "transform.proto";
24
25option java_package = "com.google.mobiledatadownload.internal";
26option java_outer_classname = "MetadataProto";
27
28// Mirrors mdi.download.ExtraHttpHeader
29//
30// HTTP headers are described in https://tools.ietf.org/html/rfc7230#section-3.2
31// as key:value, where the value may have a whitespace on each end.
32message ExtraHttpHeader {
33  optional string key = 1;
34  optional string value = 2;
35}
36
37// This proto is used to store file group metadata on disk for internal use. It
38// consists of all fields mirrored from DataFileGroup and an extra field for
39// bookkeeping.
40//
41// The tag number of extra fields should start from 1000 to reserve room for
42// growing DataFileGroup.
43//
44// Next id: 1001
45message DataFileGroupInternal {
46  // Extra information that is kept on disk.
47  //
48  // The extension was originally introduced in cl/248813966. We are migrating
49  // away from the extension. However, we still need to read from fields in the
50  // extension. Reuse the same tag number as the extension number to read from
51  // the extension.
52  optional DataFileGroupBookkeeping bookkeeping = 248813966;
53
54  // Unique name to identify the group. It should be unique per owner package.
55  // In GMSCore, use the module name as the prefix of the group name.
56  //
57  // Ex: A group name in mdisync module could be named: mdisync-profile-photos.
58  //
59  // This shouldn't ideally be something like "config", and
60  // instead should better define the feature it will be used for.
61  //
62  // Ex: "icing-language-detection-model", "smart-action-detection-model"
63  optional string group_name = 1;
64
65  // The name of the package that owns this group. If this field is left empty,
66  // the owner is assumed to be the package name of the host app.
67  //
68  // The files will only be downloaded onto the device if the owner package is
69  // present on the device.
70  //
71  // Ex: "com.google.android.gms", "com.google.android.apps.bugle"
72  optional string owner_package = 6;
73
74  // Client set version number used to identify the file group.
75  //
76  // Note that this does not uniquely identify the contents of the file group.
77  // It simply reflects a snapshot of client config changes.
78  // For example: say there's a file group 'language-detector-model' that
79  // downloads a different file per user locale.
80  // data_file_group {
81  //   file_group_name = 'language-detector-model'
82  //   file_group_version_number = 1
83  //   file {
84  //      url = 'en-model'
85  //   }
86  // }
87  // data_file_group {
88  //   file_group_name = 'language-detector-model'
89  //   file_group_version_number = 1
90  //   file {
91  //      url = 'es-model'
92  //   }
93  // }
94  // Note that even though the actual contents of the file group are different
95  // for each locale, the version is the same because this config was pushed
96  // at the same snapshot.
97  //
98  // Available GMS v18+.
99  optional int32 file_group_version_number = 10;
100
101  // DEPRECATED
102  // MDD team recommends to use explicit properties instead.
103  optional google.protobuf.Any custom_property = 20 [deprecated = true];
104
105  // Custom metadata attached to the file group.
106  //
107  // This allows clients to include specific metadata about the group for their
108  // own processing purposes. The metadata will be stored with the group and
109  // accessible when the file group is retrieved.
110  //
111  // This property should only be used if absolutely necessary. Please consult
112  // with <internal>@ if you have questions about this property or a potential
113  // use-case.
114  optional google.protobuf.Any custom_metadata = 27;
115
116  reserved 21;
117
118  // Mirrors mdi.download.DataFileGroup.AllowedReaders
119  enum AllowedReaders {
120    ALL_GOOGLE_APPS = 0;
121    ONLY_GOOGLE_PLAY_SERVICES = 1;
122    ALL_APPS = 2;
123  }
124
125  // Defines who is allowed to read this file group. Currently the options are:
126  //
127  // ALL_GOOGLE_APPS: accessible to all Google 1p Apps.
128  // ONLY_GOOGLE_PLAY_SERVICES: accessible to only GMS Core.
129  //
130  // If this field is not explicitly set it defaults to "ALL_GOOGLE_APPS".
131  //
132  // Available GMS v20+.
133  optional AllowedReaders allowed_readers_enum = 12;
134
135  // Length of time (in seconds) for which a file group version will live after
136  // since a newer version became fully downloaded. Clients should set this time
137  // to be more than the time in which they call MDD to refresh their data.
138  // NOTE: MDD will delete the file group version within a day of this time.
139  // Ex: 172800  // 2 Days
140  optional int64 stale_lifetime_secs = 3;
141
142  // The timestamp at which this filegroup should be deleted, even if it is
143  // still active, specified in seconds since epoch.
144  // NOTE: MDD will delete the file group version within a day of this time.
145  optional int64 expiration_date_secs = 11;
146
147  // Specify the conditions under which the file group should be downloaded.
148  optional DownloadConditions download_conditions = 13;
149
150  // Setting this flag to true will mean that the downloaded files will appear
151  // to be in a directory by themselves.
152  // The file name/file path of the exposed file will be the filename set in the
153  // file.relative_file_path field, OR if that field is empty, the file name
154  // from the file.url_to_download field. This enables downloaded files to refer
155  // to each other by name.
156  // It's invalid to set this flag to true if two files end up with the same
157  // file path.
158  // Valid on iOS, cMDD, and aMDD.
159  //
160  // NOTE: For aMDD, this feature is not available if Android Blob Sharing is
161  // enabled or if using an API level below 21 (L). If either case is true, this
162  // option will be ignored.
163  optional bool preserve_filenames_and_isolate_files = 14;
164
165  // List of files in the group.
166  repeated DataFile file = 2;
167
168  // Tag for the network traffic to download this file group.
169  // Tag space is determined by the host app.
170  // For Gmscore, the tag should come from:
171  // <internal>
172  optional int32 traffic_tag = 16;
173
174  // Extra HTTP headers to apply when downloading all files in the group.
175  repeated ExtraHttpHeader group_extra_http_headers = 17;
176
177  reserved 19;
178
179  // Unique identifier of a DataFileGroup config (i.e. a "snapshot") created
180  // when using MDD Ingress API.
181  optional int64 build_id = 23;
182
183  // A fingerprint allowing clients to identify a DataFileGroup
184  // config based on a given set of properties (i.e. a "partition" of
185  // any file group properties). This can be used by clients as an exact match
186  // for a class of DataFileGroups during targeting or as a compatibility check.
187  optional string variant_id = 26;
188
189  // The locales compatible with the file group. This can be different from the
190  // device locale.
191  //
192  // Values in this list may be exact locales (e.g. "en-US") or language-only
193  // ("en-*").
194  // Example 1: locale = ["en-US"]; // compatible with "en-US" only
195  // Example 2: locale = ["en-US", "en-CA"]; // compatible with "en-US" or
196  //                                         // "en-CA"
197  // Example 3: locale = ["en-*"]; // compatible with all "en" locales
198  repeated string locale = 25;
199
200  reserved 28;
201
202  // If a group enables preserve_filenames_and_isolate_files
203  // this property will contain the directory root of the isolated
204  // structure. Specifically, the property will be a string created from the
205  // group name and a hash of other identifying properties (account, variantid,
206  // buildid).
207  //
208  // currently only used in aMDD.
209  optional string isolated_directory_root = 1000;
210
211  reserved 4, 5, 7, 8, 9, 15, 18, 22, 24;
212}
213
214// Mirrors mdi.download.DataFile
215//
216// A data file represents all the metadata to download the file and then
217// manage it on the device.
218// Next tag: 22
219//
220// This should not contain any fields that are marked internal, as we compare
221// the protos directly to decide if it is a new version of the file.
222// LINT.IfChange(data_file)
223message DataFile {
224  // A unique identifier of the file within the group, that can be used to
225  // get this file from the group.
226  // Ex: "language-detection-model"
227  optional string file_id = 7;
228
229  // Url from where the file is to be downloaded.
230  // Ex: https://www.gstatic.com/group-name/model_1234.zip
231  optional string url_to_download = 2;
232
233  // Exact size of the file. This is used to check if there is space available
234  // for the file before scheduling the download.
235  // The byte_size is optional. If not set, MDD will try with best effort to get
236  // the file size using the HTTP HEAD request.
237  optional int32 byte_size = 4;
238
239  // Enum for checksum types.
240  // NOTE: do not add any new checksum type here, older MDD versions would break
241  // otherwise.
242  enum ChecksumType {
243    // Default checksum is SHA1.
244    DEFAULT = 0;
245
246    // No checksum is provided.
247    NONE = 1;
248
249    reserved 2 /* SHA256 */;
250  }
251
252  optional ChecksumType checksum_type = 15;
253
254  // SHA1 checksum to verify the file before it can be used. This is also used
255  // to de-duplicate files between different groups.
256  // For most files, this will be the checksum of the file being downloaded.
257  // For files with download_transform, this should contain the transform of
258  // the file after the transforms have been applied.
259  // The checksum is optional. If not set, the checksum_type must be
260  // ChecksumType.NONE.
261  optional string checksum = 5;
262
263  // The following are <internal> transforms to apply to the downloaded files.
264  // Transforms are bi-directional and defined in terms of what they do on
265  // write. Since these transforms are applied while reading, their
266  // directionality is reversed. Eg, you'll see 'compress' to indicate that the
267  // file should be decompressed.
268
269  // These transforms are applied once by MDD after downloading the file.
270  // Currently only compress is available.
271  // Valid on Android. iOS support is tracked by b/118828045.
272  optional mobstore.proto.Transforms download_transforms = 11;
273
274  // If DataFile has download_transforms, this field must be provided with the
275  // SHA1 checksum of the file before any transform are applied. The original
276  // checksum would also be checked after the download_transforms are applied.
277  optional string downloaded_file_checksum = 14;
278
279  // Exact size of the downloaded file. If the DataFile has download transforms
280  // like compress and zip, the downloaded file size would be different than
281  // the final file size on disk. Client could use
282  // this field to track the downloaded file size and calculate the download
283  // progress percentage. This field is not used by MDD currently.
284  optional int32 downloaded_file_byte_size = 16;
285
286  // These transforms are evaluated by the caller on-the-fly when reading the
287  // data with MobStore. Any transforms installed in the caller's MobStore
288  // instance is available.
289  // Valid on Android. iOS support is tracked by b/118759254.
290  optional mobstore.proto.Transforms read_transforms = 12;
291
292  // List of delta files that can be encoded and decoded with base files.
293  // If the device has any base file, the delta file which is much
294  // smaller will be downloaded instead of the full file.
295  // For most clients, only one delta file should be enough. If specifying
296  // multiple delta files, they should be in a sequence from the most recent
297  // base file to the oldest.
298  // This is currently only supported on Android.
299  repeated DeltaFile delta_file = 13;
300
301  enum AndroidSharingType {
302    // The dataFile isn't available for sharing.
303    UNSUPPORTED = 0;
304
305    // If sharing with the Android Blob Sharing Service isn't available, fall
306    // back to normal behavior, i.e. download locally.
307    ANDROID_BLOB_WHEN_AVAILABLE = 1;
308  }
309
310  // Defines whether the file should be shared and how.
311  // NOTE: currently this field is only used by aMDD and has no effect on iMDD.
312  optional AndroidSharingType android_sharing_type = 17;
313
314  // Enum for android sharing checksum types.
315  enum AndroidSharingChecksumType {
316    NOT_SET = 0;
317
318    // If the file group should be shared through the Android Blob Sharing
319    // Service, the checksum type must be set to SHA256.
320    SHA2_256 = 1;
321  }
322
323  optional AndroidSharingChecksumType android_sharing_checksum_type = 18;
324
325  // Checksum used to access files through the Android Blob Sharing Service.
326  optional string android_sharing_checksum = 19;
327
328  // Relative file path and file name to be preserved within the parent
329  // directory when creating symlinks for the file groups that have
330  // preserve_filenames_and_isolate_files set to true.
331  // This filename should NOT start or end with a '/', and it can not contain
332  // the substring '..'.
333  // Working example: "subDir/FileName.txt".
334  optional string relative_file_path = 20;
335
336  // Custom metadata attached to the file.
337  //
338  // This allows clients to include specific metadata about the file for their
339  // own processing purposes. The metadata will be stored with the file and
340  // accessible when the file's file group is retrieved.
341  //
342  // This property should only be used if absolutely necessary. Please consult
343  // with <internal>@ if you have questions about this property or a potential
344  // use-case.
345  optional google.protobuf.Any custom_metadata = 21;
346
347  reserved 1, 3, 6, 8, 9;
348}
349// LINT.ThenChange(
350//     <internal>,
351//     <internal>)
352
353// Mirrors mdi.download.DeltaFile
354//
355// A delta file represents all the metadata to download for a diff file encoded
356// based on a base file
357// LINT.IfChange(delta_file)
358message DeltaFile {
359  // These fields all mirror the similarly-named fields in DataFile.
360  optional string url_to_download = 1;
361  optional int32 byte_size = 2;
362  optional string checksum = 3;
363
364  // Enum of all diff decoders supported
365  enum DiffDecoder {
366    // Default to have no diff decoder specified, will thrown unsupported
367    // exception
368    UNSPECIFIED = 0;
369
370    // VcDIFF decoder
371    // Generic Differencing and Compression Data Format
372    // For more information, please refer to rfc3284
373    // The VcDiff decoder for GMS service:
374    // <internal>
375    VC_DIFF = 1;
376  }
377  // The diff decoder used to generate full file with delta and base file.
378  // For MDD as a GMS service, a VcDiff decoder will be registered and injected
379  // in by default. Using MDD as a library, clients need to register and inject
380  // in a VcDiff decoder, otherwise, an exception will be thrown.
381  optional DiffDecoder diff_decoder = 5;
382
383  // The base file represents to a full file on device. It should contain the
384  // bare minimum fields of a DataFile to identify a DataFile on device.
385  optional BaseFile base_file = 6;
386
387  reserved 4;
388}
389// LINT.ThenChange(
390//     <internal>,
391//     <internal>)
392
393// Mirrors mdi.download.BaseFile
394message BaseFile {
395  // SHA1 checksum of the base file to identify a file on device. It should
396  // match the checksum field of the base file used to generate the delta file.
397  optional string checksum = 1;
398}
399
400// Mirrors mdi.download.DownloadConditions
401//
402// Next id: 5
403message DownloadConditions {
404  // TODO(b/143548753): The first value in an enum must have a specific prefix.
405  enum DeviceStoragePolicy {
406    // MDD will block download of files in android low storage. Currently MDD
407    // doesn't delete the files in case the device reaches low storage
408    // after the file has been downloaded.
409    BLOCK_DOWNLOAD_IN_LOW_STORAGE = 0;
410
411    // Block download of files only under a lower threshold defined here
412    // <internal>
413    BLOCK_DOWNLOAD_LOWER_THRESHOLD = 1;
414
415    // Set the storage threshold to an extremely low value when downloading.
416    // IMPORTANT: if the download make the device runs out of disk, this could
417    // render the device unusable.
418    // This should only be used for critical use cases such as privacy
419    // violations. Emergency fix should not belong to this category. Please
420    // talks to <internal>@ when you want to use this option.
421    EXTREMELY_LOW_THRESHOLD = 2;
422  }
423
424  // Specify the device storage under which the files should be downloaded.
425  // By default, the files will only be downloaded if the device is not in
426  // low storage.
427  optional DeviceStoragePolicy device_storage_policy = 1;
428
429  // TODO(b/143548753): The first value in an enum must have a specific prefix.
430  enum DeviceNetworkPolicy {
431    // Only download files on wifi.
432    DOWNLOAD_ONLY_ON_WIFI = 0;
433
434    // Allow download on any network including wifi and cellular.
435    DOWNLOAD_ON_ANY_NETWORK = 1;
436
437    // Allow downloading only on wifi first, then after a configurable time
438    // period set in the field download_first_on_wifi_period_secs below,
439    // allow downloading on any network including wifi and cellular.
440    DOWNLOAD_FIRST_ON_WIFI_THEN_ON_ANY_NETWORK = 2;
441  }
442
443  // Specify the device network under which the files should be downloaded.
444  // By default, the files will only be downloaded on wifi.
445  //
446  // If your feature targets below v20 and want to download on cellular in
447  // these versions of gms, also set allow_dowload_without_wifi = true;
448  optional DeviceNetworkPolicy device_network_policy = 2;
449
450  // This field will only be used when the
451  // DeviceNetworkPolicy = DOWNLOAD_FIRST_ON_WIFI_THEN_ON_ANY_NETWORK
452  // MDD will download the file only on wifi for this period of time. If the
453  // download was not finished, MDD will download on any network including
454  // wifi and cellular.
455  // Ex: 604800  // 7 Days
456  optional int64 download_first_on_wifi_period_secs = 4;
457
458  // TODO(b/143548753): The first value in an enum must have a specific prefix.
459  enum ActivatingCondition {
460    // The download is activated as soon the server side config is received and
461    // the server configured download conditions are satisfied.
462    ALWAYS_ACTIVATED = 0;
463
464    // The download is activated when both server side activation conditions
465    // are satisfied and the client has activated the download on device.
466    //
467    // Clients can activate this group using the activateFileGroup API.
468    // <internal>
469    DEVICE_ACTIVATED = 1;
470  }
471
472  // Specify how the download is activated. By default, the download is
473  // activated as soon as server configured activating conditions are satisfied.
474  optional ActivatingCondition activating_condition = 3;
475}
476
477// This proto contains extra information about a file group for bookkeeping.
478// Next tag: 6
479message DataFileGroupBookkeeping {
480  // The epoch time (seconds since 1/1/1970) at which this stale file group will
481  // be deleted.
482  optional int64 stale_expiration_date = 1;
483
484  // The timestamp (epoch time, milliseconds since 1/1/1970) that the file group
485  // was first received.
486  //
487  // If this is an update on an existing group, then the timestamp from the old
488  // group is used if no files were updated.
489  optional int64 group_new_files_received_timestamp = 2;
490
491  // The timestamp (epoch time, milliseconds since 1/1/1970) at which the group
492  // was first marked as downloaded.
493  optional int64 group_downloaded_timestamp_in_millis = 3;
494
495  // The timestamp (epoch time, milliseconds since 1/1/1970) that MDD starts
496  // downloading the file group for the first time.
497  optional int64 group_download_started_timestamp_in_millis = 4;
498
499  // The total count of download periodic tasks needed to fully download the
500  // file group.
501  optional int32 download_started_count = 5;
502}
503
504// Key used by mdd to uniquely identify a client group.
505message GroupKey {
506  // The name of the group.
507  optional string group_name = 1;
508
509  // The package name of the group owner. A null value or empty value means
510  // that the group is not associated with any package.
511  optional string owner_package = 2;
512
513  // The account associated to the file group.
514  optional string account = 5;
515
516  // Whether or not all files in a fileGroup have been downloaded.
517  optional bool downloaded = 4;
518
519  // The variant id of the group for identification purposes.
520  //
521  // This is used to ensure that groups with different variants can have
522  // different entries in MDD metadata, and therefore have different lifecycles.
523  //
524  // Note that clients can choose to opt-in to a SINGLE_VARIANT flow where
525  // different variants replace each other on-device (only single variant can
526  // exist on a device at a time). In this case, an empty variant_id is set here
527  // so groups with different variants share the same GroupKey and are subject
528  // to the same lifecycle, even though the DataFileGroup does have a non-empty
529  // variant_id.
530  //
531  // Because of the SINGLE_VARIANT flow and because groups may still be added
532  // with no variant_id associated, using this property to tell if the
533  // associated file group has a variant_id is unreliable. Instead, the
534  // variant_id set within a DataFileGroup should be used as the source of truth
535  // about the group (such as when logging).
536  optional string variant_id = 6;
537
538  reserved 3;
539}
540
541// Group Key properties that apply to all groups with that key.
542message GroupKeyProperties {
543  // Whether this group key has been activated on the device.
544  optional bool activated_on_device = 1;
545}
546
547// SharedFile is a internal data structure of the SharedFileManager.
548message SharedFile {
549  optional string file_name = 4;
550  optional FileStatus file_status = 5;
551
552  // This field will be used to determine if a file can be retrieved from the
553  // Android Blob Sharing Service.
554  optional bool android_shared = 8;
555
556  // The maximum expiration date found for a downloaded data file. If
557  // {@code android_shared} is set to true, this field stores the current lease
558  // expiration date. The default value is 0.
559  // See <internal> for more details.
560  optional int64 max_expiration_date_secs = 9;
561
562  // Checksum used to access files through the Android Blob Sharing Service.
563  optional string android_sharing_checksum = 10;
564
565  // If the file is downloaded successfully but fails checksum matching, we will
566  // attempt to delete the file so it can be redownloaded from scratch. To
567  // prevent unnecessary network bandwidth, we keep track of the number of these
568  // attempts in this field and stop after a certain number. (configurable by a
569  // download flag).
570  optional int32 checksum_mismatch_retry_download_count = 11;
571
572  reserved 1, 2, 3, 6, 7;
573}
574
575// Metadata used by
576// com.google.android.libraries.mobiledatadownload.MobileDataDownloadManager
577message MobileDataDownloadManagerMetadata {
578  optional bool mdd_migrated_to_offroad = 1;
579  optional int32 reset_trigger = 2;
580}
581
582// Metadata used by
583// com.google.android.libraries.mobiledatadownload.SharedFileManager
584message SharedFileManagerMetadata {
585  optional bool migrated_to_new_file_key = 1;
586  optional int64 next_file_name = 2;
587}
588
589// Collects all data used by
590// com.google.android.libraries.mobiledatadownload.internal.Migrations
591message MigrationsStore {
592  enum FileKeyVersion {
593    NEW_FILE_KEY = 0;
594    ADD_DOWNLOAD_TRANSFORM = 1;
595    USE_CHECKSUM_ONLY = 2;
596  }
597  optional bool is_migrated_to_new_file_key = 1;
598  optional FileKeyVersion current_version = 2;
599}
600
601// Collects all data used by
602// com.google.android.libraries.mobiledatadownload.internal.FileGroupsMetadata
603message FileGroupsMetadataStore {
604  // Key must be a serialized GroupKey.
605  map<string, DataFileGroupInternal> data_file_groups = 1;
606  // Key must be a serialized GroupKey.
607  map<string, GroupKeyProperties> group_key_properties = 2;
608  repeated DataFileGroupInternal stale_groups = 3;
609}
610
611// Collects all data used by
612// com.google.android.libraries.mobiledatadownload.internal.SharedFilesMetadata
613message SharedFilesMetadataStore {
614  // The key must be a serialized NewFileKey.
615  map<string, SharedFile> shared_files = 1;
616}
617
618enum FileStatus {
619  // The file has never been seen before.
620  NONE = 0;
621  // The file has been subscribed to, but download has not been attempted.
622  SUBSCRIBED = 1;
623  // The file download is currently in progress.
624  DOWNLOAD_IN_PROGRESS = 2;
625  // Downloading the file failed.
626  DOWNLOAD_FAILED = 3;
627  // The file was downloaded completely, and is available for use.
628  DOWNLOAD_COMPLETE = 4;
629  // The file was corrupted or lost after being successfully downloaded.
630  CORRUPTED = 6;
631  // Status returned when their is an error while getting the file status.
632  // This is never saved on disk.
633  INTERNAL_ERROR = 5;
634}
635
636// Key used by the SharedFileManager to identify a shared file.
637message NewFileKey {
638  // These fields all mirror the similarly-named fields in DataFile.
639  optional string url_to_download = 1 [deprecated = true];
640  optional int32 byte_size = 2 [deprecated = true];
641  optional string checksum = 3;
642  optional DataFileGroupInternal.AllowedReaders allowed_readers = 4;
643  optional mobstore.proto.Transforms download_transforms = 5
644      [deprecated = true];
645}
646
647// This proto is used to store state for logging. See details at
648// <internal>
649message LoggingState {
650  // The last time maintenance was run. This should be updated every time
651  // maintenance is run.
652  // Note: the current implementation only uses this to determine the date of
653  // the last log event, but in the future we may want more granular
654  // measurements for this, so we store the timestamp as-is.
655  optional google.protobuf.Timestamp last_maintenance_run_timestamp = 1;
656
657  // File group specific logging state keyed by GroupKey, build id and version
658  // number.
659  repeated FileGroupLoggingState file_group_logging_state = 2;
660
661  // Set to true once the shared preferences migration is complete.
662  // Note: this field isn't strictly necessary at the moment - we could just
663  // check that the file_group_logging_state is empty since no one should write
664  // to the network usage monitor shared prefs since the migration will be
665  // installed at the same cl where the code is removed. However, if we were to
666  // add more fields to FileGroupLoggingState, it would be less straightforward
667  // to check for migration state - so having this boolean makes it a bit safer.
668  optional bool shared_preferences_network_usage_monitor_migration_complete = 3;
669
670  // Info to enable stable sampling. See <internal> for more
671  // info. This field will be set by a migration on first access.
672  optional SamplingInfo sampling_info = 4;
673}
674
675// This proto is used to store state for logging that is specific to a File
676// Group. This includes network usage logging and maybe download tiers (for
677// <internal>).
678//
679// NEXT TAG: 7
680message FileGroupLoggingState {
681  // GroupKey associated with a file group -- this is used to populate the group
682  // name and host package name.
683  optional GroupKey group_key = 1;
684
685  // The build_id associated with the file group.
686  optional int64 build_id = 2;
687
688  // The variant_id associated with the file group.
689  optional string variant_id = 6;
690
691  // The file group version number associated with the file group.
692  optional int32 file_group_version_number = 3;
693
694  // The number of bytes downloaded over a cellular (metered) network.
695  optional int64 cellular_usage = 4;
696
697  // The number of bytes downloaded over a wifi (unmetered) network.
698  optional int64 wifi_usage = 5;
699}
700
701// Next id: 3
702message SamplingInfo {
703  // Random number generated and persisted on device. This number should not
704  // change (unless device storage/mdd is cleared). It is used as a stable
705  // identifier to determine whether MDD should log events.
706  optional int64 stable_log_sampling_salt = 1;
707
708  // When the stable_log_sampling_salt was first set. This will be used during
709  // roll out to determine which devices have enabled stable sampling for a
710  // sufficient time period.
711  optional google.protobuf.Timestamp log_sampling_salt_set_timestamp = 2;
712}
713