Implement extract_apks

Bug: 152319766
Test: manual and builtin
Change-Id: Ia15d66e86c7bcfd52f5b776173ca1665b68ff438
diff --git a/cmd/extract_apks/bundle_proto/config.proto b/cmd/extract_apks/bundle_proto/config.proto
new file mode 100644
index 0000000..1c161aa
--- /dev/null
+++ b/cmd/extract_apks/bundle_proto/config.proto
@@ -0,0 +1,162 @@
+// 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;
+}