1*9e965d6fSRomain Jobredeaux# Copyright 2020 The Bazel Authors. All rights reserved. 2*9e965d6fSRomain Jobredeaux# 3*9e965d6fSRomain Jobredeaux# Licensed under the Apache License, Version 2.0 (the "License"); 4*9e965d6fSRomain Jobredeaux# you may not use this file except in compliance with the License. 5*9e965d6fSRomain Jobredeaux# You may obtain a copy of the License at 6*9e965d6fSRomain Jobredeaux# 7*9e965d6fSRomain Jobredeaux# http://www.apache.org/licenses/LICENSE-2.0 8*9e965d6fSRomain Jobredeaux# 9*9e965d6fSRomain Jobredeaux# Unless required by applicable law or agreed to in writing, software 10*9e965d6fSRomain Jobredeaux# distributed under the License is distributed on an "AS IS" BASIS, 11*9e965d6fSRomain Jobredeaux# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9e965d6fSRomain Jobredeaux# See the License for the specific language governing permissions and 13*9e965d6fSRomain Jobredeaux# limitations under the License. 14*9e965d6fSRomain Jobredeaux 15*9e965d6fSRomain Jobredeaux"""Bazel Bundletool Commands.""" 16*9e965d6fSRomain Jobredeaux 17*9e965d6fSRomain Jobredeauxload( 18*9e965d6fSRomain Jobredeaux "//rules:utils.bzl", 19*9e965d6fSRomain Jobredeaux "ANDROID_TOOLCHAIN_TYPE", 20*9e965d6fSRomain Jobredeaux) 21*9e965d6fSRomain Jobredeauxload("@bazel_skylib//lib:paths.bzl", "paths") 22*9e965d6fSRomain Jobredeauxload(":common.bzl", _common = "common") 23*9e965d6fSRomain Jobredeauxload(":java.bzl", _java = "java") 24*9e965d6fSRomain Jobredeaux 25*9e965d6fSRomain Jobredeaux_density_mapping = { 26*9e965d6fSRomain Jobredeaux "ldpi": 120, 27*9e965d6fSRomain Jobredeaux "mdpi": 160, 28*9e965d6fSRomain Jobredeaux "hdpi": 240, 29*9e965d6fSRomain Jobredeaux "xhdpi": 320, 30*9e965d6fSRomain Jobredeaux "xxhdpi": 480, 31*9e965d6fSRomain Jobredeaux "xxxhdpi": 640, 32*9e965d6fSRomain Jobredeaux "tvdpi": 213, 33*9e965d6fSRomain Jobredeaux} 34*9e965d6fSRomain Jobredeaux 35*9e965d6fSRomain Jobredeauxdef _build( 36*9e965d6fSRomain Jobredeaux ctx, 37*9e965d6fSRomain Jobredeaux out = None, 38*9e965d6fSRomain Jobredeaux modules = [], 39*9e965d6fSRomain Jobredeaux config = None, 40*9e965d6fSRomain Jobredeaux metadata = dict(), 41*9e965d6fSRomain Jobredeaux bundletool = None, 42*9e965d6fSRomain Jobredeaux host_javabase = None): 43*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 44*9e965d6fSRomain Jobredeaux args.add("build-bundle") 45*9e965d6fSRomain Jobredeaux args.add("--output", out) 46*9e965d6fSRomain Jobredeaux if modules: 47*9e965d6fSRomain Jobredeaux args.add_joined("--modules", modules, join_with = ",") 48*9e965d6fSRomain Jobredeaux if config: 49*9e965d6fSRomain Jobredeaux args.add("--config", config) 50*9e965d6fSRomain Jobredeaux for path, f in metadata.items(): 51*9e965d6fSRomain Jobredeaux args.add("--metadata-file", "%s:%s" % (path, f.path)) 52*9e965d6fSRomain Jobredeaux 53*9e965d6fSRomain Jobredeaux _java.run( 54*9e965d6fSRomain Jobredeaux ctx = ctx, 55*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 56*9e965d6fSRomain Jobredeaux executable = bundletool, 57*9e965d6fSRomain Jobredeaux arguments = [args], 58*9e965d6fSRomain Jobredeaux inputs = ( 59*9e965d6fSRomain Jobredeaux modules + 60*9e965d6fSRomain Jobredeaux ([config] if config else []) + 61*9e965d6fSRomain Jobredeaux metadata.values() 62*9e965d6fSRomain Jobredeaux ), 63*9e965d6fSRomain Jobredeaux outputs = [out], 64*9e965d6fSRomain Jobredeaux mnemonic = "BuildBundle", 65*9e965d6fSRomain Jobredeaux progress_message = "Building bundle %s" % out.short_path, 66*9e965d6fSRomain Jobredeaux ) 67*9e965d6fSRomain Jobredeaux 68*9e965d6fSRomain Jobredeauxdef _build_device_json( 69*9e965d6fSRomain Jobredeaux ctx, 70*9e965d6fSRomain Jobredeaux out, 71*9e965d6fSRomain Jobredeaux abis, 72*9e965d6fSRomain Jobredeaux locales, 73*9e965d6fSRomain Jobredeaux density, 74*9e965d6fSRomain Jobredeaux sdk_version): 75*9e965d6fSRomain Jobredeaux json_content = json.encode(struct( 76*9e965d6fSRomain Jobredeaux supportedAbis = abis, 77*9e965d6fSRomain Jobredeaux supportedLocales = locales, 78*9e965d6fSRomain Jobredeaux screenDensity = _density_mapping[density], 79*9e965d6fSRomain Jobredeaux sdkVersion = int(sdk_version), 80*9e965d6fSRomain Jobredeaux )) 81*9e965d6fSRomain Jobredeaux ctx.actions.write(out, json_content) 82*9e965d6fSRomain Jobredeaux 83*9e965d6fSRomain Jobredeauxdef _build_sdk_apks( 84*9e965d6fSRomain Jobredeaux ctx, 85*9e965d6fSRomain Jobredeaux out = None, 86*9e965d6fSRomain Jobredeaux aapt2 = None, 87*9e965d6fSRomain Jobredeaux sdk_bundle = None, 88*9e965d6fSRomain Jobredeaux debug_key = None, 89*9e965d6fSRomain Jobredeaux bundletool = None, 90*9e965d6fSRomain Jobredeaux host_javabase = None): 91*9e965d6fSRomain Jobredeaux apks_out = ctx.actions.declare_directory( 92*9e965d6fSRomain Jobredeaux "%s_apks_out" % paths.basename(out.path).replace(".", "_"), 93*9e965d6fSRomain Jobredeaux sibling = out, 94*9e965d6fSRomain Jobredeaux ) 95*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 96*9e965d6fSRomain Jobredeaux args.add("build-sdk-apks") 97*9e965d6fSRomain Jobredeaux args.add("--aapt2", aapt2.executable.path) 98*9e965d6fSRomain Jobredeaux args.add("--sdk-bundle", sdk_bundle) 99*9e965d6fSRomain Jobredeaux args.add("--ks", debug_key) 100*9e965d6fSRomain Jobredeaux args.add("--ks-pass=pass:android") 101*9e965d6fSRomain Jobredeaux args.add("--ks-key-alias=androiddebugkey") 102*9e965d6fSRomain Jobredeaux args.add("--key-pass=pass:android") 103*9e965d6fSRomain Jobredeaux args.add("--output-format=DIRECTORY") 104*9e965d6fSRomain Jobredeaux args.add("--output", apks_out.path) 105*9e965d6fSRomain Jobredeaux _java.run( 106*9e965d6fSRomain Jobredeaux ctx = ctx, 107*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 108*9e965d6fSRomain Jobredeaux executable = bundletool, 109*9e965d6fSRomain Jobredeaux arguments = [args], 110*9e965d6fSRomain Jobredeaux inputs = [ 111*9e965d6fSRomain Jobredeaux sdk_bundle, 112*9e965d6fSRomain Jobredeaux debug_key, 113*9e965d6fSRomain Jobredeaux ], 114*9e965d6fSRomain Jobredeaux tools = [aapt2], 115*9e965d6fSRomain Jobredeaux outputs = [apks_out], 116*9e965d6fSRomain Jobredeaux mnemonic = "BuildSdkApksDir", 117*9e965d6fSRomain Jobredeaux progress_message = "Building SDK APKs directory %s" % apks_out.short_path, 118*9e965d6fSRomain Jobredeaux ) 119*9e965d6fSRomain Jobredeaux 120*9e965d6fSRomain Jobredeaux # Now move standalone APK out of bundletool output dir. 121*9e965d6fSRomain Jobredeaux ctx.actions.run_shell( 122*9e965d6fSRomain Jobredeaux command = """ 123*9e965d6fSRomain Jobredeauxset -e 124*9e965d6fSRomain JobredeauxAPKS_OUT_DIR=%s 125*9e965d6fSRomain JobredeauxDEBUG_APK_PATH=%s 126*9e965d6fSRomain Jobredeaux 127*9e965d6fSRomain Jobredeauxmv "${APKS_OUT_DIR}/standalones/standalone.apk" "${DEBUG_APK_PATH}" 128*9e965d6fSRomain Jobredeaux""" % ( 129*9e965d6fSRomain Jobredeaux apks_out.path, 130*9e965d6fSRomain Jobredeaux out.path, 131*9e965d6fSRomain Jobredeaux ), 132*9e965d6fSRomain Jobredeaux tools = [], 133*9e965d6fSRomain Jobredeaux arguments = [], 134*9e965d6fSRomain Jobredeaux inputs = [apks_out], 135*9e965d6fSRomain Jobredeaux outputs = [out], 136*9e965d6fSRomain Jobredeaux mnemonic = "ExtractDebugSdkApk", 137*9e965d6fSRomain Jobredeaux progress_message = "Extract debug SDK APK to %s" % out.short_path, 138*9e965d6fSRomain Jobredeaux ) 139*9e965d6fSRomain Jobredeaux 140*9e965d6fSRomain Jobredeauxdef _build_sdk_bundle( 141*9e965d6fSRomain Jobredeaux ctx, 142*9e965d6fSRomain Jobredeaux out = None, 143*9e965d6fSRomain Jobredeaux module = None, 144*9e965d6fSRomain Jobredeaux sdk_api_descriptors = None, 145*9e965d6fSRomain Jobredeaux sdk_modules_config = None, 146*9e965d6fSRomain Jobredeaux bundletool = None, 147*9e965d6fSRomain Jobredeaux host_javabase = None): 148*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 149*9e965d6fSRomain Jobredeaux args.add("build-sdk-bundle") 150*9e965d6fSRomain Jobredeaux 151*9e965d6fSRomain Jobredeaux args.add("--sdk-modules-config", sdk_modules_config) 152*9e965d6fSRomain Jobredeaux args.add("--sdk-interface-descriptors", sdk_api_descriptors) 153*9e965d6fSRomain Jobredeaux args.add("--modules", module) 154*9e965d6fSRomain Jobredeaux args.add("--output", out) 155*9e965d6fSRomain Jobredeaux _java.run( 156*9e965d6fSRomain Jobredeaux ctx = ctx, 157*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 158*9e965d6fSRomain Jobredeaux executable = bundletool, 159*9e965d6fSRomain Jobredeaux arguments = [args], 160*9e965d6fSRomain Jobredeaux inputs = [ 161*9e965d6fSRomain Jobredeaux module, 162*9e965d6fSRomain Jobredeaux sdk_api_descriptors, 163*9e965d6fSRomain Jobredeaux sdk_modules_config, 164*9e965d6fSRomain Jobredeaux ], 165*9e965d6fSRomain Jobredeaux outputs = [out], 166*9e965d6fSRomain Jobredeaux mnemonic = "BuildASB", 167*9e965d6fSRomain Jobredeaux progress_message = "Building SDK bundle %s" % out.short_path, 168*9e965d6fSRomain Jobredeaux ) 169*9e965d6fSRomain Jobredeaux 170*9e965d6fSRomain Jobredeauxdef _build_sdk_module( 171*9e965d6fSRomain Jobredeaux ctx, 172*9e965d6fSRomain Jobredeaux out = None, 173*9e965d6fSRomain Jobredeaux internal_apk = None, 174*9e965d6fSRomain Jobredeaux bundletool_module_builder = None, 175*9e965d6fSRomain Jobredeaux host_javabase = None): 176*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 177*9e965d6fSRomain Jobredeaux args.add("--internal_apk_path", internal_apk) 178*9e965d6fSRomain Jobredeaux args.add("--output_module_path", out) 179*9e965d6fSRomain Jobredeaux ctx.actions.run( 180*9e965d6fSRomain Jobredeaux inputs = [internal_apk], 181*9e965d6fSRomain Jobredeaux outputs = [out], 182*9e965d6fSRomain Jobredeaux executable = bundletool_module_builder, 183*9e965d6fSRomain Jobredeaux arguments = [args], 184*9e965d6fSRomain Jobredeaux mnemonic = "BuildSdkModule", 185*9e965d6fSRomain Jobredeaux progress_message = "Building ASB zip module %s" % out.short_path, 186*9e965d6fSRomain Jobredeaux toolchain = ANDROID_TOOLCHAIN_TYPE, 187*9e965d6fSRomain Jobredeaux ) 188*9e965d6fSRomain Jobredeaux 189*9e965d6fSRomain Jobredeauxdef _bundle_to_apks( 190*9e965d6fSRomain Jobredeaux ctx, 191*9e965d6fSRomain Jobredeaux out = None, 192*9e965d6fSRomain Jobredeaux bundle = None, 193*9e965d6fSRomain Jobredeaux mode = None, 194*9e965d6fSRomain Jobredeaux system_apk_options = None, 195*9e965d6fSRomain Jobredeaux device_spec = None, 196*9e965d6fSRomain Jobredeaux keystore = None, 197*9e965d6fSRomain Jobredeaux oldest_signer = None, 198*9e965d6fSRomain Jobredeaux lineage = None, 199*9e965d6fSRomain Jobredeaux rotation_min_sdk = None, 200*9e965d6fSRomain Jobredeaux modules = None, 201*9e965d6fSRomain Jobredeaux aapt2 = None, 202*9e965d6fSRomain Jobredeaux bundletool = None, 203*9e965d6fSRomain Jobredeaux host_javabase = None): 204*9e965d6fSRomain Jobredeaux inputs = [bundle] 205*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 206*9e965d6fSRomain Jobredeaux args.add("build-apks") 207*9e965d6fSRomain Jobredeaux args.add("--output", out) 208*9e965d6fSRomain Jobredeaux args.add("--bundle", bundle) 209*9e965d6fSRomain Jobredeaux args.add("--aapt2", aapt2.executable.path) 210*9e965d6fSRomain Jobredeaux 211*9e965d6fSRomain Jobredeaux if mode: 212*9e965d6fSRomain Jobredeaux args.add("--mode", mode) 213*9e965d6fSRomain Jobredeaux 214*9e965d6fSRomain Jobredeaux if system_apk_options: 215*9e965d6fSRomain Jobredeaux if mode != "SYSTEM": 216*9e965d6fSRomain Jobredeaux fail("Unexpected system_apk_options specified, requires SYSTEM mode but got %s" % mode) 217*9e965d6fSRomain Jobredeaux args.add_joined("--system-apk-options", system_apk_options, join_with = ",") 218*9e965d6fSRomain Jobredeaux 219*9e965d6fSRomain Jobredeaux if keystore: 220*9e965d6fSRomain Jobredeaux args.add("--ks", keystore.path) 221*9e965d6fSRomain Jobredeaux args.add("--ks-pass", "pass:android") 222*9e965d6fSRomain Jobredeaux args.add("--ks-key-alias", "AndroidDebugKey") 223*9e965d6fSRomain Jobredeaux inputs.append(keystore) 224*9e965d6fSRomain Jobredeaux 225*9e965d6fSRomain Jobredeaux if lineage: 226*9e965d6fSRomain Jobredeaux if not oldest_signer: 227*9e965d6fSRomain Jobredeaux fail("Key rotation requires oldest_signer in %s" % ctx.label) 228*9e965d6fSRomain Jobredeaux oldest_signer_properties = _common.create_signer_properties(ctx, oldest_signer) 229*9e965d6fSRomain Jobredeaux args.add("--oldest-signer", oldest_signer_properties.path) 230*9e965d6fSRomain Jobredeaux args.add("--lineage", lineage.short_path) 231*9e965d6fSRomain Jobredeaux inputs.append(oldest_signer_properties) 232*9e965d6fSRomain Jobredeaux inputs.append(oldest_signer) 233*9e965d6fSRomain Jobredeaux inputs.append(lineage) 234*9e965d6fSRomain Jobredeaux 235*9e965d6fSRomain Jobredeaux if rotation_min_sdk: 236*9e965d6fSRomain Jobredeaux args.add("--rotation-min-sdk-version", rotation_min_sdk) 237*9e965d6fSRomain Jobredeaux 238*9e965d6fSRomain Jobredeaux if device_spec: 239*9e965d6fSRomain Jobredeaux args.add("--device-spec", device_spec) 240*9e965d6fSRomain Jobredeaux inputs.append(device_spec) 241*9e965d6fSRomain Jobredeaux 242*9e965d6fSRomain Jobredeaux if modules: 243*9e965d6fSRomain Jobredeaux args.add_joined("--modules", modules, join_with = ",") 244*9e965d6fSRomain Jobredeaux 245*9e965d6fSRomain Jobredeaux _java.run( 246*9e965d6fSRomain Jobredeaux ctx = ctx, 247*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 248*9e965d6fSRomain Jobredeaux executable = bundletool, 249*9e965d6fSRomain Jobredeaux arguments = [args], 250*9e965d6fSRomain Jobredeaux inputs = inputs, 251*9e965d6fSRomain Jobredeaux outputs = [out], 252*9e965d6fSRomain Jobredeaux tools = [aapt2], 253*9e965d6fSRomain Jobredeaux mnemonic = "BundleToApks", 254*9e965d6fSRomain Jobredeaux progress_message = "Converting bundle to .apks: %s" % out.short_path, 255*9e965d6fSRomain Jobredeaux ) 256*9e965d6fSRomain Jobredeaux 257*9e965d6fSRomain Jobredeauxdef _extract_config( 258*9e965d6fSRomain Jobredeaux ctx, 259*9e965d6fSRomain Jobredeaux out = None, 260*9e965d6fSRomain Jobredeaux aab = None, 261*9e965d6fSRomain Jobredeaux bundletool = None, 262*9e965d6fSRomain Jobredeaux host_javabase = None): 263*9e965d6fSRomain Jobredeaux # Need to execute as a shell script as the tool outputs to stdout 264*9e965d6fSRomain Jobredeaux cmd = """ 265*9e965d6fSRomain Jobredeauxset -e 266*9e965d6fSRomain Jobredeauxcontents=`%s -jar %s dump config --bundle %s` 267*9e965d6fSRomain Jobredeauxecho "$contents" > %s 268*9e965d6fSRomain Jobredeaux""" % ( 269*9e965d6fSRomain Jobredeaux host_javabase[java_common.JavaRuntimeInfo].java_executable_exec_path, 270*9e965d6fSRomain Jobredeaux bundletool.executable.path, 271*9e965d6fSRomain Jobredeaux aab.path, 272*9e965d6fSRomain Jobredeaux out.path, 273*9e965d6fSRomain Jobredeaux ) 274*9e965d6fSRomain Jobredeaux 275*9e965d6fSRomain Jobredeaux ctx.actions.run_shell( 276*9e965d6fSRomain Jobredeaux inputs = [aab], 277*9e965d6fSRomain Jobredeaux outputs = [out], 278*9e965d6fSRomain Jobredeaux tools = depset([bundletool.executable], transitive = [host_javabase[java_common.JavaRuntimeInfo].files]), 279*9e965d6fSRomain Jobredeaux mnemonic = "ExtractBundleConfig", 280*9e965d6fSRomain Jobredeaux progress_message = "Extract bundle config to %s" % out.short_path, 281*9e965d6fSRomain Jobredeaux command = cmd, 282*9e965d6fSRomain Jobredeaux exec_group = "android_and_java", 283*9e965d6fSRomain Jobredeaux ) 284*9e965d6fSRomain Jobredeaux 285*9e965d6fSRomain Jobredeauxdef _extract_manifest( 286*9e965d6fSRomain Jobredeaux ctx, 287*9e965d6fSRomain Jobredeaux out = None, 288*9e965d6fSRomain Jobredeaux aab = None, 289*9e965d6fSRomain Jobredeaux module = None, 290*9e965d6fSRomain Jobredeaux xpath = None, 291*9e965d6fSRomain Jobredeaux bundletool = None, 292*9e965d6fSRomain Jobredeaux host_javabase = None): 293*9e965d6fSRomain Jobredeaux # Need to execute as a shell script as the tool outputs to stdout 294*9e965d6fSRomain Jobredeaux extra_flags = [] 295*9e965d6fSRomain Jobredeaux if module: 296*9e965d6fSRomain Jobredeaux extra_flags.append("--module " + module) 297*9e965d6fSRomain Jobredeaux if xpath: 298*9e965d6fSRomain Jobredeaux extra_flags.append("--xpath " + xpath) 299*9e965d6fSRomain Jobredeaux cmd = """ 300*9e965d6fSRomain Jobredeauxset -e 301*9e965d6fSRomain Jobredeauxcontents=`%s -jar %s dump manifest --bundle %s %s` 302*9e965d6fSRomain Jobredeauxecho "$contents" > %s 303*9e965d6fSRomain Jobredeaux""" % ( 304*9e965d6fSRomain Jobredeaux host_javabase[java_common.JavaRuntimeInfo].java_executable_exec_path, 305*9e965d6fSRomain Jobredeaux bundletool.executable.path, 306*9e965d6fSRomain Jobredeaux aab.path, 307*9e965d6fSRomain Jobredeaux " ".join(extra_flags), 308*9e965d6fSRomain Jobredeaux out.path, 309*9e965d6fSRomain Jobredeaux ) 310*9e965d6fSRomain Jobredeaux 311*9e965d6fSRomain Jobredeaux ctx.actions.run_shell( 312*9e965d6fSRomain Jobredeaux inputs = [aab], 313*9e965d6fSRomain Jobredeaux outputs = [out], 314*9e965d6fSRomain Jobredeaux tools = depset([bundletool.executable], transitive = [host_javabase[java_common.JavaRuntimeInfo].files]), 315*9e965d6fSRomain Jobredeaux mnemonic = "ExtractBundleManifest", 316*9e965d6fSRomain Jobredeaux progress_message = "Extract bundle manifest to %s" % out.short_path, 317*9e965d6fSRomain Jobredeaux command = cmd, 318*9e965d6fSRomain Jobredeaux exec_group = "android_and_java", 319*9e965d6fSRomain Jobredeaux ) 320*9e965d6fSRomain Jobredeaux 321*9e965d6fSRomain Jobredeauxdef _proto_apk_to_module( 322*9e965d6fSRomain Jobredeaux ctx, 323*9e965d6fSRomain Jobredeaux out = None, 324*9e965d6fSRomain Jobredeaux proto_apk = None, 325*9e965d6fSRomain Jobredeaux bundletool_module_builder = None): 326*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 327*9e965d6fSRomain Jobredeaux args.add("--internal_apk_path", proto_apk) 328*9e965d6fSRomain Jobredeaux args.add("--output_module_path", out) 329*9e965d6fSRomain Jobredeaux ctx.actions.run( 330*9e965d6fSRomain Jobredeaux inputs = [proto_apk], 331*9e965d6fSRomain Jobredeaux outputs = [out], 332*9e965d6fSRomain Jobredeaux executable = bundletool_module_builder, 333*9e965d6fSRomain Jobredeaux arguments = [args], 334*9e965d6fSRomain Jobredeaux mnemonic = "BuildAppModule", 335*9e965d6fSRomain Jobredeaux progress_message = "Building AAB zip module %s" % out.short_path, 336*9e965d6fSRomain Jobredeaux toolchain = ANDROID_TOOLCHAIN_TYPE, 337*9e965d6fSRomain Jobredeaux ) 338*9e965d6fSRomain Jobredeaux 339*9e965d6fSRomain Jobredeauxbundletool = struct( 340*9e965d6fSRomain Jobredeaux build = _build, 341*9e965d6fSRomain Jobredeaux build_device_json = _build_device_json, 342*9e965d6fSRomain Jobredeaux build_sdk_apks = _build_sdk_apks, 343*9e965d6fSRomain Jobredeaux build_sdk_bundle = _build_sdk_bundle, 344*9e965d6fSRomain Jobredeaux build_sdk_module = _build_sdk_module, 345*9e965d6fSRomain Jobredeaux bundle_to_apks = _bundle_to_apks, 346*9e965d6fSRomain Jobredeaux extract_config = _extract_config, 347*9e965d6fSRomain Jobredeaux extract_manifest = _extract_manifest, 348*9e965d6fSRomain Jobredeaux proto_apk_to_module = _proto_apk_to_module, 349*9e965d6fSRomain Jobredeaux) 350