Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bbf0579a authored by Sasha Smundak's avatar Sasha Smundak
Browse files

Implement extract_apks

Bug: 152319766
Test: manual and builtin
Change-Id: Ia15d66e86c7bcfd52f5b776173ca1665b68ff438
Merged-In: Ia15d66e86c7bcfd52f5b776173ca1665b68ff438
parent 0f27063a
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
blueprint_go_binary {
    name: "extract_apks",
    srcs: ["main.go"],
    deps: [
        "android-archive-zip",
        "golang-protobuf-proto",
        "soong-cmd-extract_apks-proto",
    ],
    testSrcs: ["main_test.go"]
}

bootstrap_go_package {
    name: "soong-cmd-extract_apks-proto",
    pkgPath: "android/soong/cmd/extract_apks/bundle_proto",
    deps: ["golang-protobuf-proto"],
    srcs: [
        "bundle_proto/commands.pb.go",
        "bundle_proto/config.pb.go",
        "bundle_proto/targeting.pb.go",
    ],
}
+1033 −0

File added.

Preview size limit exceeded, changes collapsed.

+197 −0
Original line number Diff line number Diff line
// 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;
}
+952 −0

File added.

Preview size limit exceeded, changes collapsed.

+162 −0
Original line number Diff line number Diff line
// 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;

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

message BundleConfig {
  Bundletool bundletool = 1;
  Optimizations optimizations = 2;
  Compression compression = 3;
  // Resources to be always kept in the master split.
  MasterResources master_resources = 4;
  ApexConfig apex_config = 5;
  // APKs to be signed with the same key as generated APKs.
  repeated UnsignedEmbeddedApkConfig unsigned_embedded_apk_config = 6;
  AssetModulesConfig asset_modules_config = 7;

  enum BundleType {
    REGULAR = 0;
    APEX = 1;
    ASSET_ONLY = 2;
  }
  BundleType type = 8;
}

message Bundletool {
  reserved 1;
  // Version of BundleTool used to build the Bundle.
  string version = 2;
}

message Compression {
  // Glob matching the list of files to leave uncompressed in the APKs.
  // The matching is done against the path of files in the APK, thus excluding
  // the name of the modules, and using forward slash ("/") as a name separator.
  // Examples: "res/raw/**", "assets/**/*.uncompressed", etc.
  repeated string uncompressed_glob = 1;
}

// Resources to keep in the master split.
message MasterResources {
  // Resource IDs to be kept in master split.
  repeated int32 resource_ids = 1;
  // Resource names to be kept in master split.
  repeated string resource_names = 2;
}

message Optimizations {
  SplitsConfig splits_config = 1;
  // This is for uncompressing native libraries on M+ devices (L+ devices on
  // instant apps).
  UncompressNativeLibraries uncompress_native_libraries = 2;
  // This is for uncompressing dex files on P+ devices.
  UncompressDexFiles uncompress_dex_files = 3;
  // Configuration for the generation of standalone APKs.
  // If no StandaloneConfig is set, the configuration is inherited from
  // splits_config.
  StandaloneConfig standalone_config = 4;
}

message UncompressNativeLibraries {
  bool enabled = 1;
}

message UncompressDexFiles {
  bool enabled = 1;
}

// Optimization configuration used to generate Split APKs.
message SplitsConfig {
  repeated SplitDimension split_dimension = 1;
}

// Optimization configuration used to generate Standalone APKs.
message StandaloneConfig {
  // Device targeting dimensions to shard.
  repeated SplitDimension split_dimension = 1;
  // Whether 64 bit libraries should be stripped from Standalone APKs.
  bool strip_64_bit_libraries = 2;
}

message SplitDimension {
  enum Value {
    UNSPECIFIED_VALUE = 0;
    ABI = 1;
    SCREEN_DENSITY = 2;
    LANGUAGE = 3;
    TEXTURE_COMPRESSION_FORMAT = 4;
    // BEGIN-INTERNAL
    GRAPHICS_API = 5;
    // END-INTERNAL
  }
  Value value = 1;

  // If set to 'true', indicates that APKs should *not* be split by this
  // dimension.
  bool negate = 2;

  // Optional transformation to be applied to asset directories where
  // the targeting is encoded in the directory name (e.g: assets/foo#tcf_etc1)
  SuffixStripping suffix_stripping = 3;
}

message SuffixStripping {
  // If set to 'true', indicates that the targeting suffix should be removed
  // from assets paths for this dimension when splits (or asset slices) are
  // generated.
  // This only applies to assets.
  // For example a folder with path "assets/level1_textures#tcf_etc1"
  // would be outputted to "assets/level1_textures". File contents are
  // unchanged.
  bool enabled = 1;

  // The default suffix to be used for the cases where separate slices can't
  // be generated for this dimension. In the case of standalone/universal APKs
  // generation, stripping the suffix can lead to file name collisions. This
  // default suffix defines the directories to retain. The others are
  // discarded: standalone/universal APKs will contain only directories
  // targeted at this value for the dimension.
  //
  // If not set or empty, the fallback directory in each directory group will be
  // used (for example, if both "assets/level1_textures#tcf_etc1" and
  // "assets/level1_textures" are present and the default suffix is empty,
  // then only "assets/level1_textures" will be used).
  string default_suffix = 2;
}

// Configuration for processing APEX bundles.
// https://source.android.com/devices/tech/ota/apex
message ApexConfig {
  // Configuration for processing of APKs embedded in an APEX image.
  repeated ApexEmbeddedApkConfig apex_embedded_apk_config = 1;
}

message ApexEmbeddedApkConfig {
  // Android package name of the APK.
  string package_name = 1;

  // Path to the APK within the APEX system image.
  string path = 2;
}

message UnsignedEmbeddedApkConfig {
  // Path to the APK inside the module (e.g. if the path inside the bundle
  // is split/assets/example.apk, this will be assets/example.apk).
  string path = 1;
}

message AssetModulesConfig {
  // App versionCodes that will be updated with these asset modules.
  // Only relevant for asset-only bundles.
  repeated int64 app_version = 1;

  // Version tag for the asset upload.
  // Only relevant for asset-only bundles.
  string asset_version_tag = 2;
}
Loading