1*9e965d6fSRomain Jobredeaux# Copyright 2019 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 ResourcesBusyBox Commands.""" 16*9e965d6fSRomain Jobredeaux 17*9e965d6fSRomain Jobredeauxload(":java.bzl", _java = "java") 18*9e965d6fSRomain Jobredeaux 19*9e965d6fSRomain Jobredeaux_ANDROID_RESOURCES_STRICT_DEPS = "android_resources_strict_deps" 20*9e965d6fSRomain Jobredeaux 21*9e965d6fSRomain Jobredeauxdef _sanitize_assets_dir(assets_dir): 22*9e965d6fSRomain Jobredeaux sanitized_assets_dir = "/".join( 23*9e965d6fSRomain Jobredeaux [ 24*9e965d6fSRomain Jobredeaux part 25*9e965d6fSRomain Jobredeaux for part in assets_dir.split("/") 26*9e965d6fSRomain Jobredeaux if part != "" and part != "." 27*9e965d6fSRomain Jobredeaux ], 28*9e965d6fSRomain Jobredeaux ) 29*9e965d6fSRomain Jobredeaux 30*9e965d6fSRomain Jobredeaux return "/" + sanitized_assets_dir if assets_dir.startswith("/") else sanitized_assets_dir 31*9e965d6fSRomain Jobredeaux 32*9e965d6fSRomain Jobredeauxdef _get_unique_assets_dirs(assets, assets_dir): 33*9e965d6fSRomain Jobredeaux """Find the unique assets directories, partitioned by assets_dir. 34*9e965d6fSRomain Jobredeaux 35*9e965d6fSRomain Jobredeaux Args: 36*9e965d6fSRomain Jobredeaux assets: A list of Files. List of asset files to process. 37*9e965d6fSRomain Jobredeaux assets_dir: String. String giving the path to the files in assets. 38*9e965d6fSRomain Jobredeaux 39*9e965d6fSRomain Jobredeaux Returns: 40*9e965d6fSRomain Jobredeaux A list of short_paths representing unique asset dirs. 41*9e965d6fSRomain Jobredeaux """ 42*9e965d6fSRomain Jobredeaux if not assets: 43*9e965d6fSRomain Jobredeaux return [] 44*9e965d6fSRomain Jobredeaux 45*9e965d6fSRomain Jobredeaux dirs = dict() 46*9e965d6fSRomain Jobredeaux 47*9e965d6fSRomain Jobredeaux assets_dir = _sanitize_assets_dir(assets_dir) 48*9e965d6fSRomain Jobredeaux if assets_dir: 49*9e965d6fSRomain Jobredeaux partition_by = "/%s/" % assets_dir.strip("/") 50*9e965d6fSRomain Jobredeaux for f in assets: 51*9e965d6fSRomain Jobredeaux if f.is_directory and f.path.endswith(partition_by[:-1]): 52*9e965d6fSRomain Jobredeaux # If f is a directory, check if its path ends with the assets_dir. 53*9e965d6fSRomain Jobredeaux dirs[f.path] = True 54*9e965d6fSRomain Jobredeaux elif f.is_directory and "_aar/unzipped" in f.path: 55*9e965d6fSRomain Jobredeaux # Assets from an aar_import rule are extracted in a 56*9e965d6fSRomain Jobredeaux # "assets" subdirectory of the given path 57*9e965d6fSRomain Jobredeaux dirs["%s/assets" % f.path] = True 58*9e965d6fSRomain Jobredeaux else: 59*9e965d6fSRomain Jobredeaux # Partition to remove subdirectories beneath assets_dir 60*9e965d6fSRomain Jobredeaux # Also removes the trailing / 61*9e965d6fSRomain Jobredeaux dirs["".join(f.path.rpartition(partition_by)[:2])[:-1]] = True 62*9e965d6fSRomain Jobredeaux else: 63*9e965d6fSRomain Jobredeaux # Use the dirname of the generating target if no assets_dir. 64*9e965d6fSRomain Jobredeaux for f in assets: 65*9e965d6fSRomain Jobredeaux if f.is_source: 66*9e965d6fSRomain Jobredeaux dirs[f.owner.package] = True 67*9e965d6fSRomain Jobredeaux else: 68*9e965d6fSRomain Jobredeaux # Prepend the root path for generated files. 69*9e965d6fSRomain Jobredeaux dirs[f.root.path + "/" + f.owner.package] = True 70*9e965d6fSRomain Jobredeaux return dirs.keys() 71*9e965d6fSRomain Jobredeaux 72*9e965d6fSRomain Jobredeauxdef _get_unique_res_dirs(resource_files): 73*9e965d6fSRomain Jobredeaux """Find the unique res dirs. 74*9e965d6fSRomain Jobredeaux 75*9e965d6fSRomain Jobredeaux Args: 76*9e965d6fSRomain Jobredeaux resource_files: A list of Files. A list of resource_files. 77*9e965d6fSRomain Jobredeaux 78*9e965d6fSRomain Jobredeaux Returns: 79*9e965d6fSRomain Jobredeaux A list of short_paths representing unique res dirs from the given resource files. 80*9e965d6fSRomain Jobredeaux """ 81*9e965d6fSRomain Jobredeaux dirs = dict() 82*9e965d6fSRomain Jobredeaux for f in resource_files: 83*9e965d6fSRomain Jobredeaux if f.is_directory: 84*9e965d6fSRomain Jobredeaux dirs[f.path] = True 85*9e965d6fSRomain Jobredeaux else: 86*9e965d6fSRomain Jobredeaux dirs[f.dirname.rpartition("/" + f.dirname.split("/")[-1])[0]] = True 87*9e965d6fSRomain Jobredeaux return dirs.keys() 88*9e965d6fSRomain Jobredeaux 89*9e965d6fSRomain Jobredeauxdef _make_serialized_resources_flag( 90*9e965d6fSRomain Jobredeaux assets = [], 91*9e965d6fSRomain Jobredeaux assets_dir = None, 92*9e965d6fSRomain Jobredeaux resource_files = [], 93*9e965d6fSRomain Jobredeaux label = "", 94*9e965d6fSRomain Jobredeaux symbols = None): 95*9e965d6fSRomain Jobredeaux return ";".join( 96*9e965d6fSRomain Jobredeaux [ 97*9e965d6fSRomain Jobredeaux "#".join(_get_unique_res_dirs(resource_files)), 98*9e965d6fSRomain Jobredeaux "#".join(_get_unique_assets_dirs(assets, assets_dir)), 99*9e965d6fSRomain Jobredeaux label, 100*9e965d6fSRomain Jobredeaux symbols.path if symbols else "", 101*9e965d6fSRomain Jobredeaux ], 102*9e965d6fSRomain Jobredeaux ).rstrip(":") 103*9e965d6fSRomain Jobredeaux 104*9e965d6fSRomain Jobredeauxdef _make_resources_flag( 105*9e965d6fSRomain Jobredeaux assets = [], 106*9e965d6fSRomain Jobredeaux assets_dir = None, 107*9e965d6fSRomain Jobredeaux resource_files = [], 108*9e965d6fSRomain Jobredeaux manifest = None, 109*9e965d6fSRomain Jobredeaux r_txt = None, 110*9e965d6fSRomain Jobredeaux symbols = None): 111*9e965d6fSRomain Jobredeaux return ":".join( 112*9e965d6fSRomain Jobredeaux [ 113*9e965d6fSRomain Jobredeaux "#".join(_get_unique_res_dirs(resource_files)), 114*9e965d6fSRomain Jobredeaux "#".join(_get_unique_assets_dirs(assets, assets_dir)), 115*9e965d6fSRomain Jobredeaux manifest.path if manifest else "", 116*9e965d6fSRomain Jobredeaux r_txt.path if r_txt else "", 117*9e965d6fSRomain Jobredeaux symbols.path if symbols else "", 118*9e965d6fSRomain Jobredeaux ], 119*9e965d6fSRomain Jobredeaux ) 120*9e965d6fSRomain Jobredeaux 121*9e965d6fSRomain Jobredeauxdef _path(f): 122*9e965d6fSRomain Jobredeaux return f.path 123*9e965d6fSRomain Jobredeaux 124*9e965d6fSRomain Jobredeauxdef _make_package_resources_flags(resources_node): 125*9e965d6fSRomain Jobredeaux if not (resources_node.manifest and resources_node.r_txt and resources_node.compiled_resources): 126*9e965d6fSRomain Jobredeaux return None 127*9e965d6fSRomain Jobredeaux flag = _make_resources_flag( 128*9e965d6fSRomain Jobredeaux resource_files = resources_node.resource_files.to_list(), 129*9e965d6fSRomain Jobredeaux assets = resources_node.assets.to_list(), 130*9e965d6fSRomain Jobredeaux assets_dir = resources_node.assets_dir, 131*9e965d6fSRomain Jobredeaux manifest = resources_node.manifest, 132*9e965d6fSRomain Jobredeaux r_txt = resources_node.r_txt, 133*9e965d6fSRomain Jobredeaux symbols = resources_node.compiled_resources, 134*9e965d6fSRomain Jobredeaux ) 135*9e965d6fSRomain Jobredeaux return flag 136*9e965d6fSRomain Jobredeaux 137*9e965d6fSRomain Jobredeauxdef _make_package_assets_flags(resources_node): 138*9e965d6fSRomain Jobredeaux assets = resources_node.assets.to_list() 139*9e965d6fSRomain Jobredeaux if not assets: 140*9e965d6fSRomain Jobredeaux return None 141*9e965d6fSRomain Jobredeaux return _make_serialized_resources_flag( 142*9e965d6fSRomain Jobredeaux assets = assets, 143*9e965d6fSRomain Jobredeaux assets_dir = resources_node.assets_dir, 144*9e965d6fSRomain Jobredeaux label = str(resources_node.label), 145*9e965d6fSRomain Jobredeaux symbols = resources_node.compiled_assets, 146*9e965d6fSRomain Jobredeaux ) 147*9e965d6fSRomain Jobredeaux 148*9e965d6fSRomain Jobredeauxdef _extract_filters( 149*9e965d6fSRomain Jobredeaux raw_list): 150*9e965d6fSRomain Jobredeaux """Extract densities and resource_configuration filters from raw string lists. 151*9e965d6fSRomain Jobredeaux 152*9e965d6fSRomain Jobredeaux In BUILD files, string lists can be represented as a list of strings, a single comma-separated 153*9e965d6fSRomain Jobredeaux string, or a combination of both. This method outputs a single list of individual string values, 154*9e965d6fSRomain Jobredeaux which can then be passed directly to resource processing actions. Empty strings are removed and 155*9e965d6fSRomain Jobredeaux the final list is sorted. 156*9e965d6fSRomain Jobredeaux 157*9e965d6fSRomain Jobredeaux Args: 158*9e965d6fSRomain Jobredeaux raw_list: List of strings. The raw densities or resource configuration filters. 159*9e965d6fSRomain Jobredeaux 160*9e965d6fSRomain Jobredeaux Returns: 161*9e965d6fSRomain Jobredeaux List of strings extracted from the raw list. 162*9e965d6fSRomain Jobredeaux """ 163*9e965d6fSRomain Jobredeaux out_filters = [] 164*9e965d6fSRomain Jobredeaux for item in raw_list: 165*9e965d6fSRomain Jobredeaux if "," in item: 166*9e965d6fSRomain Jobredeaux item_list = item.split(",") 167*9e965d6fSRomain Jobredeaux for entry in item_list: 168*9e965d6fSRomain Jobredeaux stripped_entry = entry.strip() 169*9e965d6fSRomain Jobredeaux if stripped_entry: 170*9e965d6fSRomain Jobredeaux out_filters.append(stripped_entry) 171*9e965d6fSRomain Jobredeaux elif item: 172*9e965d6fSRomain Jobredeaux out_filters.append(item) 173*9e965d6fSRomain Jobredeaux return sorted(out_filters) 174*9e965d6fSRomain Jobredeaux 175*9e965d6fSRomain Jobredeauxdef _package( 176*9e965d6fSRomain Jobredeaux ctx, 177*9e965d6fSRomain Jobredeaux out_r_src_jar = None, 178*9e965d6fSRomain Jobredeaux out_r_txt = None, 179*9e965d6fSRomain Jobredeaux out_symbols = None, 180*9e965d6fSRomain Jobredeaux out_manifest = None, 181*9e965d6fSRomain Jobredeaux out_proguard_cfg = None, 182*9e965d6fSRomain Jobredeaux out_main_dex_proguard_cfg = None, 183*9e965d6fSRomain Jobredeaux out_resource_files_zip = None, 184*9e965d6fSRomain Jobredeaux out_file = None, 185*9e965d6fSRomain Jobredeaux package_type = None, 186*9e965d6fSRomain Jobredeaux java_package = None, 187*9e965d6fSRomain Jobredeaux manifest = None, 188*9e965d6fSRomain Jobredeaux assets = [], 189*9e965d6fSRomain Jobredeaux assets_dir = None, 190*9e965d6fSRomain Jobredeaux resource_files = [], 191*9e965d6fSRomain Jobredeaux resource_configs = None, 192*9e965d6fSRomain Jobredeaux densities = [], 193*9e965d6fSRomain Jobredeaux application_id = None, 194*9e965d6fSRomain Jobredeaux package_id = None, 195*9e965d6fSRomain Jobredeaux direct_resources_nodes = [], 196*9e965d6fSRomain Jobredeaux transitive_resources_nodes = [], 197*9e965d6fSRomain Jobredeaux transitive_manifests = [], 198*9e965d6fSRomain Jobredeaux transitive_assets = [], 199*9e965d6fSRomain Jobredeaux transitive_compiled_assets = [], 200*9e965d6fSRomain Jobredeaux transitive_resource_files = [], 201*9e965d6fSRomain Jobredeaux transitive_compiled_resources = [], 202*9e965d6fSRomain Jobredeaux transitive_r_txts = [], 203*9e965d6fSRomain Jobredeaux additional_apks_to_link_against = [], 204*9e965d6fSRomain Jobredeaux resource_apks = depset(), 205*9e965d6fSRomain Jobredeaux nocompress_extensions = [], 206*9e965d6fSRomain Jobredeaux proto_format = False, 207*9e965d6fSRomain Jobredeaux shrink_resource_cycles = False, 208*9e965d6fSRomain Jobredeaux version_name = None, 209*9e965d6fSRomain Jobredeaux version_code = None, 210*9e965d6fSRomain Jobredeaux android_jar = None, 211*9e965d6fSRomain Jobredeaux aapt = None, 212*9e965d6fSRomain Jobredeaux busybox = None, 213*9e965d6fSRomain Jobredeaux host_javabase = None, 214*9e965d6fSRomain Jobredeaux should_throw_on_conflict = True, # TODO: read this from allowlist at caller 215*9e965d6fSRomain Jobredeaux debug = True): # TODO: we will set this to false in prod builds 216*9e965d6fSRomain Jobredeaux """Packages the compiled Android Resources with AAPT. 217*9e965d6fSRomain Jobredeaux 218*9e965d6fSRomain Jobredeaux Args: 219*9e965d6fSRomain Jobredeaux ctx: The context. 220*9e965d6fSRomain Jobredeaux out_r_src_jar: A File. The R.java outputted by linking resources in a srcjar. 221*9e965d6fSRomain Jobredeaux out_r_txt: A File. The resource IDs outputted by linking resources in text. 222*9e965d6fSRomain Jobredeaux out_symbols: A File. The output zip containing compiled resources. 223*9e965d6fSRomain Jobredeaux out_manifest: A File. The output processed manifest. 224*9e965d6fSRomain Jobredeaux out_proguard_cfg: A File. The proguard config to be generated. 225*9e965d6fSRomain Jobredeaux out_main_dex_proguard_cfg: A File. The main dex proguard config to be generated. 226*9e965d6fSRomain Jobredeaux out_resource_files_zip: A File. The resource files zipped by linking resources. 227*9e965d6fSRomain Jobredeaux out_file: A File. The Resource APK outputted by linking resources. 228*9e965d6fSRomain Jobredeaux package_type: A string. The configuration type to use when packaging. 229*9e965d6fSRomain Jobredeaux java_package: A string. The Java package for the generated R.java. 230*9e965d6fSRomain Jobredeaux manifest: A File. The AndroidManifest.xml. 231*9e965d6fSRomain Jobredeaux assets: sequence of Files. A list of Android assets files to be processed. 232*9e965d6fSRomain Jobredeaux assets_dir: String. The name of the assets directory. 233*9e965d6fSRomain Jobredeaux resource_files: A list of Files. The resource files. 234*9e965d6fSRomain Jobredeaux resource_configs: A list of strings. The list of resource configuration 235*9e965d6fSRomain Jobredeaux filters. 236*9e965d6fSRomain Jobredeaux densities: A list of strings. The list of screen densities to filter for when 237*9e965d6fSRomain Jobredeaux building the apk. 238*9e965d6fSRomain Jobredeaux application_id: An optional string. The applicationId set in manifest values. 239*9e965d6fSRomain Jobredeaux package_id: An optional integer in [2,255]. This is the prefix byte for 240*9e965d6fSRomain Jobredeaux all generated resource IDs, defaults to 0x7F (127). 1 is reserved by the 241*9e965d6fSRomain Jobredeaux framework, and some builds are known to crash when given IDs > 127. 242*9e965d6fSRomain Jobredeaux Shared libraries are also assigned monotonically increasing IDs in 243*9e965d6fSRomain Jobredeaux [2,126], so care should be taken that there is room at the lower end. 244*9e965d6fSRomain Jobredeaux direct_resources_nodes: Depset of ResourcesNodeInfo providers. The set of 245*9e965d6fSRomain Jobredeaux ResourcesNodeInfo from direct dependencies. 246*9e965d6fSRomain Jobredeaux transitive_resources_nodes: Depset of ResourcesNodeInfo providers. The set 247*9e965d6fSRomain Jobredeaux of ResourcesNodeInfo from transitive dependencies (not including directs). 248*9e965d6fSRomain Jobredeaux transitive_manifests: List of Depsets. Depsets contain all transitive manifests. 249*9e965d6fSRomain Jobredeaux transitive_assets: List of Depsets. Depsets contain all transitive assets. 250*9e965d6fSRomain Jobredeaux transitive_compiled_assets: List of Depsets. Depsets contain all transitive 251*9e965d6fSRomain Jobredeaux compiled_assets. 252*9e965d6fSRomain Jobredeaux transitive_resource_files: List of Depsets. Depsets contain all transitive 253*9e965d6fSRomain Jobredeaux resource files. 254*9e965d6fSRomain Jobredeaux transitive_compiled_resources: List of Depsets. Depsets contain all transitive 255*9e965d6fSRomain Jobredeaux compiled_resources. 256*9e965d6fSRomain Jobredeaux transitive_r_txts: List of Depsets. Depsets contain all transitive R txt files. 257*9e965d6fSRomain Jobredeaux additional_apks_to_link_against: A list of Files. Additional APKs to link 258*9e965d6fSRomain Jobredeaux against. Optional. 259*9e965d6fSRomain Jobredeaux resource_apks: Depset of resource only apk files to link against. 260*9e965d6fSRomain Jobredeaux nocompress_extensions: A list of strings. File extension to leave uncompressed 261*9e965d6fSRomain Jobredeaux in the apk. 262*9e965d6fSRomain Jobredeaux proto_format: Boolean, whether to generate the resource table in proto format. 263*9e965d6fSRomain Jobredeaux shrink_resource_cycles: Boolean, flag that enables more shrinking of 264*9e965d6fSRomain Jobredeaux code and resources by instructing AAPT2 to emit conditional Proguard keep rules. 265*9e965d6fSRomain Jobredeaux version_name: A string. The version name to stamp the generated manifest with. Optional. 266*9e965d6fSRomain Jobredeaux version_code: A string. The version code to stamp the generated manifest with. Optional. 267*9e965d6fSRomain Jobredeaux android_jar: A File. The Android Jar. 268*9e965d6fSRomain Jobredeaux aapt: A FilesToRunProvider. The AAPT executable. 269*9e965d6fSRomain Jobredeaux busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable. 270*9e965d6fSRomain Jobredeaux host_javabase: Target. The host javabase. 271*9e965d6fSRomain Jobredeaux should_throw_on_conflict: A boolean. Determines whether an error should be thrown 272*9e965d6fSRomain Jobredeaux when a resource conflict occurs. 273*9e965d6fSRomain Jobredeaux debug: A boolean. Determines whether to enable debugging. 274*9e965d6fSRomain Jobredeaux """ 275*9e965d6fSRomain Jobredeaux if not manifest: 276*9e965d6fSRomain Jobredeaux fail("No manifest given, the manifest is mandatory.") 277*9e965d6fSRomain Jobredeaux 278*9e965d6fSRomain Jobredeaux direct_data_flag = [] 279*9e965d6fSRomain Jobredeaux direct_compiled_resources = [] 280*9e965d6fSRomain Jobredeaux 281*9e965d6fSRomain Jobredeaux output_files = [] 282*9e965d6fSRomain Jobredeaux input_files = [] 283*9e965d6fSRomain Jobredeaux transitive_input_files = [] 284*9e965d6fSRomain Jobredeaux 285*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 286*9e965d6fSRomain Jobredeaux args.use_param_file("@%s") 287*9e965d6fSRomain Jobredeaux args.add("--tool", "AAPT2_PACKAGE") 288*9e965d6fSRomain Jobredeaux args.add("--") 289*9e965d6fSRomain Jobredeaux args.add("--aapt2", aapt.executable) 290*9e965d6fSRomain Jobredeaux args.add_joined( 291*9e965d6fSRomain Jobredeaux "--data", 292*9e965d6fSRomain Jobredeaux transitive_resources_nodes, 293*9e965d6fSRomain Jobredeaux map_each = _make_package_resources_flags, 294*9e965d6fSRomain Jobredeaux join_with = ",", 295*9e965d6fSRomain Jobredeaux ) 296*9e965d6fSRomain Jobredeaux args.add_joined( 297*9e965d6fSRomain Jobredeaux "--directData", 298*9e965d6fSRomain Jobredeaux direct_resources_nodes, 299*9e965d6fSRomain Jobredeaux map_each = _make_package_resources_flags, 300*9e965d6fSRomain Jobredeaux join_with = ",", 301*9e965d6fSRomain Jobredeaux ) 302*9e965d6fSRomain Jobredeaux args.add_joined( 303*9e965d6fSRomain Jobredeaux "--directAssets", 304*9e965d6fSRomain Jobredeaux direct_resources_nodes, 305*9e965d6fSRomain Jobredeaux map_each = _make_package_assets_flags, 306*9e965d6fSRomain Jobredeaux join_with = "&", 307*9e965d6fSRomain Jobredeaux omit_if_empty = True, 308*9e965d6fSRomain Jobredeaux ) 309*9e965d6fSRomain Jobredeaux args.add_joined( 310*9e965d6fSRomain Jobredeaux "--assets", 311*9e965d6fSRomain Jobredeaux transitive_resources_nodes, 312*9e965d6fSRomain Jobredeaux map_each = _make_package_assets_flags, 313*9e965d6fSRomain Jobredeaux join_with = "&", 314*9e965d6fSRomain Jobredeaux omit_if_empty = True, 315*9e965d6fSRomain Jobredeaux ) 316*9e965d6fSRomain Jobredeaux transitive_input_files.extend(transitive_resource_files) 317*9e965d6fSRomain Jobredeaux transitive_input_files.extend(transitive_assets) 318*9e965d6fSRomain Jobredeaux transitive_input_files.extend(transitive_compiled_assets) 319*9e965d6fSRomain Jobredeaux transitive_input_files.extend(transitive_compiled_resources) 320*9e965d6fSRomain Jobredeaux transitive_input_files.extend(transitive_manifests) 321*9e965d6fSRomain Jobredeaux transitive_input_files.extend(transitive_r_txts) 322*9e965d6fSRomain Jobredeaux args.add( 323*9e965d6fSRomain Jobredeaux "--primaryData", 324*9e965d6fSRomain Jobredeaux _make_resources_flag( 325*9e965d6fSRomain Jobredeaux manifest = manifest, 326*9e965d6fSRomain Jobredeaux assets = assets, 327*9e965d6fSRomain Jobredeaux assets_dir = assets_dir, 328*9e965d6fSRomain Jobredeaux resource_files = resource_files, 329*9e965d6fSRomain Jobredeaux ), 330*9e965d6fSRomain Jobredeaux ) 331*9e965d6fSRomain Jobredeaux input_files.append(manifest) 332*9e965d6fSRomain Jobredeaux input_files.extend(resource_files) 333*9e965d6fSRomain Jobredeaux input_files.extend(assets) 334*9e965d6fSRomain Jobredeaux args.add("--androidJar", android_jar) 335*9e965d6fSRomain Jobredeaux input_files.append(android_jar) 336*9e965d6fSRomain Jobredeaux args.add("--rOutput", out_r_txt) 337*9e965d6fSRomain Jobredeaux output_files.append(out_r_txt) 338*9e965d6fSRomain Jobredeaux if out_symbols: 339*9e965d6fSRomain Jobredeaux args.add("--symbolsOut", out_symbols) 340*9e965d6fSRomain Jobredeaux output_files.append(out_symbols) 341*9e965d6fSRomain Jobredeaux args.add("--srcJarOutput", out_r_src_jar) 342*9e965d6fSRomain Jobredeaux output_files.append(out_r_src_jar) 343*9e965d6fSRomain Jobredeaux if out_proguard_cfg: 344*9e965d6fSRomain Jobredeaux args.add("--proguardOutput", out_proguard_cfg) 345*9e965d6fSRomain Jobredeaux output_files.append(out_proguard_cfg) 346*9e965d6fSRomain Jobredeaux if out_main_dex_proguard_cfg: 347*9e965d6fSRomain Jobredeaux args.add("--mainDexProguardOutput", out_main_dex_proguard_cfg) 348*9e965d6fSRomain Jobredeaux output_files.append(out_main_dex_proguard_cfg) 349*9e965d6fSRomain Jobredeaux args.add("--manifestOutput", out_manifest) 350*9e965d6fSRomain Jobredeaux output_files.append(out_manifest) 351*9e965d6fSRomain Jobredeaux if out_resource_files_zip: 352*9e965d6fSRomain Jobredeaux args.add("--resourcesOutput", out_resource_files_zip) 353*9e965d6fSRomain Jobredeaux output_files.append(out_resource_files_zip) 354*9e965d6fSRomain Jobredeaux if out_file: 355*9e965d6fSRomain Jobredeaux args.add("--packagePath", out_file) 356*9e965d6fSRomain Jobredeaux output_files.append(out_file) 357*9e965d6fSRomain Jobredeaux args.add("--useAaptCruncher=no") # Unnecessary, used for AAPT1 only but added here to minimize diffs. 358*9e965d6fSRomain Jobredeaux if package_type: 359*9e965d6fSRomain Jobredeaux args.add("--packageType", package_type) 360*9e965d6fSRomain Jobredeaux if debug: 361*9e965d6fSRomain Jobredeaux args.add("--debug") 362*9e965d6fSRomain Jobredeaux if should_throw_on_conflict: 363*9e965d6fSRomain Jobredeaux args.add("--throwOnResourceConflict") 364*9e965d6fSRomain Jobredeaux if resource_configs: 365*9e965d6fSRomain Jobredeaux args.add_joined("--resourceConfigs", _extract_filters(resource_configs), join_with = ",") 366*9e965d6fSRomain Jobredeaux if densities: 367*9e965d6fSRomain Jobredeaux args.add_joined("--densities", _extract_filters(densities), join_with = ",") 368*9e965d6fSRomain Jobredeaux if application_id: 369*9e965d6fSRomain Jobredeaux args.add("--applicationId", application_id) 370*9e965d6fSRomain Jobredeaux if package_id: 371*9e965d6fSRomain Jobredeaux args.add("--packageId", package_id) 372*9e965d6fSRomain Jobredeaux if additional_apks_to_link_against: 373*9e965d6fSRomain Jobredeaux args.add_joined( 374*9e965d6fSRomain Jobredeaux "--additionalApksToLinkAgainst", 375*9e965d6fSRomain Jobredeaux additional_apks_to_link_against, 376*9e965d6fSRomain Jobredeaux join_with = ":", 377*9e965d6fSRomain Jobredeaux map_each = _path, 378*9e965d6fSRomain Jobredeaux ) 379*9e965d6fSRomain Jobredeaux input_files.extend(additional_apks_to_link_against) 380*9e965d6fSRomain Jobredeaux if nocompress_extensions: 381*9e965d6fSRomain Jobredeaux args.add_joined("--uncompressedExtensions", nocompress_extensions, join_with = ",") 382*9e965d6fSRomain Jobredeaux if proto_format: 383*9e965d6fSRomain Jobredeaux args.add("--resourceTableAsProto") 384*9e965d6fSRomain Jobredeaux if shrink_resource_cycles: 385*9e965d6fSRomain Jobredeaux args.add("--conditionalKeepRules=yes") 386*9e965d6fSRomain Jobredeaux if version_name: 387*9e965d6fSRomain Jobredeaux args.add("--versionName", version_name) 388*9e965d6fSRomain Jobredeaux if version_code: 389*9e965d6fSRomain Jobredeaux args.add("--versionCode", version_code) 390*9e965d6fSRomain Jobredeaux if java_package: 391*9e965d6fSRomain Jobredeaux args.add("--packageForR", java_package) 392*9e965d6fSRomain Jobredeaux 393*9e965d6fSRomain Jobredeaux args.add_joined( 394*9e965d6fSRomain Jobredeaux "--resourceApks", 395*9e965d6fSRomain Jobredeaux resource_apks, 396*9e965d6fSRomain Jobredeaux join_with = ":", 397*9e965d6fSRomain Jobredeaux ) 398*9e965d6fSRomain Jobredeaux transitive_input_files.append(resource_apks) 399*9e965d6fSRomain Jobredeaux 400*9e965d6fSRomain Jobredeaux _java.run( 401*9e965d6fSRomain Jobredeaux ctx = ctx, 402*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 403*9e965d6fSRomain Jobredeaux executable = busybox, 404*9e965d6fSRomain Jobredeaux tools = [aapt], 405*9e965d6fSRomain Jobredeaux arguments = [args], 406*9e965d6fSRomain Jobredeaux inputs = depset(input_files, transitive = transitive_input_files), 407*9e965d6fSRomain Jobredeaux outputs = output_files, 408*9e965d6fSRomain Jobredeaux mnemonic = "PackageAndroidResources", 409*9e965d6fSRomain Jobredeaux progress_message = "Packaging Android Resources in %s" % ctx.label, 410*9e965d6fSRomain Jobredeaux ) 411*9e965d6fSRomain Jobredeaux 412*9e965d6fSRomain Jobredeauxdef _parse( 413*9e965d6fSRomain Jobredeaux ctx, 414*9e965d6fSRomain Jobredeaux out_symbols = None, 415*9e965d6fSRomain Jobredeaux assets = [], 416*9e965d6fSRomain Jobredeaux assets_dir = None, 417*9e965d6fSRomain Jobredeaux busybox = None, 418*9e965d6fSRomain Jobredeaux host_javabase = None): 419*9e965d6fSRomain Jobredeaux """Parses Android assets. 420*9e965d6fSRomain Jobredeaux 421*9e965d6fSRomain Jobredeaux Args: 422*9e965d6fSRomain Jobredeaux ctx: The context. 423*9e965d6fSRomain Jobredeaux out_symbols: A File. The output bin containing parsed assets. 424*9e965d6fSRomain Jobredeaux assets: sequence of Files. A list of Android assets files to be processed. 425*9e965d6fSRomain Jobredeaux assets_dir: String. The name of the assets directory. 426*9e965d6fSRomain Jobredeaux busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable. 427*9e965d6fSRomain Jobredeaux host_javabase: Target. The host javabase. 428*9e965d6fSRomain Jobredeaux """ 429*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 430*9e965d6fSRomain Jobredeaux args.use_param_file("@%s") 431*9e965d6fSRomain Jobredeaux args.add("--tool", "PARSE") 432*9e965d6fSRomain Jobredeaux args.add("--") 433*9e965d6fSRomain Jobredeaux args.add( 434*9e965d6fSRomain Jobredeaux "--primaryData", 435*9e965d6fSRomain Jobredeaux _make_resources_flag( 436*9e965d6fSRomain Jobredeaux assets = assets, 437*9e965d6fSRomain Jobredeaux assets_dir = assets_dir, 438*9e965d6fSRomain Jobredeaux ), 439*9e965d6fSRomain Jobredeaux ) 440*9e965d6fSRomain Jobredeaux args.add("--output", out_symbols) 441*9e965d6fSRomain Jobredeaux 442*9e965d6fSRomain Jobredeaux _java.run( 443*9e965d6fSRomain Jobredeaux ctx = ctx, 444*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 445*9e965d6fSRomain Jobredeaux executable = busybox, 446*9e965d6fSRomain Jobredeaux arguments = [args], 447*9e965d6fSRomain Jobredeaux inputs = assets, 448*9e965d6fSRomain Jobredeaux outputs = [out_symbols], 449*9e965d6fSRomain Jobredeaux mnemonic = "ParseAndroidResources", 450*9e965d6fSRomain Jobredeaux progress_message = "Parsing Android Resources in %s" % out_symbols.short_path, 451*9e965d6fSRomain Jobredeaux ) 452*9e965d6fSRomain Jobredeaux 453*9e965d6fSRomain Jobredeauxdef _make_merge_assets_flags(resources_node): 454*9e965d6fSRomain Jobredeaux assets = resources_node.assets.to_list() 455*9e965d6fSRomain Jobredeaux if not (assets or resources_node.assets_dir): 456*9e965d6fSRomain Jobredeaux return None 457*9e965d6fSRomain Jobredeaux return _make_serialized_resources_flag( 458*9e965d6fSRomain Jobredeaux assets = assets, 459*9e965d6fSRomain Jobredeaux assets_dir = resources_node.assets_dir, 460*9e965d6fSRomain Jobredeaux label = str(resources_node.label), 461*9e965d6fSRomain Jobredeaux symbols = resources_node.assets_symbols, 462*9e965d6fSRomain Jobredeaux ) 463*9e965d6fSRomain Jobredeaux 464*9e965d6fSRomain Jobredeauxdef _merge_assets( 465*9e965d6fSRomain Jobredeaux ctx, 466*9e965d6fSRomain Jobredeaux out_assets_zip = None, 467*9e965d6fSRomain Jobredeaux assets = [], 468*9e965d6fSRomain Jobredeaux assets_dir = None, 469*9e965d6fSRomain Jobredeaux symbols = None, 470*9e965d6fSRomain Jobredeaux transitive_assets = [], 471*9e965d6fSRomain Jobredeaux transitive_assets_symbols = [], 472*9e965d6fSRomain Jobredeaux direct_resources_nodes = [], 473*9e965d6fSRomain Jobredeaux transitive_resources_nodes = [], 474*9e965d6fSRomain Jobredeaux busybox = None, 475*9e965d6fSRomain Jobredeaux host_javabase = None): 476*9e965d6fSRomain Jobredeaux """Merges Android assets. 477*9e965d6fSRomain Jobredeaux 478*9e965d6fSRomain Jobredeaux Args: 479*9e965d6fSRomain Jobredeaux ctx: The context. 480*9e965d6fSRomain Jobredeaux out_assets_zip: A File. 481*9e965d6fSRomain Jobredeaux assets: sequence of Files. A list of Android assets files to be processed. 482*9e965d6fSRomain Jobredeaux assets_dir: String. The name of the assets directory. 483*9e965d6fSRomain Jobredeaux symbols: A File. The parsed assets. 484*9e965d6fSRomain Jobredeaux transitive_assets: Sequence of Depsets. The list of transitive 485*9e965d6fSRomain Jobredeaux assets from deps. 486*9e965d6fSRomain Jobredeaux transitive_assets_symbols: Sequence of Depsets. The list of 487*9e965d6fSRomain Jobredeaux transitive assets_symbols files from deps. 488*9e965d6fSRomain Jobredeaux direct_resources_nodes: Sequence of ResourcesNodeInfo providers. The list 489*9e965d6fSRomain Jobredeaux of ResourcesNodeInfo providers that are direct depencies. 490*9e965d6fSRomain Jobredeaux transitive_resources_nodes: Sequence of ResourcesNodeInfo providers. The 491*9e965d6fSRomain Jobredeaux list of ResourcesNodeInfo providers that are transitive depencies. 492*9e965d6fSRomain Jobredeaux busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable. 493*9e965d6fSRomain Jobredeaux host_javabase: Target. The host javabase. 494*9e965d6fSRomain Jobredeaux """ 495*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 496*9e965d6fSRomain Jobredeaux args.use_param_file("@%s") 497*9e965d6fSRomain Jobredeaux args.add("--tool", "MERGE_ASSETS") 498*9e965d6fSRomain Jobredeaux args.add("--") 499*9e965d6fSRomain Jobredeaux args.add("--assetsOutput", out_assets_zip) 500*9e965d6fSRomain Jobredeaux args.add( 501*9e965d6fSRomain Jobredeaux "--primaryData", 502*9e965d6fSRomain Jobredeaux _make_serialized_resources_flag( 503*9e965d6fSRomain Jobredeaux assets = assets, 504*9e965d6fSRomain Jobredeaux assets_dir = assets_dir, 505*9e965d6fSRomain Jobredeaux label = str(ctx.label), 506*9e965d6fSRomain Jobredeaux symbols = symbols, 507*9e965d6fSRomain Jobredeaux ), 508*9e965d6fSRomain Jobredeaux ) 509*9e965d6fSRomain Jobredeaux args.add_joined( 510*9e965d6fSRomain Jobredeaux "--directData", 511*9e965d6fSRomain Jobredeaux direct_resources_nodes, 512*9e965d6fSRomain Jobredeaux map_each = _make_merge_assets_flags, 513*9e965d6fSRomain Jobredeaux join_with = "&", 514*9e965d6fSRomain Jobredeaux ) 515*9e965d6fSRomain Jobredeaux args.add_joined( 516*9e965d6fSRomain Jobredeaux "--data", 517*9e965d6fSRomain Jobredeaux transitive_resources_nodes, 518*9e965d6fSRomain Jobredeaux map_each = _make_merge_assets_flags, 519*9e965d6fSRomain Jobredeaux join_with = "&", 520*9e965d6fSRomain Jobredeaux ) 521*9e965d6fSRomain Jobredeaux 522*9e965d6fSRomain Jobredeaux _java.run( 523*9e965d6fSRomain Jobredeaux ctx = ctx, 524*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 525*9e965d6fSRomain Jobredeaux executable = busybox, 526*9e965d6fSRomain Jobredeaux arguments = [args], 527*9e965d6fSRomain Jobredeaux inputs = depset( 528*9e965d6fSRomain Jobredeaux assets + [symbols], 529*9e965d6fSRomain Jobredeaux transitive = transitive_assets + transitive_assets_symbols, 530*9e965d6fSRomain Jobredeaux ), 531*9e965d6fSRomain Jobredeaux outputs = [out_assets_zip], 532*9e965d6fSRomain Jobredeaux mnemonic = "MergeAndroidAssets", 533*9e965d6fSRomain Jobredeaux progress_message = 534*9e965d6fSRomain Jobredeaux "Merging Android Assets in %s" % out_assets_zip.short_path, 535*9e965d6fSRomain Jobredeaux ) 536*9e965d6fSRomain Jobredeaux 537*9e965d6fSRomain Jobredeauxdef _validate_and_link( 538*9e965d6fSRomain Jobredeaux ctx, 539*9e965d6fSRomain Jobredeaux out_r_src_jar = None, 540*9e965d6fSRomain Jobredeaux out_r_txt = None, 541*9e965d6fSRomain Jobredeaux out_file = None, 542*9e965d6fSRomain Jobredeaux compiled_resources = None, 543*9e965d6fSRomain Jobredeaux transitive_compiled_resources = depset(), 544*9e965d6fSRomain Jobredeaux java_package = None, 545*9e965d6fSRomain Jobredeaux manifest = None, 546*9e965d6fSRomain Jobredeaux resource_apks = [], 547*9e965d6fSRomain Jobredeaux android_jar = None, 548*9e965d6fSRomain Jobredeaux busybox = None, 549*9e965d6fSRomain Jobredeaux host_javabase = None, 550*9e965d6fSRomain Jobredeaux aapt = None): 551*9e965d6fSRomain Jobredeaux """Links compiled Android Resources with AAPT. 552*9e965d6fSRomain Jobredeaux 553*9e965d6fSRomain Jobredeaux Args: 554*9e965d6fSRomain Jobredeaux ctx: The context. 555*9e965d6fSRomain Jobredeaux out_r_src_jar: A File. The R.java outputted by linking resources in a srcjar. 556*9e965d6fSRomain Jobredeaux out_r_txt: A File. The resource IDs outputted by linking resources in text. 557*9e965d6fSRomain Jobredeaux out_file: A File. The Resource APK outputted by linking resources. 558*9e965d6fSRomain Jobredeaux compiled_resources: A File. The symbols.zip of compiled resources for 559*9e965d6fSRomain Jobredeaux this target. 560*9e965d6fSRomain Jobredeaux transitive_compiled_resources: Depset of Files. The symbols.zip of the 561*9e965d6fSRomain Jobredeaux compiled resources from the transitive dependencies of this target. 562*9e965d6fSRomain Jobredeaux java_package: A string. The Java package for the generated R.java. 563*9e965d6fSRomain Jobredeaux manifest: A File. The AndroidManifest.xml. 564*9e965d6fSRomain Jobredeaux resource_apks: List of direct resource only apk files. 565*9e965d6fSRomain Jobredeaux android_jar: A File. The Android Jar. 566*9e965d6fSRomain Jobredeaux busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable. 567*9e965d6fSRomain Jobredeaux host_javabase: Target. The host javabase. 568*9e965d6fSRomain Jobredeaux aapt: A FilesToRunProvider. The AAPT executable. 569*9e965d6fSRomain Jobredeaux """ 570*9e965d6fSRomain Jobredeaux output_files = [] 571*9e965d6fSRomain Jobredeaux input_files = [android_jar] 572*9e965d6fSRomain Jobredeaux transitive_input_files = [] 573*9e965d6fSRomain Jobredeaux 574*9e965d6fSRomain Jobredeaux # Retrieves the list of files at runtime when a directory is passed. 575*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 576*9e965d6fSRomain Jobredeaux args.use_param_file("@%s") 577*9e965d6fSRomain Jobredeaux args.add("--tool", "LINK_STATIC_LIBRARY") 578*9e965d6fSRomain Jobredeaux args.add("--") 579*9e965d6fSRomain Jobredeaux args.add("--aapt2", aapt.executable) 580*9e965d6fSRomain Jobredeaux args.add("--libraries", android_jar) 581*9e965d6fSRomain Jobredeaux if compiled_resources: 582*9e965d6fSRomain Jobredeaux args.add("--compiled", compiled_resources) 583*9e965d6fSRomain Jobredeaux input_files.append(compiled_resources) 584*9e965d6fSRomain Jobredeaux args.add_joined( 585*9e965d6fSRomain Jobredeaux "--compiledDep", 586*9e965d6fSRomain Jobredeaux transitive_compiled_resources, 587*9e965d6fSRomain Jobredeaux join_with = ":", 588*9e965d6fSRomain Jobredeaux ) 589*9e965d6fSRomain Jobredeaux transitive_input_files.append(transitive_compiled_resources) 590*9e965d6fSRomain Jobredeaux args.add("--manifest", manifest) 591*9e965d6fSRomain Jobredeaux input_files.append(manifest) 592*9e965d6fSRomain Jobredeaux if java_package: 593*9e965d6fSRomain Jobredeaux args.add("--packageForR", java_package) 594*9e965d6fSRomain Jobredeaux args.add("--sourceJarOut", out_r_src_jar) 595*9e965d6fSRomain Jobredeaux output_files.append(out_r_src_jar) 596*9e965d6fSRomain Jobredeaux args.add("--rTxtOut", out_r_txt) 597*9e965d6fSRomain Jobredeaux output_files.append(out_r_txt) 598*9e965d6fSRomain Jobredeaux args.add("--staticLibraryOut", out_file) 599*9e965d6fSRomain Jobredeaux output_files.append(out_file) 600*9e965d6fSRomain Jobredeaux args.add_joined( 601*9e965d6fSRomain Jobredeaux "--resourceApks", 602*9e965d6fSRomain Jobredeaux resource_apks, 603*9e965d6fSRomain Jobredeaux join_with = ":", 604*9e965d6fSRomain Jobredeaux ) 605*9e965d6fSRomain Jobredeaux input_files.extend(resource_apks) 606*9e965d6fSRomain Jobredeaux 607*9e965d6fSRomain Jobredeaux _java.run( 608*9e965d6fSRomain Jobredeaux ctx = ctx, 609*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 610*9e965d6fSRomain Jobredeaux executable = busybox, 611*9e965d6fSRomain Jobredeaux tools = [aapt], 612*9e965d6fSRomain Jobredeaux arguments = [args], 613*9e965d6fSRomain Jobredeaux inputs = depset(input_files, transitive = transitive_input_files), 614*9e965d6fSRomain Jobredeaux outputs = output_files, 615*9e965d6fSRomain Jobredeaux mnemonic = "LinkAndroidResources", 616*9e965d6fSRomain Jobredeaux progress_message = 617*9e965d6fSRomain Jobredeaux "Linking Android Resources in " + out_file.short_path, 618*9e965d6fSRomain Jobredeaux ) 619*9e965d6fSRomain Jobredeaux 620*9e965d6fSRomain Jobredeauxdef _compile( 621*9e965d6fSRomain Jobredeaux ctx, 622*9e965d6fSRomain Jobredeaux out_file = None, 623*9e965d6fSRomain Jobredeaux assets = [], 624*9e965d6fSRomain Jobredeaux assets_dir = None, 625*9e965d6fSRomain Jobredeaux resource_files = [], 626*9e965d6fSRomain Jobredeaux busybox = None, 627*9e965d6fSRomain Jobredeaux aapt = None, 628*9e965d6fSRomain Jobredeaux host_javabase = None): 629*9e965d6fSRomain Jobredeaux """Compile and store resources in a single archive. 630*9e965d6fSRomain Jobredeaux 631*9e965d6fSRomain Jobredeaux Args: 632*9e965d6fSRomain Jobredeaux ctx: The context. 633*9e965d6fSRomain Jobredeaux out_file: File. The output zip containing compiled resources. 634*9e965d6fSRomain Jobredeaux resource_files: A list of Files. The list of resource files or directories 635*9e965d6fSRomain Jobredeaux assets: A list of Files. The list of assets files or directories 636*9e965d6fSRomain Jobredeaux to process. 637*9e965d6fSRomain Jobredeaux assets_dir: String. The name of the assets directory. 638*9e965d6fSRomain Jobredeaux busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable. 639*9e965d6fSRomain Jobredeaux aapt: AAPT. Tool for compiling resources. 640*9e965d6fSRomain Jobredeaux host_javabase: Target. The host javabase. 641*9e965d6fSRomain Jobredeaux """ 642*9e965d6fSRomain Jobredeaux if not out_file: 643*9e965d6fSRomain Jobredeaux fail("No output directory specified.") 644*9e965d6fSRomain Jobredeaux 645*9e965d6fSRomain Jobredeaux # Retrieves the list of files at runtime when a directory is passed. 646*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 647*9e965d6fSRomain Jobredeaux args.use_param_file("@%s") 648*9e965d6fSRomain Jobredeaux args.add("--tool", "COMPILE_LIBRARY_RESOURCES") 649*9e965d6fSRomain Jobredeaux args.add("--") 650*9e965d6fSRomain Jobredeaux args.add("--aapt2", aapt.executable) 651*9e965d6fSRomain Jobredeaux args.add( 652*9e965d6fSRomain Jobredeaux "--resources", 653*9e965d6fSRomain Jobredeaux _make_resources_flag( 654*9e965d6fSRomain Jobredeaux resource_files = resource_files, 655*9e965d6fSRomain Jobredeaux assets = assets, 656*9e965d6fSRomain Jobredeaux assets_dir = assets_dir, 657*9e965d6fSRomain Jobredeaux ), 658*9e965d6fSRomain Jobredeaux ) 659*9e965d6fSRomain Jobredeaux args.add("--output", out_file) 660*9e965d6fSRomain Jobredeaux 661*9e965d6fSRomain Jobredeaux _java.run( 662*9e965d6fSRomain Jobredeaux ctx = ctx, 663*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 664*9e965d6fSRomain Jobredeaux executable = busybox, 665*9e965d6fSRomain Jobredeaux tools = [aapt], 666*9e965d6fSRomain Jobredeaux arguments = [args], 667*9e965d6fSRomain Jobredeaux inputs = resource_files + assets, 668*9e965d6fSRomain Jobredeaux outputs = [out_file], 669*9e965d6fSRomain Jobredeaux mnemonic = "CompileAndroidResources", 670*9e965d6fSRomain Jobredeaux progress_message = "Compiling Android Resources in %s" % out_file.short_path, 671*9e965d6fSRomain Jobredeaux ) 672*9e965d6fSRomain Jobredeaux 673*9e965d6fSRomain Jobredeauxdef _make_merge_compiled_flags(resources_node_info): 674*9e965d6fSRomain Jobredeaux if not resources_node_info.compiled_resources: 675*9e965d6fSRomain Jobredeaux return None 676*9e965d6fSRomain Jobredeaux return _make_serialized_resources_flag( 677*9e965d6fSRomain Jobredeaux label = str(resources_node_info.label), 678*9e965d6fSRomain Jobredeaux symbols = resources_node_info.compiled_resources, 679*9e965d6fSRomain Jobredeaux ) 680*9e965d6fSRomain Jobredeaux 681*9e965d6fSRomain Jobredeauxdef _merge_compiled( 682*9e965d6fSRomain Jobredeaux ctx, 683*9e965d6fSRomain Jobredeaux out_class_jar = None, 684*9e965d6fSRomain Jobredeaux out_manifest = None, 685*9e965d6fSRomain Jobredeaux out_aapt2_r_txt = None, 686*9e965d6fSRomain Jobredeaux java_package = None, 687*9e965d6fSRomain Jobredeaux manifest = None, 688*9e965d6fSRomain Jobredeaux compiled_resources = None, 689*9e965d6fSRomain Jobredeaux direct_resources_nodes = [], 690*9e965d6fSRomain Jobredeaux transitive_resources_nodes = [], 691*9e965d6fSRomain Jobredeaux direct_compiled_resources = depset(), 692*9e965d6fSRomain Jobredeaux transitive_compiled_resources = depset(), 693*9e965d6fSRomain Jobredeaux android_jar = None, 694*9e965d6fSRomain Jobredeaux busybox = None, 695*9e965d6fSRomain Jobredeaux host_javabase = None): 696*9e965d6fSRomain Jobredeaux """Merges the compile resources. 697*9e965d6fSRomain Jobredeaux 698*9e965d6fSRomain Jobredeaux Args: 699*9e965d6fSRomain Jobredeaux ctx: The context. 700*9e965d6fSRomain Jobredeaux out_class_jar: A File. The compiled R.java outputted by linking resources. 701*9e965d6fSRomain Jobredeaux out_manifest: A File. The list of resource files or directories 702*9e965d6fSRomain Jobredeaux out_aapt2_r_txt: A File. The resource IDs outputted by linking resources in text. 703*9e965d6fSRomain Jobredeaux java_package: A string. The Java package for the generated R.java. 704*9e965d6fSRomain Jobredeaux manifest: A File. The AndroidManifest.xml. 705*9e965d6fSRomain Jobredeaux compiled_resources: A File. The symbols.zip of compiled resources for this target. 706*9e965d6fSRomain Jobredeaux direct_resources_nodes: Sequence of ResourcesNodeInfo providers. The list 707*9e965d6fSRomain Jobredeaux of ResourcesNodeInfo providers that are direct depencies. 708*9e965d6fSRomain Jobredeaux transitive_resources_nodes: Sequence of ResourcesNodeInfo providers. The 709*9e965d6fSRomain Jobredeaux list of ResourcesNodeInfo providers that are transitive depencies. 710*9e965d6fSRomain Jobredeaux direct_compiled_resources: Depset of Files. A depset of symbols.zip of 711*9e965d6fSRomain Jobredeaux compiled resources from direct dependencies. 712*9e965d6fSRomain Jobredeaux transitive_compiled_resources: Depset of Files. A depset of symbols.zip of 713*9e965d6fSRomain Jobredeaux compiled resources from transitive dependencies. 714*9e965d6fSRomain Jobredeaux android_jar: A File. The Android Jar. 715*9e965d6fSRomain Jobredeaux busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable. 716*9e965d6fSRomain Jobredeaux host_javabase: Target. The host javabase. 717*9e965d6fSRomain Jobredeaux """ 718*9e965d6fSRomain Jobredeaux output_files = [] 719*9e965d6fSRomain Jobredeaux input_files = [android_jar] 720*9e965d6fSRomain Jobredeaux transitive_input_files = [] 721*9e965d6fSRomain Jobredeaux 722*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 723*9e965d6fSRomain Jobredeaux args.use_param_file("@%s") 724*9e965d6fSRomain Jobredeaux args.add("--tool", "MERGE_COMPILED") 725*9e965d6fSRomain Jobredeaux args.add("--") 726*9e965d6fSRomain Jobredeaux args.add("--classJarOutput", out_class_jar) 727*9e965d6fSRomain Jobredeaux output_files.append(out_class_jar) 728*9e965d6fSRomain Jobredeaux args.add("--targetLabel", ctx.label) 729*9e965d6fSRomain Jobredeaux args.add("--manifestOutput", out_manifest) 730*9e965d6fSRomain Jobredeaux output_files.append(out_manifest) 731*9e965d6fSRomain Jobredeaux args.add("--rTxtOut", out_aapt2_r_txt) 732*9e965d6fSRomain Jobredeaux output_files.append(out_aapt2_r_txt) 733*9e965d6fSRomain Jobredeaux args.add("--androidJar", android_jar) 734*9e965d6fSRomain Jobredeaux args.add("--primaryManifest", manifest) 735*9e965d6fSRomain Jobredeaux input_files.append(manifest) 736*9e965d6fSRomain Jobredeaux if java_package: 737*9e965d6fSRomain Jobredeaux args.add("--packageForR", java_package) 738*9e965d6fSRomain Jobredeaux args.add( 739*9e965d6fSRomain Jobredeaux "--primaryData", 740*9e965d6fSRomain Jobredeaux _make_serialized_resources_flag( 741*9e965d6fSRomain Jobredeaux label = str(ctx.label), 742*9e965d6fSRomain Jobredeaux symbols = compiled_resources, 743*9e965d6fSRomain Jobredeaux ), 744*9e965d6fSRomain Jobredeaux ) 745*9e965d6fSRomain Jobredeaux input_files.append(compiled_resources) 746*9e965d6fSRomain Jobredeaux args.add_joined( 747*9e965d6fSRomain Jobredeaux "--directData", 748*9e965d6fSRomain Jobredeaux direct_resources_nodes, 749*9e965d6fSRomain Jobredeaux map_each = _make_merge_compiled_flags, 750*9e965d6fSRomain Jobredeaux join_with = "&", 751*9e965d6fSRomain Jobredeaux ) 752*9e965d6fSRomain Jobredeaux transitive_input_files.append(direct_compiled_resources) 753*9e965d6fSRomain Jobredeaux if _ANDROID_RESOURCES_STRICT_DEPS in ctx.disabled_features: 754*9e965d6fSRomain Jobredeaux args.add_joined( 755*9e965d6fSRomain Jobredeaux "--data", 756*9e965d6fSRomain Jobredeaux transitive_resources_nodes, 757*9e965d6fSRomain Jobredeaux map_each = _make_merge_compiled_flags, 758*9e965d6fSRomain Jobredeaux join_with = "&", 759*9e965d6fSRomain Jobredeaux ) 760*9e965d6fSRomain Jobredeaux transitive_input_files.append(transitive_compiled_resources) 761*9e965d6fSRomain Jobredeaux 762*9e965d6fSRomain Jobredeaux _java.run( 763*9e965d6fSRomain Jobredeaux ctx = ctx, 764*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 765*9e965d6fSRomain Jobredeaux executable = busybox, 766*9e965d6fSRomain Jobredeaux arguments = [args], 767*9e965d6fSRomain Jobredeaux inputs = depset(input_files, transitive = transitive_input_files), 768*9e965d6fSRomain Jobredeaux outputs = output_files, 769*9e965d6fSRomain Jobredeaux mnemonic = "StarlarkMergeCompiledAndroidResources", 770*9e965d6fSRomain Jobredeaux progress_message = 771*9e965d6fSRomain Jobredeaux "Merging compiled Android Resources in " + out_class_jar.short_path, 772*9e965d6fSRomain Jobredeaux ) 773*9e965d6fSRomain Jobredeaux 774*9e965d6fSRomain Jobredeauxdef _escape_mv(s): 775*9e965d6fSRomain Jobredeaux """Escapes `:` and `,` in manifest values so they can be used as a busybox flag.""" 776*9e965d6fSRomain Jobredeaux return s.replace(":", "\\:").replace(",", "\\,") 777*9e965d6fSRomain Jobredeaux 778*9e965d6fSRomain Jobredeauxdef _owner_label(file): 779*9e965d6fSRomain Jobredeaux return "//" + file.owner.package + ":" + file.owner.name 780*9e965d6fSRomain Jobredeaux 781*9e965d6fSRomain Jobredeaux# We need to remove the "/_migrated/" path segment from file paths in order for sorting to 782*9e965d6fSRomain Jobredeaux# match the order of the native manifest merging action. 783*9e965d6fSRomain Jobredeauxdef _manifest_short_path(manifest): 784*9e965d6fSRomain Jobredeaux return manifest.short_path.replace("/_migrated/", "/") 785*9e965d6fSRomain Jobredeaux 786*9e965d6fSRomain Jobredeauxdef _mergee_manifests_flag(manifests): 787*9e965d6fSRomain Jobredeaux ordered_manifests = sorted(manifests.to_list(), key = _manifest_short_path) 788*9e965d6fSRomain Jobredeaux entries = [] 789*9e965d6fSRomain Jobredeaux for manifest in ordered_manifests: 790*9e965d6fSRomain Jobredeaux label = _owner_label(manifest).replace(":", "\\:") 791*9e965d6fSRomain Jobredeaux entries.append((manifest.path + ":" + label).replace(",", "\\,")) 792*9e965d6fSRomain Jobredeaux flag_entry = ",".join(entries) 793*9e965d6fSRomain Jobredeaux if not flag_entry: 794*9e965d6fSRomain Jobredeaux return None 795*9e965d6fSRomain Jobredeaux return flag_entry 796*9e965d6fSRomain Jobredeaux 797*9e965d6fSRomain Jobredeauxdef _merge_manifests( 798*9e965d6fSRomain Jobredeaux ctx, 799*9e965d6fSRomain Jobredeaux out_file = None, 800*9e965d6fSRomain Jobredeaux out_log_file = None, 801*9e965d6fSRomain Jobredeaux merge_type = "APPLICATION", 802*9e965d6fSRomain Jobredeaux manifest = None, 803*9e965d6fSRomain Jobredeaux mergee_manifests = depset(), 804*9e965d6fSRomain Jobredeaux manifest_values = None, 805*9e965d6fSRomain Jobredeaux java_package = None, 806*9e965d6fSRomain Jobredeaux busybox = None, 807*9e965d6fSRomain Jobredeaux host_javabase = None): 808*9e965d6fSRomain Jobredeaux """Merge multiple AndroidManifest.xml files into a single one. 809*9e965d6fSRomain Jobredeaux 810*9e965d6fSRomain Jobredeaux Args: 811*9e965d6fSRomain Jobredeaux ctx: The context. 812*9e965d6fSRomain Jobredeaux out_file: A File. The output merged manifest. 813*9e965d6fSRomain Jobredeaux out_log_file: A File. The output log from the merge tool. 814*9e965d6fSRomain Jobredeaux merge_type: A string, either APPLICATION or LIBRARY. Type of merging. 815*9e965d6fSRomain Jobredeaux manifest: A File. The primary AndroidManifest.xml. 816*9e965d6fSRomain Jobredeaux mergee_manifests: A depset of Files. All transitive manifests to be merged. 817*9e965d6fSRomain Jobredeaux manifest_values: A dictionary. Manifest values to substitute. 818*9e965d6fSRomain Jobredeaux java_package: A string. Custom java package to insert in manifest package attribute. 819*9e965d6fSRomain Jobredeaux busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable. 820*9e965d6fSRomain Jobredeaux host_javabase: Target. The host javabase. 821*9e965d6fSRomain Jobredeaux """ 822*9e965d6fSRomain Jobredeaux if merge_type not in ["APPLICATION", "LIBRARY"]: 823*9e965d6fSRomain Jobredeaux fail("Unexpected manifest merge type: " + merge_type) 824*9e965d6fSRomain Jobredeaux 825*9e965d6fSRomain Jobredeaux outputs = [out_file] 826*9e965d6fSRomain Jobredeaux directs = [manifest] if manifest else [] 827*9e965d6fSRomain Jobredeaux transitives = [mergee_manifests] 828*9e965d6fSRomain Jobredeaux 829*9e965d6fSRomain Jobredeaux # Args for busybox 830*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 831*9e965d6fSRomain Jobredeaux args.use_param_file("@%s", use_always = True) 832*9e965d6fSRomain Jobredeaux args.add("--tool", "MERGE_MANIFEST") 833*9e965d6fSRomain Jobredeaux args.add("--") 834*9e965d6fSRomain Jobredeaux if manifest: 835*9e965d6fSRomain Jobredeaux args.add("--manifest", manifest) 836*9e965d6fSRomain Jobredeaux args.add_all( 837*9e965d6fSRomain Jobredeaux "--mergeeManifests", 838*9e965d6fSRomain Jobredeaux [mergee_manifests], 839*9e965d6fSRomain Jobredeaux map_each = _mergee_manifests_flag, 840*9e965d6fSRomain Jobredeaux ) 841*9e965d6fSRomain Jobredeaux if manifest_values: 842*9e965d6fSRomain Jobredeaux args.add( 843*9e965d6fSRomain Jobredeaux "--manifestValues", 844*9e965d6fSRomain Jobredeaux ",".join(["%s:%s" % (_escape_mv(k), _escape_mv(v)) for k, v in manifest_values.items()]), 845*9e965d6fSRomain Jobredeaux ) 846*9e965d6fSRomain Jobredeaux args.add("--mergeType", merge_type) 847*9e965d6fSRomain Jobredeaux if java_package: 848*9e965d6fSRomain Jobredeaux args.add("--customPackage", java_package) 849*9e965d6fSRomain Jobredeaux args.add("--manifestOutput", out_file) 850*9e965d6fSRomain Jobredeaux if out_log_file: 851*9e965d6fSRomain Jobredeaux args.add("--log", out_log_file) 852*9e965d6fSRomain Jobredeaux outputs.append(out_log_file) 853*9e965d6fSRomain Jobredeaux 854*9e965d6fSRomain Jobredeaux _java.run( 855*9e965d6fSRomain Jobredeaux ctx = ctx, 856*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 857*9e965d6fSRomain Jobredeaux executable = busybox, 858*9e965d6fSRomain Jobredeaux arguments = [args], 859*9e965d6fSRomain Jobredeaux inputs = depset(directs, transitive = transitives), 860*9e965d6fSRomain Jobredeaux outputs = outputs, 861*9e965d6fSRomain Jobredeaux mnemonic = "MergeManifests", 862*9e965d6fSRomain Jobredeaux progress_message = "Merging Android Manifests in %s" % out_file.short_path, 863*9e965d6fSRomain Jobredeaux ) 864*9e965d6fSRomain Jobredeaux 865*9e965d6fSRomain Jobredeauxdef _process_databinding( 866*9e965d6fSRomain Jobredeaux ctx, 867*9e965d6fSRomain Jobredeaux out_databinding_info = None, 868*9e965d6fSRomain Jobredeaux out_databinding_processed_resources = None, 869*9e965d6fSRomain Jobredeaux databinding_resources_dirname = None, 870*9e965d6fSRomain Jobredeaux resource_files = None, 871*9e965d6fSRomain Jobredeaux java_package = None, 872*9e965d6fSRomain Jobredeaux busybox = None, 873*9e965d6fSRomain Jobredeaux host_javabase = None): 874*9e965d6fSRomain Jobredeaux """Processes databinding for android_binary. 875*9e965d6fSRomain Jobredeaux 876*9e965d6fSRomain Jobredeaux Processes databinding declarations over resources, populates the databinding layout 877*9e965d6fSRomain Jobredeaux info file, and generates new resources with databinding expressions stripped out. 878*9e965d6fSRomain Jobredeaux 879*9e965d6fSRomain Jobredeaux Args: 880*9e965d6fSRomain Jobredeaux ctx: The context. 881*9e965d6fSRomain Jobredeaux out_databinding_info: File. The output databinding layout info zip file. 882*9e965d6fSRomain Jobredeaux out_databinding_processed_resources: List of Files. The generated databinding 883*9e965d6fSRomain Jobredeaux processed resource files. 884*9e965d6fSRomain Jobredeaux databinding_resources_dirname: String. The execution path to the directory where 885*9e965d6fSRomain Jobredeaux the out_databinding_processed_resources are generated. 886*9e965d6fSRomain Jobredeaux resource_files: List of Files. The resource files to be processed. 887*9e965d6fSRomain Jobredeaux java_package: String. Java package for which java sources will be 888*9e965d6fSRomain Jobredeaux generated. By default the package is inferred from the directory where 889*9e965d6fSRomain Jobredeaux the BUILD file containing the rule is. 890*9e965d6fSRomain Jobredeaux busybox: FilesToRunProvider. The ResourceBusyBox executable or 891*9e965d6fSRomain Jobredeaux FilesToRunprovider 892*9e965d6fSRomain Jobredeaux host_javabase: A Target. The host javabase. 893*9e965d6fSRomain Jobredeaux """ 894*9e965d6fSRomain Jobredeaux res_dirs = _get_unique_res_dirs(resource_files) 895*9e965d6fSRomain Jobredeaux 896*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 897*9e965d6fSRomain Jobredeaux args.add("--tool", "PROCESS_DATABINDING") 898*9e965d6fSRomain Jobredeaux args.add("--") 899*9e965d6fSRomain Jobredeaux args.add("--output_resource_directory", databinding_resources_dirname) 900*9e965d6fSRomain Jobredeaux args.add_all(res_dirs, before_each = "--resource_root") 901*9e965d6fSRomain Jobredeaux args.add("--dataBindingInfoOut", out_databinding_info) 902*9e965d6fSRomain Jobredeaux args.add("--appId", java_package) 903*9e965d6fSRomain Jobredeaux 904*9e965d6fSRomain Jobredeaux _java.run( 905*9e965d6fSRomain Jobredeaux ctx = ctx, 906*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 907*9e965d6fSRomain Jobredeaux executable = busybox, 908*9e965d6fSRomain Jobredeaux arguments = [args], 909*9e965d6fSRomain Jobredeaux inputs = resource_files, 910*9e965d6fSRomain Jobredeaux outputs = [out_databinding_info] + out_databinding_processed_resources, 911*9e965d6fSRomain Jobredeaux mnemonic = "StarlarkProcessDatabinding", 912*9e965d6fSRomain Jobredeaux progress_message = "Processing data binding", 913*9e965d6fSRomain Jobredeaux ) 914*9e965d6fSRomain Jobredeaux 915*9e965d6fSRomain Jobredeauxdef _make_generate_binay_r_flags(resources_node): 916*9e965d6fSRomain Jobredeaux if not (resources_node.r_txt or resources_node.manifest): 917*9e965d6fSRomain Jobredeaux return None 918*9e965d6fSRomain Jobredeaux return ",".join( 919*9e965d6fSRomain Jobredeaux [ 920*9e965d6fSRomain Jobredeaux resources_node.r_txt.path if resources_node.r_txt else "", 921*9e965d6fSRomain Jobredeaux resources_node.manifest.path if resources_node.manifest else "", 922*9e965d6fSRomain Jobredeaux ], 923*9e965d6fSRomain Jobredeaux ) 924*9e965d6fSRomain Jobredeaux 925*9e965d6fSRomain Jobredeauxdef _generate_binary_r( 926*9e965d6fSRomain Jobredeaux ctx, 927*9e965d6fSRomain Jobredeaux out_class_jar = None, 928*9e965d6fSRomain Jobredeaux r_txt = None, 929*9e965d6fSRomain Jobredeaux manifest = None, 930*9e965d6fSRomain Jobredeaux package_for_r = None, 931*9e965d6fSRomain Jobredeaux final_fields = None, 932*9e965d6fSRomain Jobredeaux resources_nodes = depset(), 933*9e965d6fSRomain Jobredeaux transitive_r_txts = [], 934*9e965d6fSRomain Jobredeaux transitive_manifests = [], 935*9e965d6fSRomain Jobredeaux busybox = None, 936*9e965d6fSRomain Jobredeaux host_javabase = None): 937*9e965d6fSRomain Jobredeaux """Generate compiled resources class jar. 938*9e965d6fSRomain Jobredeaux 939*9e965d6fSRomain Jobredeaux Args: 940*9e965d6fSRomain Jobredeaux ctx: The context. 941*9e965d6fSRomain Jobredeaux out_class_jar: File. The output class jar file. 942*9e965d6fSRomain Jobredeaux r_txt: File. The resource IDs outputted by linking resources in text. 943*9e965d6fSRomain Jobredeaux manifest: File. The primary AndroidManifest.xml. 944*9e965d6fSRomain Jobredeaux package_for_r: String. The Java package for the generated R class files. 945*9e965d6fSRomain Jobredeaux final_fields: Bool. Whether fields get declared as final. 946*9e965d6fSRomain Jobredeaux busybox: FilesToRunProvider. The ResourceBusyBox executable or 947*9e965d6fSRomain Jobredeaux FilesToRunprovider 948*9e965d6fSRomain Jobredeaux host_javabase: A Target. The host javabase. 949*9e965d6fSRomain Jobredeaux """ 950*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 951*9e965d6fSRomain Jobredeaux args.add("--tool", "GENERATE_BINARY_R") 952*9e965d6fSRomain Jobredeaux args.add("--") 953*9e965d6fSRomain Jobredeaux args.add("--primaryRTxt", r_txt) 954*9e965d6fSRomain Jobredeaux args.add("--primaryManifest", manifest) 955*9e965d6fSRomain Jobredeaux if package_for_r: 956*9e965d6fSRomain Jobredeaux args.add("--packageForR", package_for_r) 957*9e965d6fSRomain Jobredeaux args.add_all( 958*9e965d6fSRomain Jobredeaux resources_nodes, 959*9e965d6fSRomain Jobredeaux map_each = _make_generate_binay_r_flags, 960*9e965d6fSRomain Jobredeaux before_each = "--library", 961*9e965d6fSRomain Jobredeaux ) 962*9e965d6fSRomain Jobredeaux if final_fields: 963*9e965d6fSRomain Jobredeaux args.add("--finalFields") 964*9e965d6fSRomain Jobredeaux else: 965*9e965d6fSRomain Jobredeaux args.add("--nofinalFields") 966*9e965d6fSRomain Jobredeaux 967*9e965d6fSRomain Jobredeaux # TODO(b/154003916): support transitive "--library transitive_r_txt_path,transitive_manifest_path" flags 968*9e965d6fSRomain Jobredeaux args.add("--classJarOutput", out_class_jar) 969*9e965d6fSRomain Jobredeaux args.add("--targetLabel", str(ctx.label)) 970*9e965d6fSRomain Jobredeaux args.use_param_file("@%s") 971*9e965d6fSRomain Jobredeaux 972*9e965d6fSRomain Jobredeaux _java.run( 973*9e965d6fSRomain Jobredeaux ctx = ctx, 974*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 975*9e965d6fSRomain Jobredeaux executable = busybox, 976*9e965d6fSRomain Jobredeaux arguments = [args], 977*9e965d6fSRomain Jobredeaux inputs = depset([r_txt, manifest], transitive = transitive_r_txts + transitive_manifests), 978*9e965d6fSRomain Jobredeaux outputs = [out_class_jar], 979*9e965d6fSRomain Jobredeaux mnemonic = "StarlarkRClassGenerator", 980*9e965d6fSRomain Jobredeaux progress_message = "Generating R classes", 981*9e965d6fSRomain Jobredeaux ) 982*9e965d6fSRomain Jobredeaux 983*9e965d6fSRomain Jobredeauxdef _make_aar( 984*9e965d6fSRomain Jobredeaux ctx, 985*9e965d6fSRomain Jobredeaux out_aar = None, 986*9e965d6fSRomain Jobredeaux assets = [], 987*9e965d6fSRomain Jobredeaux assets_dir = None, 988*9e965d6fSRomain Jobredeaux resource_files = [], 989*9e965d6fSRomain Jobredeaux class_jar = None, 990*9e965d6fSRomain Jobredeaux r_txt = None, 991*9e965d6fSRomain Jobredeaux manifest = None, 992*9e965d6fSRomain Jobredeaux proguard_specs = [], 993*9e965d6fSRomain Jobredeaux should_throw_on_conflict = False, 994*9e965d6fSRomain Jobredeaux busybox = None, 995*9e965d6fSRomain Jobredeaux host_javabase = None): 996*9e965d6fSRomain Jobredeaux """Generate an android archive file. 997*9e965d6fSRomain Jobredeaux 998*9e965d6fSRomain Jobredeaux Args: 999*9e965d6fSRomain Jobredeaux ctx: The context. 1000*9e965d6fSRomain Jobredeaux out_aar: File. The output AAR file. 1001*9e965d6fSRomain Jobredeaux assets: sequence of Files. A list of Android assets files to be processed. 1002*9e965d6fSRomain Jobredeaux assets_dir: String. The name of the assets directory. 1003*9e965d6fSRomain Jobredeaux resource_files: A list of Files. The resource files. 1004*9e965d6fSRomain Jobredeaux class_jar: File. The class jar file. 1005*9e965d6fSRomain Jobredeaux r_txt: File. The resource IDs outputted by linking resources in text. 1006*9e965d6fSRomain Jobredeaux manifest: File. The primary AndroidManifest.xml. 1007*9e965d6fSRomain Jobredeaux proguard_specs: List of File. The proguard spec files. 1008*9e965d6fSRomain Jobredeaux busybox: FilesToRunProvider. The ResourceBusyBox executable or 1009*9e965d6fSRomain Jobredeaux FilesToRunprovider 1010*9e965d6fSRomain Jobredeaux host_javabase: A Target. The host javabase. 1011*9e965d6fSRomain Jobredeaux should_throw_on_conflict: A boolean. Determines whether an error should be thrown 1012*9e965d6fSRomain Jobredeaux when a resource conflict occurs. 1013*9e965d6fSRomain Jobredeaux """ 1014*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 1015*9e965d6fSRomain Jobredeaux args.add("--tool", "GENERATE_AAR") 1016*9e965d6fSRomain Jobredeaux args.add("--") 1017*9e965d6fSRomain Jobredeaux args.add( 1018*9e965d6fSRomain Jobredeaux "--mainData", 1019*9e965d6fSRomain Jobredeaux _make_resources_flag( 1020*9e965d6fSRomain Jobredeaux manifest = manifest, 1021*9e965d6fSRomain Jobredeaux assets = assets, 1022*9e965d6fSRomain Jobredeaux assets_dir = assets_dir, 1023*9e965d6fSRomain Jobredeaux resource_files = resource_files, 1024*9e965d6fSRomain Jobredeaux ), 1025*9e965d6fSRomain Jobredeaux ) 1026*9e965d6fSRomain Jobredeaux args.add("--manifest", manifest) 1027*9e965d6fSRomain Jobredeaux args.add("--rtxt", r_txt) 1028*9e965d6fSRomain Jobredeaux args.add("--classes", class_jar) 1029*9e965d6fSRomain Jobredeaux args.add("--aarOutput", out_aar) 1030*9e965d6fSRomain Jobredeaux args.add_all(proguard_specs, before_each = "--proguardSpec") 1031*9e965d6fSRomain Jobredeaux if should_throw_on_conflict: 1032*9e965d6fSRomain Jobredeaux args.add("--throwOnResourceConflict") 1033*9e965d6fSRomain Jobredeaux 1034*9e965d6fSRomain Jobredeaux _java.run( 1035*9e965d6fSRomain Jobredeaux ctx = ctx, 1036*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 1037*9e965d6fSRomain Jobredeaux executable = busybox, 1038*9e965d6fSRomain Jobredeaux arguments = [args], 1039*9e965d6fSRomain Jobredeaux inputs = ( 1040*9e965d6fSRomain Jobredeaux resource_files + 1041*9e965d6fSRomain Jobredeaux assets + 1042*9e965d6fSRomain Jobredeaux proguard_specs + 1043*9e965d6fSRomain Jobredeaux [r_txt, manifest, class_jar] 1044*9e965d6fSRomain Jobredeaux ), 1045*9e965d6fSRomain Jobredeaux outputs = [out_aar], 1046*9e965d6fSRomain Jobredeaux mnemonic = "StarlarkAARGenerator", 1047*9e965d6fSRomain Jobredeaux progress_message = "Generating AAR package for %s" % ctx.label, 1048*9e965d6fSRomain Jobredeaux ) 1049*9e965d6fSRomain Jobredeaux 1050*9e965d6fSRomain Jobredeauxdef _shrink( 1051*9e965d6fSRomain Jobredeaux ctx, 1052*9e965d6fSRomain Jobredeaux out_apk, 1053*9e965d6fSRomain Jobredeaux out_zip, 1054*9e965d6fSRomain Jobredeaux out_log, 1055*9e965d6fSRomain Jobredeaux out_config = None, 1056*9e965d6fSRomain Jobredeaux resources_zip = None, 1057*9e965d6fSRomain Jobredeaux aapt = None, 1058*9e965d6fSRomain Jobredeaux android_jar = None, 1059*9e965d6fSRomain Jobredeaux r_txt = None, 1060*9e965d6fSRomain Jobredeaux shrunk_jar = None, 1061*9e965d6fSRomain Jobredeaux proguard_mapping = None, 1062*9e965d6fSRomain Jobredeaux debug = True, 1063*9e965d6fSRomain Jobredeaux busybox = None, 1064*9e965d6fSRomain Jobredeaux host_javabase = None): 1065*9e965d6fSRomain Jobredeaux """Shrinks the resource apk by removing the resources unused from the packaged app. 1066*9e965d6fSRomain Jobredeaux 1067*9e965d6fSRomain Jobredeaux Args: 1068*9e965d6fSRomain Jobredeaux ctx: The context. 1069*9e965d6fSRomain Jobredeaux out_apk: File. The output shrunk resource ap_ package. 1070*9e965d6fSRomain Jobredeaux out_zip: File. The output shrunk resources file zip. 1071*9e965d6fSRomain Jobredeaux out_log: File. The output shrinker log. 1072*9e965d6fSRomain Jobredeaux out_config: File. The output config for the optimizer. 1073*9e965d6fSRomain Jobredeaux resources_zip: File. The input resources file zip. 1074*9e965d6fSRomain Jobredeaux aapt: FilesToRunProvider. The AAPT executable. 1075*9e965d6fSRomain Jobredeaux android_jar: File. The Android Jar. 1076*9e965d6fSRomain Jobredeaux r_txt: File. The resource IDs outputted by linking resources in text. 1077*9e965d6fSRomain Jobredeaux shrunk_jar: File. The proguarded jar. 1078*9e965d6fSRomain Jobredeaux proguard_mapping: File. The Proguard Mapping file. 1079*9e965d6fSRomain Jobredeaux debug: Boolean. Whether to enable debug mode. 1080*9e965d6fSRomain Jobredeaux busybox: FilesToRunProvider. The ResourceBusyBox executable. 1081*9e965d6fSRomain Jobredeaux host_javabase: Target. The host javabase. 1082*9e965d6fSRomain Jobredeaux """ 1083*9e965d6fSRomain Jobredeaux 1084*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 1085*9e965d6fSRomain Jobredeaux args.use_param_file("@%s") 1086*9e965d6fSRomain Jobredeaux args.add("--tool", "SHRINK_AAPT2") 1087*9e965d6fSRomain Jobredeaux args.add("--") 1088*9e965d6fSRomain Jobredeaux args.add("--aapt2", aapt.executable) 1089*9e965d6fSRomain Jobredeaux args.add("--androidJar", android_jar) 1090*9e965d6fSRomain Jobredeaux args.add("--resources", resources_zip) 1091*9e965d6fSRomain Jobredeaux args.add("--shrunkJar", shrunk_jar) 1092*9e965d6fSRomain Jobredeaux args.add("--proguardMapping", proguard_mapping) 1093*9e965d6fSRomain Jobredeaux args.add("--rTxt", r_txt) 1094*9e965d6fSRomain Jobredeaux args.add("--shrunkResourceApk", out_apk) 1095*9e965d6fSRomain Jobredeaux args.add("--shrunkResources", out_zip) 1096*9e965d6fSRomain Jobredeaux args.add("--log", out_log) 1097*9e965d6fSRomain Jobredeaux args.add("--useDataBindingAndroidX") 1098*9e965d6fSRomain Jobredeaux if debug: 1099*9e965d6fSRomain Jobredeaux args.add("--debug") 1100*9e965d6fSRomain Jobredeaux 1101*9e965d6fSRomain Jobredeaux input_files = [ 1102*9e965d6fSRomain Jobredeaux android_jar, 1103*9e965d6fSRomain Jobredeaux resources_zip, 1104*9e965d6fSRomain Jobredeaux shrunk_jar, 1105*9e965d6fSRomain Jobredeaux proguard_mapping, 1106*9e965d6fSRomain Jobredeaux r_txt, 1107*9e965d6fSRomain Jobredeaux ] 1108*9e965d6fSRomain Jobredeaux output_files = [ 1109*9e965d6fSRomain Jobredeaux out_apk, 1110*9e965d6fSRomain Jobredeaux out_zip, 1111*9e965d6fSRomain Jobredeaux out_log, 1112*9e965d6fSRomain Jobredeaux ] 1113*9e965d6fSRomain Jobredeaux if out_config: 1114*9e965d6fSRomain Jobredeaux args.add("--resourcesConfigOutput", out_config) 1115*9e965d6fSRomain Jobredeaux output_files.append(out_config) 1116*9e965d6fSRomain Jobredeaux 1117*9e965d6fSRomain Jobredeaux _java.run( 1118*9e965d6fSRomain Jobredeaux ctx = ctx, 1119*9e965d6fSRomain Jobredeaux executable = busybox, 1120*9e965d6fSRomain Jobredeaux tools = [aapt], 1121*9e965d6fSRomain Jobredeaux outputs = output_files, 1122*9e965d6fSRomain Jobredeaux inputs = input_files, 1123*9e965d6fSRomain Jobredeaux arguments = [args], 1124*9e965d6fSRomain Jobredeaux mnemonic = "ResourceShrinker", 1125*9e965d6fSRomain Jobredeaux progress_message = 1126*9e965d6fSRomain Jobredeaux "Shrinking resources for " + str(ctx.label), 1127*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 1128*9e965d6fSRomain Jobredeaux use_default_shell_env = True, 1129*9e965d6fSRomain Jobredeaux ) 1130*9e965d6fSRomain Jobredeaux 1131*9e965d6fSRomain Jobredeauxdef _optimize( 1132*9e965d6fSRomain Jobredeaux ctx, 1133*9e965d6fSRomain Jobredeaux out_apk, 1134*9e965d6fSRomain Jobredeaux in_apk, 1135*9e965d6fSRomain Jobredeaux resource_path_shortening_map = None, 1136*9e965d6fSRomain Jobredeaux resource_optimization_config = None, 1137*9e965d6fSRomain Jobredeaux aapt = None, 1138*9e965d6fSRomain Jobredeaux busybox = None, 1139*9e965d6fSRomain Jobredeaux host_javabase = None): 1140*9e965d6fSRomain Jobredeaux """Optimizes the resource apk including resource obfuscation, sparse encoding and path shortening. 1141*9e965d6fSRomain Jobredeaux 1142*9e965d6fSRomain Jobredeaux Args: 1143*9e965d6fSRomain Jobredeaux ctx: The context. 1144*9e965d6fSRomain Jobredeaux out_apk: File. The output optimized resource ap_ package. 1145*9e965d6fSRomain Jobredeaux in_apk: File. The resource ap_ package to be optimized. 1146*9e965d6fSRomain Jobredeaux resource_path_shortening_map: File. The output path shortening map. Optional. 1147*9e965d6fSRomain Jobredeaux resource_optimization_config: File. The input optimization config. Optional. 1148*9e965d6fSRomain Jobredeaux aapt: FilesToRunProvider. The AAPT executable. 1149*9e965d6fSRomain Jobredeaux busybox: FilesToRunProvider. The ResourceBusyBox executable. 1150*9e965d6fSRomain Jobredeaux host_javabase: Target. The host javabase. 1151*9e965d6fSRomain Jobredeaux """ 1152*9e965d6fSRomain Jobredeaux 1153*9e965d6fSRomain Jobredeaux output_files = [out_apk] 1154*9e965d6fSRomain Jobredeaux input_files = [in_apk] 1155*9e965d6fSRomain Jobredeaux 1156*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 1157*9e965d6fSRomain Jobredeaux args.use_param_file("@%s") 1158*9e965d6fSRomain Jobredeaux args.add("--tool", "AAPT2_OPTIMIZE") 1159*9e965d6fSRomain Jobredeaux args.add("--") 1160*9e965d6fSRomain Jobredeaux args.add("--aapt2", aapt.executable) 1161*9e965d6fSRomain Jobredeaux args.add("--") 1162*9e965d6fSRomain Jobredeaux if resource_path_shortening_map: 1163*9e965d6fSRomain Jobredeaux args.add("--shorten-resource-paths") 1164*9e965d6fSRomain Jobredeaux args.add("--resource-path-shortening-map", resource_path_shortening_map) 1165*9e965d6fSRomain Jobredeaux output_files.append(resource_path_shortening_map) 1166*9e965d6fSRomain Jobredeaux if resource_optimization_config: 1167*9e965d6fSRomain Jobredeaux args.add("--collapse-resource-names") 1168*9e965d6fSRomain Jobredeaux args.add("--resources-config-path", resource_optimization_config) 1169*9e965d6fSRomain Jobredeaux input_files.append(resource_optimization_config) 1170*9e965d6fSRomain Jobredeaux args.add("-o", out_apk) 1171*9e965d6fSRomain Jobredeaux args.add(in_apk) 1172*9e965d6fSRomain Jobredeaux 1173*9e965d6fSRomain Jobredeaux _java.run( 1174*9e965d6fSRomain Jobredeaux ctx = ctx, 1175*9e965d6fSRomain Jobredeaux host_javabase = host_javabase, 1176*9e965d6fSRomain Jobredeaux executable = busybox, 1177*9e965d6fSRomain Jobredeaux tools = [aapt], 1178*9e965d6fSRomain Jobredeaux arguments = [args], 1179*9e965d6fSRomain Jobredeaux inputs = input_files, 1180*9e965d6fSRomain Jobredeaux outputs = output_files, 1181*9e965d6fSRomain Jobredeaux mnemonic = "Aapt2Optimize", 1182*9e965d6fSRomain Jobredeaux progress_message = 1183*9e965d6fSRomain Jobredeaux "Optimizing Android resources for " + str(ctx.label), 1184*9e965d6fSRomain Jobredeaux use_default_shell_env = True, 1185*9e965d6fSRomain Jobredeaux ) 1186*9e965d6fSRomain Jobredeaux 1187*9e965d6fSRomain Jobredeauxbusybox = struct( 1188*9e965d6fSRomain Jobredeaux compile = _compile, 1189*9e965d6fSRomain Jobredeaux merge_compiled = _merge_compiled, 1190*9e965d6fSRomain Jobredeaux validate_and_link = _validate_and_link, 1191*9e965d6fSRomain Jobredeaux merge_manifests = _merge_manifests, 1192*9e965d6fSRomain Jobredeaux package = _package, 1193*9e965d6fSRomain Jobredeaux parse = _parse, 1194*9e965d6fSRomain Jobredeaux merge_assets = _merge_assets, 1195*9e965d6fSRomain Jobredeaux make_resources_flag = _make_resources_flag, 1196*9e965d6fSRomain Jobredeaux process_databinding = _process_databinding, 1197*9e965d6fSRomain Jobredeaux generate_binary_r = _generate_binary_r, 1198*9e965d6fSRomain Jobredeaux make_aar = _make_aar, 1199*9e965d6fSRomain Jobredeaux shrink = _shrink, 1200*9e965d6fSRomain Jobredeaux optimize = _optimize, 1201*9e965d6fSRomain Jobredeaux 1202*9e965d6fSRomain Jobredeaux # Exposed for testing 1203*9e965d6fSRomain Jobredeaux mergee_manifests_flag = _mergee_manifests_flag, 1204*9e965d6fSRomain Jobredeaux get_unique_res_dirs = _get_unique_res_dirs, 1205*9e965d6fSRomain Jobredeaux sanitize_assets_dir = _sanitize_assets_dir, 1206*9e965d6fSRomain Jobredeaux extract_filters = _extract_filters, 1207*9e965d6fSRomain Jobredeaux) 1208