// Messages describing APK Set's table of contents (toc.pb entry).
// Please be advised that the ultimate source is at
// https://github.com/google/bundletool/tree/master/src/main/proto
// so you have been warned.
syntax = "proto3";

package android.bundle;

import "config.proto";
import "targeting.proto";

option go_package = "android_bundle_proto";
option java_package = "com.android.bundle";

// Describes the output of the "build-apks" command.
message BuildApksResult {
  // The package name of this app.
  string package_name = 4;

  // List of the created variants.
  repeated Variant variant = 1;

  // Metadata about BundleTool used to build the APKs.
  Bundletool bundletool = 2;

  // List of the created asset slices.
  repeated AssetSliceSet asset_slice_set = 3;

  // Information about local testing mode.
  LocalTestingInfo local_testing_info = 5;
}

// Variant is a group of APKs that covers a part of the device configuration
// space. APKs from multiple variants are never combined on one device.
message Variant {
  // Variant-level targeting.
  // This targeting is fairly high-level and each APK has its own targeting as
  // well.
  VariantTargeting targeting = 1;

  // Set of APKs, one set per module.
  repeated ApkSet apk_set = 2;

  // Number of the variant, starting at 0 (unless overridden).
  // A device will receive APKs from the first variant that matches the device
  // configuration, with higher variant numbers having priority over lower
  // variant numbers.
  uint32 variant_number = 3;
}

// Represents a module.
// For pre-L devices multiple modules (possibly all) may be merged into one.
message ApkSet {
  ModuleMetadata module_metadata = 1;

  // APKs.
  repeated ApkDescription apk_description = 2;
}

message ModuleMetadata {
  // Module name.
  string name = 1;

  // Indicates the delivery type (e.g. on-demand) of the module.
  DeliveryType delivery_type = 6;

  // Indicates whether this module is marked "instant".
  bool is_instant = 3;

  // Names of the modules that this module directly depends on.
  // Each module implicitly depends on the base module.
  repeated string dependencies = 4;

  // The targeting that makes a conditional module installed.
  // Relevant only for Split APKs.
  ModuleTargeting targeting = 5;

  // Deprecated. Please use delivery_type.
  bool on_demand_deprecated = 2 [deprecated = true];
}

// Set of asset slices belonging to a single asset module.
message AssetSliceSet {
  // Module level metadata.
  AssetModuleMetadata asset_module_metadata = 1;

  // Asset slices.
  repeated ApkDescription apk_description = 2;
}

message AssetModuleMetadata {
  // Module name.
  string name = 1;

  // Indicates the delivery type for persistent install.
  DeliveryType delivery_type = 4;

  // Metadata for instant installs.
  InstantMetadata instant_metadata = 3;

  // Deprecated. Use delivery_type.
  bool on_demand_deprecated = 2 [deprecated = true];
}

message InstantMetadata {
  // Indicates whether this module is marked "instant".
  bool is_instant = 1;

  // Indicates the delivery type for instant install.
  DeliveryType delivery_type = 3;

  // Deprecated. Use delivery_type.
  bool on_demand_deprecated = 2 [deprecated = true];
}

enum DeliveryType {
  UNKNOWN_DELIVERY_TYPE = 0;
  INSTALL_TIME = 1;
  ON_DEMAND = 2;
  FAST_FOLLOW = 3;
}

message ApkDescription {
  ApkTargeting targeting = 1;

  // Path to the APK file.
  // BEGIN-INTERNAL
  // The path may be a blobkey if the proto is not constructed by bundletool.
  // END-INTERNAL
  string path = 2;

  oneof apk_metadata_oneof_value {
    // Set only for Split APKs.
    SplitApkMetadata split_apk_metadata = 3;
    // Set only for standalone APKs.
    StandaloneApkMetadata standalone_apk_metadata = 4;
    // Set only for Instant split APKs.
    SplitApkMetadata instant_apk_metadata = 5;
    // Set only for system APKs.
    SystemApkMetadata system_apk_metadata = 6;
    // Set only for asset slices.
    SplitApkMetadata asset_slice_metadata = 7;
    // Set only for APEX APKs.
    ApexApkMetadata apex_apk_metadata = 8;
  }
}

// Holds data specific to Split APKs.
message SplitApkMetadata {
  string split_id = 1;

  // Indicates whether this APK is the master split of the module.
  bool is_master_split = 2;
}

// Holds data specific to Standalone APKs.
message StandaloneApkMetadata {
  // Names of the modules fused in this standalone APK.
  repeated string fused_module_name = 1;

  reserved 2;
}

// Holds data specific to system APKs.
message SystemApkMetadata {
  // Names of the modules fused in this system APK.
  repeated string fused_module_name = 1;
  enum SystemApkType {
    UNSPECIFIED_VALUE = 0;
    // Uncompressed APK for system image.
    SYSTEM = 1;
    // Stub APK for compressed APK in the system image
    // (contains only android manifest).
    SYSTEM_STUB = 2;
    // Compressed APK for system image.
    SYSTEM_COMPRESSED = 3;
  }
  // Indicates whether the APK is uncompressed system APK, stub APK or
  // compressed system APK.
  SystemApkType system_apk_type = 2;
}

// Holds data specific to APEX APKs.
message ApexApkMetadata {
  // Configuration for processing of APKs embedded in an APEX image.
  repeated ApexEmbeddedApkConfig apex_embedded_apk_config = 1;
}

message LocalTestingInfo {
  // Indicates if the bundle is built in local testing mode.
  bool enabled = 1;
  // The local testing path, as specified in the base manifest.
  // This refers to the relative path on the external directory of the app where
  // APKs will be pushed for local testing.
  // Set only if local testing is enabled.
  string local_testing_path = 2;
}
