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. 14syntax = "proto2"; 15 16package mdi.download; 17 18import "google/protobuf/any.proto"; 19import "transform.proto"; 20 21option java_package = "com.google.mobiledatadownload"; 22option java_outer_classname = "DownloadConfigProto"; 23option objc_class_prefix = "Icing"; 24//option go_api_flag = "OPEN_TO_OPAQUE_HYBRID"; // See <internal>. 25 26// The top-level proto for Mobile Data Download (<internal>). 27message DownloadConfig { 28 repeated DataFileGroup data_file_group = 1; 29 30 reserved 2; 31} 32 33// HTTP headers are described in https://tools.ietf.org/html/rfc7230#section-3.2 34// as key:value, where the value may have a whitespace on each end. 35message ExtraHttpHeader { 36 optional string key = 1; 37 optional string value = 2; 38} 39 40// A FileGroup is a set of files that should be atomically updated. 41// Next id: 29 42message DataFileGroup { 43 // Unique name to identify the group. It should be unique per owner package. 44 // In GMSCore, use the module name as the prefix of the group name. 45 // 46 // Ex: A group name in mdisync module could be named: mdisync-profile-photos. 47 // 48 // This shouldn't ideally be something like "config", and 49 // instead should better define the feature it will be used for. 50 // 51 // Ex: "icing-language-detection-model", "smart-action-detection-model" 52 // 53 // IMPORTANT: this group name will be logged to clearcut, and must never 54 // contain PII. 55 optional string group_name = 1; 56 57 // The name of the package that owns this group. If this field is left empty, 58 // the owner is assumed to be the package name of the host app. 59 // 60 // The files will only be downloaded onto the device if the owner package is 61 // present on the device. 62 // 63 // Ex: "com.google.android.gms", "com.google.android.apps.bugle" 64 optional string owner_package = 6; 65 66 // Client set version number used to identify the file group. 67 // 68 // Note that this does not uniquely identify the contents of the file group. 69 // It simply reflects a snapshot of client config changes. 70 // For example: say there's a file group 'language-detector-model' that 71 // downloads a different file per user locale. 72 // data_file_group { 73 // file_group_name = 'language-detector-model' 74 // file_group_version_number = 1 75 // file { 76 // url = 'en-model' 77 // } 78 // } 79 // data_file_group { 80 // file_group_name = 'language-detector-model' 81 // file_group_version_number = 1 82 // file { 83 // url = 'es-model' 84 // } 85 // } 86 // Note that even though the actual contents of the file group are different 87 // for each locale, the version is the same because this config was pushed 88 // at the same snapshot. 89 // 90 // Available GMS v18+. 91 optional int32 file_group_version_number = 10; 92 93 reserved 20; 94 95 // Custom metadata attached to the file group. 96 // 97 // This allows clients to include specific metadata about the group for their 98 // own processing purposes. The metadata will be stored with the group and 99 // accessible when the file group is retrieved. 100 // 101 // This property should only be used if absolutely necessary. Please consult 102 // with <internal>@ if you have questions about this property or a potential 103 // use-case. 104 // 105 // Available for aMDD Lib only. 106 optional google.protobuf.Any custom_metadata = 27; 107 108 reserved 22; 109 110 reserved 21; 111 112 enum AllowedReaders { 113 ALL_GOOGLE_APPS = 0; 114 ONLY_GOOGLE_PLAY_SERVICES = 1; 115 ALL_APPS = 2; 116 } 117 118 // Defines who is allowed to read this file group. Currently the options are: 119 // 120 // ALL_GOOGLE_APPS: accessible to all Google 1p Apps. 121 // ONLY_GOOGLE_PLAY_SERVICES: accessible to only GMS Core. 122 // 123 // If this field is not explicitly set it defaults to "ALL_GOOGLE_APPS". 124 // 125 // Available GMS v20+. 126 optional AllowedReaders allowed_readers_enum = 12; 127 128 // Length of time (in seconds) for which a file group version will live after 129 // a newer version became fully downloaded. Clients should set this time 130 // to be more than the time in which they call MDD to refresh their data. 131 // NOTE: MDD will delete the file group version within a day of this time. 132 // Ex: 172800 // 2 Days 133 optional int64 stale_lifetime_secs = 3; 134 135 // The timestamp at which this filegroup should be deleted specified in 136 // seconds since epoch. This is a hard deadline and can be applied to file 137 // groups still in the ACTIVE state. If the value is 0, that is the same as 138 // unset (no expiration). Expiration is performed at next cleanup time, which 139 // is typically daily. Therefore, file groups may remain even after expired, 140 // and may do so indefinitely if cleanup is not scheduled. 141 // 142 // NOTE this is not the way to delete a file group. For example, setting an 143 // expiration date in the past will fail, potentially leaving an unexpired 144 // file group in place indefinitely. Use the MDD removeFileGroup API for that 145 // on device. From the server, the way to delete a file group is to add a new 146 // one with the same name, but with no files (this functions as a tombstone). 147 // 148 // NOTE b/252890898 for behavior on CastOS (cMDD) 149 // NOTE b/252885626 for missing support for delete in MobServe Ingress 150 optional int64 expiration_date = 11; 151 152 // Specify the conditions under which the file group should be downloaded. 153 optional DownloadConditions download_conditions = 13; 154 155 // Setting this flag to true will mean that the downloaded files will appear 156 // to be in a directory by themselves. 157 // The file name/file path of the exposed file will be the filename set in the 158 // file.relative_file_path field, OR if that field is empty, the file name 159 // from the file.url_to_download field. This enables downloaded files to refer 160 // to each other by name. 161 // It's invalid to set this flag to true if two files end up with the same 162 // file path. 163 // Valid on iOS, cMDD, and aMDD. 164 // 165 // NOTE: For aMDD, this feature is not available if Android Blob Sharing is 166 // enabled or if using an API level below 21 (L). If either case is true, this 167 // option will be ignored. 168 optional bool preserve_filenames_and_isolate_files = 14; 169 170 // List of files in the group. 171 repeated DataFile file = 2; 172 173 // Tag for the network traffic to download this file group. 174 // Tag space is determined by the host app. 175 // For Gmscore, the tag should come from: 176 // <internal> 177 optional int32 traffic_tag = 16; 178 179 // Extra HTTP headers to apply when downloading all files in the group. 180 repeated ExtraHttpHeader group_extra_http_headers = 17; 181 182 reserved 19; 183 184 // Unique identifier of a DataFileGroup config (i.e. a "snapshot") created 185 // when using MDD Ingress API. 186 optional int64 build_id = 23; 187 188 // A fingerprint allowing clients to identify a DataFileGroup 189 // config based on a given set of properties (i.e. a "partition" of 190 // any file group properties). This can be used by clients as an exact match 191 // for a class of DataFileGroups during targeting or as a compatibility check. 192 optional string variant_id = 26; 193 194 // The locales compatible with the file group. This can be different from the 195 // device locale. 196 // 197 // Values in this list may be exact locales (e.g. "en-US") or language-only 198 // ("en-*"). 199 // Example 1: locale = ["en-US"]; // compatible with "en-US" only 200 // Example 2: locale = ["en-US", "en-CA"]; // compatible with "en-US" or 201 // // "en-CA" 202 // Example 3: locale = ["en-*"]; // compatible with all "en" locales 203 repeated string locale = 25; 204 205 reserved 28; 206 207 reserved 4, 5, 7, 8, 9, 15, 18, 24, 248813966 /*aMDD extension*/, 208 248606552 /*cMDD extension*/; 209} 210 211// A data file represents all the metadata to download the file and then 212// manage it on the device. 213// Next tag: 22 214// 215// This should not contain any fields that are marked internal, as we compare 216// the protos directly to decide if it is a new version of the file. 217// LINT.IfChange(data_file) 218message DataFile { 219 // A unique identifier of the file within the group, that can be used to 220 // get this file from the group. 221 // Ex: "language-detection-model" 222 optional string file_id = 7; 223 224 // Url from where the file is to be downloaded. 225 // Ex: https://www.gstatic.com/group-name/model_1234.zip 226 optional string url_to_download = 2; 227 228 // Exact size of the file. This is used to check if there is space available 229 // for the file before scheduling the download. 230 // The byte_size is optional. If not set, MDD will not be able check the space 231 // available before schedulding the download. 232 optional int32 byte_size = 4; 233 234 // Enum for checksum types. 235 // NOTE: do not add any new checksum type here, older MDD versions would break 236 // otherwise. 237 enum ChecksumType { 238 // Default checksum is SHA1. 239 DEFAULT = 0; 240 241 // No checksum is provided. 242 // This is NOT currently supported by iMDD. Please contact <internal>@ if you 243 // need this feature. 244 NONE = 1; 245 246 // This is currently only supported by cMDD. If you need it for Android or 247 // iOS, please contact MDD team <internal>@. 248 SHA256 = 2; 249 } 250 251 optional ChecksumType checksum_type = 15; 252 253 // SHA1 checksum to verify the file before it can be used. This is also used 254 // to de-duplicate files between different groups. 255 // For most files, this will be the checksum of the file being downloaded. 256 // For files with download_transform, this should contain the transform of 257 // the file after the transforms have been applied. 258 // The checksum is optional. If not set, the checksum_type must be 259 // ChecksumType.NONE. 260 optional string checksum = 5; 261 262 // The following are <internal> transforms to apply to the downloaded files. 263 // Transforms are bi-directional and defined in terms of what they do on 264 // write. Since these transforms are applied while reading, their 265 // directionality is reversed. Eg, you'll see 'compress' to indicate that the 266 // file should be decompressed. 267 268 // These transforms are applied once by MDD after downloading the file. 269 // Currently only compress is available. 270 // Valid on Android. iOS support is tracked by b/118828045. 271 optional mobstore.proto.Transforms download_transforms = 11; 272 273 // If DataFile has download_transforms, this field must be provided with the 274 // SHA1 checksum of the file before any transform are applied. The original 275 // checksum would also be checked after the download_transforms are applied. 276 optional string downloaded_file_checksum = 14; 277 278 // Exact size of the downloaded file. If the DataFile has download transforms 279 // like compress and zip, the downloaded file size would be different than 280 // the final file size on disk. Client could use 281 // this field to track the downloaded file size and calculate the download 282 // progress percentage. This field is not used by MDD currently. 283 optional int32 downloaded_file_byte_size = 16; 284 285 // These transforms are evaluated by the caller on-the-fly when reading the 286 // data with MobStore. Any transforms installed in the caller's MobStore 287 // instance is available. 288 // Valid on Android and cMDD. iOS support is tracked by b/118759254. 289 optional mobstore.proto.Transforms read_transforms = 12; 290 291 // List of delta files that can be encoded and decoded with base files. 292 // If the device has any base file, the delta file which is much 293 // smaller will be downloaded instead of the full file. 294 // For most clients, only one delta file should be enough. If specifying 295 // multiple delta files, they should be in a sequence from the most recent 296 // base file to the oldest. 297 // This is currently only supported on Android. 298 repeated DeltaFile delta_file = 13; 299 300 enum AndroidSharingType { 301 // The dataFile isn't available for sharing. 302 UNSUPPORTED = 0; 303 304 // If sharing with the Android Blob Sharing Service isn't available, fall 305 // back to normal behavior, i.e. download locally. 306 ANDROID_BLOB_WHEN_AVAILABLE = 1; 307 } 308 309 // Defines whether the file should be shared and how. 310 // NOTE: currently this field is only used by aMDD and has no effect on iMDD. 311 optional AndroidSharingType android_sharing_type = 17; 312 313 // Enum for android sharing checksum types. 314 enum AndroidSharingChecksumType { 315 NOT_SET = 0; 316 317 // If the file group should be shared through the Android Blob Sharing 318 // Service, the checksum type must be set to SHA256. 319 SHA2_256 = 1; 320 } 321 322 optional AndroidSharingChecksumType android_sharing_checksum_type = 18; 323 324 // Checksum used to access files through the Android Blob Sharing Service. 325 optional string android_sharing_checksum = 19; 326 327 // Relative file path and file name to be preserved within the parent 328 // directory when creating symlinks for the file groups that have 329 // preserve_filenames_and_isolate_files set to true. 330 // This filename should NOT start or end with a '/', and it can not contain 331 // the substring '..'. 332 // Working example: "subDir/FileName.txt". 333 optional string relative_file_path = 20; 334 335 // Custom metadata attached to the file. 336 // 337 // This allows clients to include specific metadata about the file for their 338 // own processing purposes. The metadata will be stored with the file and 339 // accessible when the file's file group is retrieved. 340 // 341 // This property should only be used if absolutely necessary. Please consult 342 // with <internal>@ if you have questions about this property or a potential 343 // use-case. 344 // 345 // Available for aMDD Lib only. 346 optional google.protobuf.Any custom_metadata = 21; 347 348 reserved 1, 3, 6, 8, 9; 349} 350// LINT.ThenChange( 351// <internal>, 352// <internal>) 353 354// A delta file represents all the metadata to download for a diff file encoded 355// based on a base file 356// LINT.IfChange(delta_file) 357message DeltaFile { 358 // These fields all mirror the similarly-named fields in DataFile. 359 optional string url_to_download = 1; 360 optional int32 byte_size = 2; 361 optional string checksum = 3; 362 363 // Enum of all diff decoders supported 364 enum DiffDecoder { 365 // Default to have no diff decoder specified, will thrown unsupported 366 // exception 367 UNSPECIFIED = 0; 368 369 // VcDIFF decoder 370 // Generic Differencing and Compression Data Format 371 // For more information, please refer to rfc3284 372 // The VcDiff decoder for GMS service: 373 // <internal> 374 VC_DIFF = 1; 375 } 376 // The diff decoder used to generate full file with delta and base file. 377 // For MDD as a GMS service, a VcDiff decoder will be registered and injected 378 // in by default. Using MDD as a library, clients need to register and inject 379 // in a VcDiff decoder, otherwise, an exception will be thrown. 380 optional DiffDecoder diff_decoder = 5; 381 382 // The base file represents to a full file on device. It should contain the 383 // bare minimum fields of a DataFile to identify a DataFile on device. 384 optional BaseFile base_file = 6; 385 386 reserved 4; 387} 388// LINT.ThenChange( 389// <internal>, 390// <internal>) 391 392message BaseFile { 393 // SHA1 checksum of the base file to identify a file on device. It should 394 // match the checksum field of the base file used to generate the delta file. 395 optional string checksum = 1; 396} 397 398// LINT.IfChange 399// Next id: 5 400message DownloadConditions { 401 // TODO(b/143548753): The first value in an enum must have a specific prefix. 402 enum DeviceStoragePolicy { 403 // MDD will block download of files in android low storage. Currently MDD 404 // doesn't delete the files in case the device reaches low storage 405 // after the file has been downloaded. 406 BLOCK_DOWNLOAD_IN_LOW_STORAGE = 0; 407 408 // Block download of files only under a lower threshold defined here 409 // <internal> 410 BLOCK_DOWNLOAD_LOWER_THRESHOLD = 1; 411 412 // Set the storage threshold to an extremely low value when downloading. 413 // IMPORTANT: if the download make the device runs out of disk, this could 414 // render the device unusable. 415 // This should only be used for critical use cases such as privacy 416 // violations. Emergency fix should not belong to this category. Please 417 // talks to <internal>@ when you want to use this option. 418 EXTREMELY_LOW_THRESHOLD = 2; 419 } 420 421 // Specify the device storage under which the files should be downloaded. 422 // By default, the files will only be downloaded if the device is not in 423 // low storage. 424 optional DeviceStoragePolicy device_storage_policy = 1; 425 426 // TODO(b/143548753): The first value in an enum must have a specific prefix. 427 enum DeviceNetworkPolicy { 428 // Only download files on wifi. 429 DOWNLOAD_ONLY_ON_WIFI = 0; 430 431 // Allow download on any network including wifi and cellular. 432 DOWNLOAD_ON_ANY_NETWORK = 1; 433 434 // Allow downloading only on wifi first, then after a configurable time 435 // period set in the field download_first_on_wifi_period_secs below, 436 // allow downloading on any network including wifi and cellular. 437 DOWNLOAD_FIRST_ON_WIFI_THEN_ON_ANY_NETWORK = 2; 438 } 439 440 // Specify the device network under which the files should be downloaded. 441 // By default, the files will only be downloaded on wifi. 442 // 443 // If your feature targets below v20 and want to download on cellular in 444 // these versions of gms, also set allow_download_without_wifi = true; 445 optional DeviceNetworkPolicy device_network_policy = 2; 446 447 // This field will only be used when the 448 // DeviceNetworkPolicy = DOWNLOAD_FIRST_ON_WIFI_THEN_ON_ANY_NETWORK 449 // MDD will download the file only on wifi for this period of time. If the 450 // download was not finished, MDD will download on any network including 451 // wifi and cellular. 452 // Ex: 604800 // 7 Days 453 optional int64 download_first_on_wifi_period_secs = 4; 454 455 // TODO(b/143548753): The first value in an enum must have a specific prefix. 456 enum ActivatingCondition { 457 // The download is activated as soon the server side config is received and 458 // the server configured download conditions are satisfied. 459 ALWAYS_ACTIVATED = 0; 460 461 // The download is activated when both server side activation conditions 462 // are satisfied and the client has activated the download on device. 463 // 464 // Clients can activate this group using the activateFileGroup API. 465 // <internal> 466 DEVICE_ACTIVATED = 1; 467 } 468 469 // Specify how the download is activated. By default, the download is 470 // activated as soon as server configured activating conditions are satisfied. 471 optional ActivatingCondition activating_condition = 3; 472} 473// LINT.ThenChange( 474// <internal>, 475// <internal>) 476 477message PhConfig { 478 repeated PhClient ph_client = 1; 479} 480 481// Config for a client that wants to download their data file group using 482// a phenotype flag. It contains the phenotype flag name where the client 483// config is present. 484// This is used by clients that want to download data files conditionally. Its 485// current usage is to download webref slices. 486message PhClient { 487 // The phenotype flag name where the config is present. 488 optional string ph_flag_name = 1; 489} 490 491// ManifestConfig to support on device targeting. 492// The ManifestConfig could be in a payload of a PH flag or it could be in the 493// content of a Manifest file. See <internal> for more 494// details. 495// Each ManifestConfig.Entry will have a Modifier and a corresponding 496// DataFileGroup. The Modifier will be used for on device filtering/targeting. 497message ManifestConfig { 498 message Entry { 499 // All the modifier variables are used for filtering/targeting on the device 500 // side. For example, we can specify the locale "en_US" and does the 501 // targeting on the device based on this locale. If you need to add more 502 // fields to Modifier, please email <internal>@. 503 message Modifier { 504 // Locales for which this DataFileGroup is valid. 505 // Locales defined here are application's specific. 506 // It will be consumed by the application's 507 // ManifestConfigFlagPopulator.Overrider to do on-device targeting. The 508 // Overrider will interprete the locales to select best locale matches. 509 // For example, it can invoke the LanguageMatcher [1] to support 510 // "Local Inheritance" [2]. 511 // [1] 512 // <internal> 513 // [2] <internal> 514 repeated string locale = 1; 515 516 // Custom Properties. 517 // Defined by each application. The application needs to provide a 518 // ManifestConfigOverrider 519 // (<internal> 520 // that understands and filters entries based on this Custom Properties. 521 optional google.protobuf.Any custom_properties = 2; 522 523 message Location { 524 // S2CellId (<internal>) associated with this DataFileGroup. It will be 525 // used to do location based targeting on device, optionally filtering 526 // extraneous slices if the user has location permissions enabled. 527 // Otherwise location targeting will be based on a rough estimate from 528 // IP-based geolocation on the server. The type fixed64 is a bit more 529 // efficient than int64 for our purposes. This is because int64 uses 530 // prefix encoding, however, for the S2CellIds the high-order bits 531 // encode the face-ID and as a result we often end up with large 532 // numbers. 533// optional fixed64 s2_cell_id = 1 [ 534// (datapol.semantic_type) = ST_LOCATION 535 optional fixed64 s2_cell_id = 1; 536 } 537 538 optional Location location = 3; 539 } 540 541 optional Modifier modifier = 1; 542 optional DataFileGroup data_file_group = 2; 543 } 544 545 message UrlTemplate { 546 // Template to construct a {@code DataFile}'s url_to_download on device. 547 // If the url template should be used, the url_to_download field should be 548 // left unpopulated. If the url template and the url_to_download are both 549 // populated, the template will be ignored. 550 optional string file_url_template = 1; 551 } 552 553 repeated Entry entry = 1; 554 555 // Template definition for constructing URLs on device. It applies to every 556 // DataFile defined in the ManifestConfig. 557 optional UrlTemplate url_template = 2; 558} 559 560// The flag that MDD gets from P/H, and contains information about the manifest 561// file to be downloaded. 562// Next id: 3 563message ManifestFileFlag { 564 // The ID for the manifest file. This should be unique in the host app space. 565 optional string manifest_id = 1; 566 567 // The url to the manifest file on Google hosting service. 568 optional string manifest_file_url = 2; 569} 570